Jump to content
Search Community

Combining gsap transformation with another scrolltrigger effect

maxvia test
Moderator Tag

Go to solution Solved by ZachSaucier,

Recommended Posts

Hi,

 

I am trying to implement the first horizontal section effect of the following website:  https://rino-pelle.com/

 

Images are moving from right to left when you are not doing anything BUT moving faster when scrolling down.

 

I know how to accomplish the first part using as example the following code: 

 

        gsap.to(movableImageWrapper, 
            {   xPercent: -100, duration: 40, repeat: 100, 
                ease: 'none'}, '<'
            )

 

I also know how to accomplish the 2nd part using scrolltrigger: 

        gsap.timeline(movableImageWrapper, {xPercent: -100,
            scrollTrigger: {
              trigger: mainSection,
              start:"top 50%",
              end: "bottom 300",
              scrub: true,
              toggleActions: "play none none none",
            }
          })

 

However where I am confused is how to combine both because if I try doing this my scrolltrigger function will move my images depending of their original axis not the current one (not sure if I am clear).

 

How would you guys proceed with that? is there anw to track the first transformation ?

 

Thanks for the tips

 

Btw I am using react but js is fine as well

 

Thank you

Link to comment
Share on other sites

Hey maxvia. I'd make use of ScrollTrigger's .getVelocity() method paired with GSAP's modifiers to do this. Modifiers will also help with the infinite wrapping (GSAP's wrap utility method can also help there). You will want to animate each element individually so that you can wrap it properly. That also means that you should probably stick to the x property instead of xPercent.

  • Like 3
Link to comment
Share on other sites

hey @ZachSaucier,

 

Thank you for pointing out the different options I have however after some hours looking for the solution, I wasnt able to come to a good one that.

 

I first took care of the scrolltrigger method this way: 

 

        const imagesScrollerTrigger = ScrollTrigger.create({
            trigger: mainSection,
            start:"top 50%",
            end: "bottom 50%",
            markers: true,
            ease: 'none',
            onUpdate: function(self) {
            
              let velocity = self.getVelocity() 
              //first image
              let axis = images[0].getBoundingClientRect().x
              firstImagesAxisValue = axis
            
              if (velocity > 0) {   
                gsap.to(moveImages, {
                    ease: "none",
                    x: calculateNewX(velocity, axis), 
                    modifiers: {
                      x: gsap.utils.unitize(x => parseFloat(x) % -window.innerWidth ) 
                    }, 
                 })

                 timelineImage.pause()

              }
            }
           })

I am quite happy with my scrolltrigger. It is working fine and the images are moving to speed I like. Also I dont want them to move on scroll up thats why I only make change is the velocity is positive.

 

then I set up a timeline as follow :

        let timelineImages = gsap.timeline()
        timelineImages.fromTo(imagesArray, {
          		//x value of my first image 
                x: images.current[0].getBoundingClientRect().x,
                }

            , {
                ease: "none",
                duration: 40,
                x: -window.innerWidth, 
                repeat: -1
            })
        }

My first intention was to do when scrollTrigger onUpdate isActive => timeImages.pause() and when onUpdate is not isActive =>  timeIineImages.play() or .restart() (in order to have  a new accurate value of from x, since this one was modified by the scrolltrigger)

 

Is there anyway to do such a thing or I try another way?

 

Thank you!

Link to comment
Share on other sites

1 hour ago, maxvia said:

My first intention was to do when scrollTrigger onUpdate isActive => timeImages.pause() and when onUpdate is not isActive =>  timeIineImages.play() or .restart() (in order to have  a new accurate value of from x, since this one was modified by the scrolltrigger)

 

Is there anyway to do such a thing or I try another way?

You technically could do something like this by using a setTimeout or GSAP delayedCall but I would think you would have syncing issues unless your animations are affecting different elements (like a container instead for one of them).

 

Why not use modifiers like I suggested? 

 

I would likely set things up along the lines of this (pseudo-code):

let additionalY = { val: 0 };
let additionalYAnim;

items.forEach(item => {
  gsap.to(item, {
    x: -containerWidth,
    modifiers: {
      x: gsap.utils.unitize(x => {
        (parseFloat(x) + additionalY.val) % -containerWidth
      })
    }
  });
});

const imagesScrollerTrigger = ScrollTrigger.create({
  trigger: mainSection,
  start: "top 50%",
  end: "bottom 50%",
  markers: true,
  ease: 'none',
  onUpdate: function(self) {
    const velocity = self.getVelocity();
    
    if(additionalYAnim) additionalYAnim.kill();
    
    additionalYAnim.val = velocity/1000;
    
    if (velocity > 0) {   
      additionalYAnim = gsap.to(additionalY, { y: 0 });
    }
  }
})

 

  • Like 2
Link to comment
Share on other sites

thanks for the reply Zach 

 

So this wouldnt work if I add a duration value? 

items.forEach(item => {
  gsap.to(item, {
    x: -containerWidth,
    modifiers: {
      x: gsap.utils.unitize(x => {
        (parseFloat(x) + additionalY.val) % -containerWidth
      })
    }
  });
});

I wanted my animated to go over all the picture within 40 second so I added to duration: 40 as a paramaters. If i remove the duration parameters it goes way to fast. It takes about one second to go all over the pics.

 

It was working fine, meaning all the pics were moving on their own, however I tried to give a value to  additionalY.val to see if it would go faster but it was changing changing anything. Animation was not going faster. 

 

Also, sorry but I am confused about this part? 

 

    if (velocity > 0) {   
      additionalYAnim = gsap.to(additionalY, { y: 0 });
    }

Did you mean the array of items instead of additionalY? 

 

 

Link to comment
Share on other sites

Adding a duration is fine.

 

24 minutes ago, maxvia said:

Did you mean the array of items instead of additionalY?

Nope. The goal of my approach is to have a single object that is storing the additional (i.e. increased speed) value. So you update one thing when ScrollTrigger updates and that one thing is used to affect the offset of all of your other tweens.

 

Perhaps it would be helpful if you made a minimal demo of what you're trying.

  • Like 1
Link to comment
Share on other sites

I created the following codepen with the pseudo code you gave me. 

See the Pen QWKEevR by skima37 (@skima37) on CodePen

 

As you can see, the first method is working fine however the second one (the one using scrolltrigger) is buggy at the moment.

What I basically want is that whenever I am scrolling and I am within my scrolltrigger area, I want my images going left faster relative to my scrolling activity.

 

 

Thank you Zach

Link to comment
Share on other sites

  • Solution

You've got several logical issues. As I said, my code was very much pseudo-code. Fixing the logic issues you should get something like this:

See the Pen NWRRKQg?editors=1000 by GreenSock (@GreenSock) on CodePen

 

With that being said, I don't really understand what you're trying to do with the "hidden images". It'd probably make more sense to absolutely position the images because the calculations are harder if you don't. There are a lot of examples of how to do wrapping like this including these:

See the Pen e09daad9223a4745f12934332ac11afa by ZachSaucier (@ZachSaucier) on CodePen

 

That'd probably fix the flashing issue that the pen I included above has.

  • Thanks 1
Link to comment
Share on other sites

7 hours ago, maxvia said:

In this particular exemple. Is it the wrapping + the updateProgress function that makes the animation infinite?

Yes, those are key parts. I encourage you to spend time understanding exactly what my code is doing in both examples :) That will help you figure out the differences in the approaches and how you can make an approach that exactly fits your needs.

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