The GSAP script runs before the page images have loaded so the scrollTrigger markers are in the wrong heights on the page like the following which causes the animation not to run as expected (the images should fade in and up when scrolled into the viewport):
Whereas after the images have loaded and the page is resized they are in the correct place and the animation runs as intended:
Also, if the page is refreshed the scroll animations do not run at all.
I've tried useLayoutEffect instead of useEffect and tried to use refs and an onload event to wait to run the GSAP script but neither has worked. I'm using React-Bootstrap and the images are responsive so I can't set a fixed height on a parent element because I don't know the height they will be rendered ahead of time.
I made a pen to demonstrate the problem: https://codepen.io/EOJA/pen/XWzBZew?editors=0010
let { Card, Col, Container, Row } = ReactBootstrap
if (typeof window !== undefined) {
gsap.registerPlugin(ScrollTrigger)
}
const sources = [
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/bridge_1.jpg?raw=true", alt: "bridge"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/car_1.jpg?raw=true", alt: "car"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/computer_1.jpg?raw=true", alt: "computer"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/bridge_1.jpg?raw=true", alt: "bridge"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/car_1.jpg?raw=true", alt: "car"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/computer_1.jpg?raw=true", alt: "computer"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/bridge_1.jpg?raw=true", alt: "bridge"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/car_1.jpg?raw=true", alt: "car"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/computer_1.jpg?raw=true", alt: "computer"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/bridge_1.jpg?raw=true", alt: "bridge"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/car_1.jpg?raw=true", alt: "car"},
{src: "https://github.com/eoja82/For-Sale/blob/master/static/img/computer_1.jpg?raw=true", alt: "computer"}
]
const App = () => {
const images = React.useRef(null),
q = gsap.utils.selector(images)
React.useEffect(() => {
q(".card").map( card => {
return gsap.from(card, {
y: 50,
opacity: 0,
duration: .6,
scrollTrigger: {
markers: true,
trigger: card,
start: "top bottom-=100px",
toggleActions: "play pause resume reverse"
}
})
})
})
return (
<div>
<div>
<div id="section1">First Section</div>
</div>
<Container>
<Row xs={1} s={1} md={2} lg={2} xl={3} ref={images} id="images">
{sources.map( (x, i) => {
return (
<Col className="flipCard" style={{padding: "8px"}} key={i}>
<Card className="cardInner bg-dark" style={{border: "none"}}>
<div className="cardFront">
<Card.Img src={x.src} alt={x.alt} />
</div>
<div className="cardBack">
<Card.Body>
<Card.Title>{x.alt}</Card.Title>
</Card.Body>
</div>
</Card>
</Col>
)
})}
</Row>
</Container>
<div>
<div id="section2">Last Section</div>
</div>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("app"))