Jump to content
Search Community

ScrollTrigger: "Start" marker doesn't load where it's supposed to be

AlexMKC test
Moderator Tag

Recommended Posts

When my page loads, the animation for "textRef2" and "animeRef3" (text and picture at the bottom of the page) start immediately, instead of on the specified start point.

 

On my PC browser, I'm noticing that when I refresh the page, I see the "start" marker appear above "scroller-start" marker for 1 second before going to it's proper place below it. I believe this glitch is causing my animation to start immediately on page load, rather than on the scroll start. I have no idea why this is happening.

 

Here is a sandbox of my project. Please click on "open in new window" to fully see the issue. On this sandbox, however, the "start" button doesn't flicker,  but appears above the "scroller-start" marker by default. 

https://codesandbox.io/s/silly-payne-w69cg?file=/src/App.js

 

Why doesn't the "start" marker simply load where it's supposed to be consistently every time?

 

Code snippet

  useEffect(() => {
    gsap.from(
      textRef.current,
      {
        opacity:0,
        x: -80,
        duration: 3
      },
    ),
    gsap.from(
      animeRef1.current,
      {
        duration: 1.2,
        opacity: 0
        y: -30
      }
    ),
    gsap.from(
      animeRef2.current,
      {
        duration: 1.5,
        opacity: 0,
        y: -20
      }
    ),
    gsap.from(
      textRef2.current,
      {
        opacity:0,
        x: -80,
        duration: 3,
        scrollTrigger: {
          trigger: textRef2.current,
          start: "top center"
        }
      }),
    gsap.from(
      animeRef3.current,
      {
        duration: 1.5,
        opacity: 0,
        y: -20,
        scrollTrigger: {
          trigger: animeRef3.current,
          start: "top center",
          markers: true
        }
      }
    );
  }, []);

 

Full code for context

 

import React, { useStateuseEffectuseRef } from 'react';
import './../App.css';
import {GridTypographyPaperuseMediaQueryuseThemeContainerCardMediaButtonfrom '@material-ui/core';
import {makeStylesfrom '@material-ui/core/styles';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
 
const useStyles = makeStyles((theme=> ({
  holderText: {
    left: '200px',
    textAlign: 'left',
    paddingTop: '50px'
},
  holderImg: {
    flexGrow: '1',
    marginLeft: '20px'
},
  containerStyle:{
    marginTop: '30px'
},
  containerStyleSecond:{
    marginTop: '100px',
    marginBottom: '100px'
},
  buttonFont: {
    fontSize: 12
  }
}))
 
function Homepage() {
 
  const classes = useStyles();
  const textRef = useRef()
  const textRef2 = useRef()
  const animeRef1 = useRef()
  const animeRef2 = useRef()
  const animeRef3 = useRef()
 
  useEffect(() => {
    gsap.from(
      textRef.current,
      {
        opacity:0,
        x: -80,
        duration: 3
      },
    ),
    gsap.from(
      animeRef1.current,
      {
        duration: 1.2,
        opacity: 0
        y: -30
      }
    ),
    gsap.from(
      animeRef2.current,
      {
        duration: 1.5,
        opacity: 0,
        y: -20
      }
    ),
    gsap.from(
      textRef2.current,
      {
        opacity:0,
        x: -80,
        duration: 3,
        scrollTrigger: {
          trigger: textRef2.current,
          start: "top center"
        }
      }),
    gsap.from(
      animeRef3.current,
      {
        duration: 1.5,
        opacity: 0,
        y: -20,
        scrollTrigger: {
          trigger: animeRef3.current,
          start: "top center",
          markers: true
        }
      }
    );
  }, []);
 
    return (
      <div>
        <section>
          <Container maxWidth={false} className={classes.containerStyle}>
            <Grid item xs={12} container > 
              <Grid item xs={1} />
              <Grid item xs={3} >
                  <div className={"classes.holderText"}>
                    <Typography ref={textRef}>
                        <h1>
                        Lorem ipsum dolor sit amet.
                        </h1>
                        <p>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                        </p>
                        <Button to={'/shop'} className={classes.buttonFont}>
                            Enter
                        </Button>
                    </Typography>
                  </div>
              </Grid>
             <Grid item xs={4} >
                  <div className={classes.holderImg} >
                    <div className="first">
                      <div className="firstP">
                    <Paper ref={animeRef1}>
                        <CardMedia
                          component="img"
                          image={require(`../images/LA_night_car.jpg`)}                          
                        />
                    </Paper>
                    </div>
                    </div>
                  </div>
             </Grid>
              <Grid item xs={2}>
                <Paper className={classes.holderImg} ref={animeRef2}>
                    <CardMedia
                      component="img"
                      image={require(`../images/skater.jpg`)}
                    />
                </Paper>
              </Grid>
              <Grid item xs={4} />
           </Grid>
          </Container>
        </section>
        <section  >
          <Container maxWidth={false} className={classes.containerStyleSecond} >
            <Grid item xs={12} container > 
                <Grid item xs={1} />
                <Grid item xs={4}>
                    <div className={classes.holderText}>
                      <Typography ref={textRef2}>
                          <h1 >
                          Lorem ipsum dolor.
                          </h1>
                          <p>
                          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
                          </p>
                      </Typography>
                    </div>
                </Grid>
              <Grid item xs={4} >
                    <div className={classes.holderImg}>
                      <Paper ref={animeRef3}>
                          <CardMedia
                            component="img"
                            image={require(`../images/diner_portrait.jpg`)}
                          />
                      </Paper>
                    </div>
              </Grid>
                <Grid item xs={3} />
            </Grid>
           </Container>
 
        </section>
      </div>
    );
}
 
export default Homepage;
Link to comment
Share on other sites

11 hours ago, GreenSock said:

If I understand your question correctly, try setting immediateRender: false on your tweens. gsap.from() tweens render immediately by default, and you've got "y" values set, thus their position is being affected. 

I tried  adding "immediateRender: false" but the issue persists. Below is a video of what I'm seeing. Notice on the far right that the "start" marker seems to momentarily flash ahead of the "scroller-start" which I believe is causing the animation to start immediately on page load, rather than on scrollTrigger. Does this help provide more context? Do you know what's going on here? 

 

 

Link to comment
Share on other sites

Oh, yes, that's because you haven't defined any "height" for the elements, so your HTML loads but your images haven't loaded, so the elements are much much higher on the page when you create your ScrollTriggers...and then later your images load and push things way down on the page, but by that time the ScrollTrigger animations have already fired. 

 

You could either define the height values so that your layout doesn't shift, or you could just not create your animations/ScrollTriggers until everything has finished loading. Like:

window.addEventListener("load", function() {
  // do stuff here.
});

 

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...