Jump to content
Search Community

How to animate a ScrollTrigger trigger element

SteveS test
Moderator Tag

Go to solution Solved by Cassie,

Recommended Posts

I am trying to make a react component that produces a parallax effect on its child component. To do so, I am creating a scrollTrigger that starts when the element enters the viewport, and ends when it leaves. However, this requires me to use the element as the trigger and animate it. I'm aware that this is usually recommended against for a variety of reasons, however, in this case I find it works with one exception. Since I want the parallax to be controlled by the initial position of the element from start to end, the default behavior of the trigger bounds not updating is exactly what I want.

However, I am using a .fromTo tween. As a result, the trigger positions are calculated based on the "from" position when instead I want them to be calculated from the elements default position. Is there a way I can get the scrollTrigger to calculate the trigger bounds before the tween is applied?

Relevant code:
 

useEffect(() => {
        const { current: element } = el;

        const parallax = gsap.fromTo(element, {
            translateY: `${amount}vh`
        }, {
            translateY: `-${amount}vh`
        })

        ScrollTrigger.create({
            trigger: element,
            start: "top bottom",
            end: "bottom top",
            animation: parallax,
            scrub: 0.3,
            markers: true
        })
    }, [])

 

  • Like 1
Link to comment
Share on other sites

I'll put one together shortly. That being said I tried the method you are suggested before making the post, the issue being that I'm not aware of a way to have an element ignore its parent. For example, if you want the element to be a flex child, adding a container element can interfere with how that child sits in its higher container.

Link to comment
Share on other sites

If I understand your question correctly, yes, you're animating the trigger element which would affect the start/end positions. If you don't want that, you can either use a wrapper element  - animate the inner element and use the wrapper as the trigger -OR- you can adjust your start/end values according to however far you're moving the trigger.  

Link to comment
Share on other sites

I just want the scrollTrigger to use the elements untweened position values. I've managed to make a janky way of doing it by applying the scrollTrigger to an empty timeline, and then in the next useEffect I add the actual tweens. It works, but it would be much nicer if there were a way to target the elements before the tweens are put on them. Doesn't seem like that's the case though.

Link to comment
Share on other sites

  • Solution
const parallax = gsap.fromTo(
      element,
      {
        translateY: `${amount}vh`
      },
      {
        translateY: `-${amount}vh`
      }
    );

    ScrollTrigger.create({
      trigger: element,
      start: `top-=${amount} bottom`,
      end: `bottom-=${amount} top`,
      animation: parallax,
      scrub: 0.3,
      markers: true
    });

Adjusting your start/end values is probably what you're after?

Link to comment
Share on other sites

8 minutes ago, SteveS said:

That actually might work, but the amount is in VH. Is that a supported relative transforms on the top and bottom?

No, you'd need to convert that to px. 

ScrollTrigger.create({
  trigger: element,
  start: () => `top-=${amount * window.innerHeight / 100} bottom`,
  end: () => `bottom-=${amount * window.innerHeight / 100} top`,
  animation: parallax,
  scrub: 0.3,
  markers: true
});

 

  • Like 2
Link to comment
Share on other sites

This works in preliminary tests! Great! Working with scrollTrigger takes some getting used to, but translating the start and end by the translation amount totally makes sense. It's still not as ideal as getting to initial position to begin with, but it is certainly better than the solution I came up with. Thanks!

Link to comment
Share on other sites

Further testing showed that relative start end in itself didn't fix the issue. For whatever reason, the fromTo tween would complete before the end trigger. My solution was to create a timeline and add a from tween and a to tween manually. After attaching the timeline to the scroller, it now works as expected.

For this to work, the from and to tweens must manually be set to have an ease of "none" otherwise they get the default ease and do not work as intended.

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