Jump to content
Search Community

Multiple scrollTriggers within one timeline?!

geogeo test
Moderator Tag

Recommended Posts

Hi there,

 

I've created the following timeline which I want to animate each section once the user has scrolled into view.

Theres two sections  "section--design" & "section--dev" which appear after each other on the page and i'd assume the animations would run in each section depending on the scrollTrigger ... however theyre not! The animations are very patchy and seem to animate not in order and without any duration or ease. 

I'm new to this so might be completed approaching this wrong?! 

 

Any help much appreciated! 

 


const design = gsap.timeline({
    duration: 2
});

design
    // section--design
    .from('.section--design .semi-circle-right', {
        x : -485,
        ease: "power.out",
        scrollTrigger: {
            trigger: '.section--design',
            start: 'top center',
            end: 'center center',
            scrub: false,
            markers: true,
        }
    })
    .from('.section--design .wp-block-column h2, .section--design .wp-block-column p', {
        opacity : 0,
        delay: 1,
        y: 40,
        stagger: 1,
    })
    // section--dev
    .from('.section--dev .semi-circle-left', {
        x : 485,
        ease: "power.out",
        scrollTrigger: {
            trigger: '.section--dev',
            start: 'top center',
            end: 'center center',
            scrub: false,
            // markers: true,
        }
    })
    .from('.section--dev .wp-block-column h2, .section--dev .wp-block-column p', {
        opacity : 0,
        delay: 1,
        y: 40,
        stagger: 1,
    });

 

Link to comment
Share on other sites

Hey geogeo and welcome to the GreenSock forums. 

 

You're making one of the most common ScrollTrigger mistakes: putting ScrollTriggers on tweens within a timeline. Doing so doesn't make much sense because both the timeline and ScrollTrigger will try to control the progress of the tween. The article I linked to talks about other potential solutions. If you're still having issues, please make a minimal demo of your situation as the following thread talks about and we'll do our best to help :) 

Happy tweening. 

Link to comment
Share on other sites

Hi,

 

Many thanks for your quick reply! I thought that might be the case, but I just couldn't work out how to run an animation after a scroll trigger had completed. I've tried adding the second tween as a function / variable and then try to run it on "onComplete" or "onLeave" etc. but the callbacks all seem to run on page load (I know I must be doing it wrong)

 

Unfortunately I cant use the Loop as each section has a slightly different animation, but I assume its possible to have more than one scroll trigger on the page? I just need to get each section to work correctly.

 

Many thanks for the help - very much appreciated!

 

// const sectionTitle = () => {
let sectionTitle = gsap.from('.section--design .wp-block-column h2, .section--design .wp-block-column p', {
    opacity : 0,
    delay: 1,
    y: 40,
    stagger: 1,
});

gsap.from('.section--design .semi-circle-right', {
    x : -485,
    ease: "power.out",
    // onComplete: sectionTitle.play(),
    scrollTrigger: {
        trigger: '.section--design',
        start: 'top center',
        end: 'center center',
        scrub: false,
        markers: true,
        onLeave: sectionTitle.play(),
    }
});

 

Link to comment
Share on other sites

Hi .. so I've been playing around with it and I suppose the way to do it would be to add a scroll trigger for each item in the section .. which works fine! 

 

Heres the code for ref: 

 

Many thanks!

 

gsap.from('.section--design .semi-circle-right', {
    x : -485,
    ease: "power.out",
    scrollTrigger: {
        trigger: '.section--design',
        start: 'top center',
        end: 'center center',
    }
});
gsap.from('.section--design .wp-block-column h2, .section--design .wp-block-column p', {
    opacity : 0,
    delay: 1,
    y: 40,
    stagger: .2,
    scrollTrigger: {
        trigger: '.section--design',
        start: 'top center',
        end: 'center center',
    }
});

 

Link to comment
Share on other sites

1 hour ago, geogeo said:

I assume its possible to have more than one scroll trigger on the page?

Yep!

 

21 minutes ago, geogeo said:

the way to do it would be to add a scroll trigger for each item in the section .. which works fine! 

I would rewrite that code that you have to use a single ScrollTrigger applied to the timeline itself (as the article I linked to discussed) and then fire both animations at time 0 using the position parameter.

 

P.S. ease: "power.out" is an invalid ease. There needs to be a number like "power1.out" which is equivalent to just "power1" since .out is the default. See the most common GSAP mistakes for more info.

Link to comment
Share on other sites

Thanks so much, that is a much better solution! 

Here's what I got:

 

const design = gsap.timeline({
    ease: "power1.out",
    scrollTrigger: {
        trigger: '.section--design',
        start: 'top center',
        end: 'center center',
        markers: true,
        toggleActions: 'play none reverse none',
    }
});
design
    .from('.section--design .semi-circle-right', { x : -485 } )
    .from('.section--design h2, .section--design p', {
        opacity : 0, y: 40, stagger: .2,
    }, "<.5" );

 

 

Link to comment
Share on other sites

  • 3 years later...

Hi

 

There's a difference between reverse and reversed methods.

 

https://gsap.com/docs/v3/GSAP/Tween/reverse()

 

https://gsap.com/docs/v3/GSAP/Tween/reversed()

 

 

The first one (reverse) simply sets the direction of the tween's playhead, while the second (reversed) is both getter and setter.

 

So this pattern you can see kind of often when toggling the direction of a GSAP instance in a single line of code:

t.reversed(!t.reversed());

 

Basically consists in the first expression acting as a setter and the one used as a parameter acts as a getter. The we add the ! operator to use the opposite value. But both instances of the method use the same GSAP instance.

 

The error you're getting is because there's no GSAP instance or anything else in your code defined as t. This should solve the problem you have there

imageCourtain.reversed(!imageCourtain.reversed());

 

Hopefully this helps

Happy Tweening!

Link to comment
Share on other sites

It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or Stackblitz that demonstrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen

 

Using a framework/library like React, Vue, Next, etc.? 

CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: 

 

Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

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...