Jump to content
GreenSock

Akash Ranjan

Smoothly play video on scrolltrigger

Recommended Posts

Hello guys,

 

I am stuck in a really bad situation and cant find a solution of it.  So what I am trying to achieve is that I want to play a video smoothly on scrollTrigger scrub but that is not happening. The video is playing very choppily. I have a created a minimal codesandbox for you guys to have a look

 

https://codesandbox.io/s/gracious-sunset-0xsvr?file=/src/pages/index.jsx

 

Please help me as I am stuck on this for 2 days :(

 

Thanks

 

Link to comment
Share on other sites

Hi Akash, 

 

I can't even get that sandbox running, but if the video is choppy, it's probably because of the encoding.

 

 

 

An alternate way would be to use images instead, kind of like here.

 

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

 

 

  • Like 1
Link to comment
Share on other sites

Yep, I bet Blake is right - the video MUST be encoded with very frequent keyframes so that you can jump around smoothly. This has nothing to do with GSAP - it's the nature of video encoding. When you encode your video that way, it'll also increase the file size because it must use more keyframes. I'd encourage you to research how encoding works and keyframe placement during the encoding process. You might want to try switching to that other technique Blake mentioned and see if that works better for you. 

Link to comment
Share on other sites

Hey,

 

Thanks for the response. @OSUblake I tried and implemented the image sequence on my code, but stuck in one error that is frame number. So what I am trying to achieve is that once user reaches certain frame a class will be added to the content div. But I am unable to fetch the current frame number. Can you help me here please.

 

Thanks alot for the help

Link to comment
Share on other sites

You can calculate at what time you will hit a certain frame, and then add a callback to your timeline. So let's say you want to add it at frame 45, and the duration of the animation is 1 sec, you would do this.

 

let tl = gsap.timeline({
  onUpdate: render,
  scrollTrigger: {
    scrub: 1,
  }
});

tl.to(airpods, {
  ease: "none",
  frame: frameCount - 1,
  snap: "frame",
  duration: 1
});

tl.add(() => {
  console.log("hit frame", airpods.frame);
  
  // add your class
}, 45 / (frameCount - 1))

 

Link to comment
Share on other sites

Hey @OSUblake,

 

Can you also please tell me what is the best approach for tweening single element multiple times. For example I want a sticky card to show when in view but then hide it after the card reaches the next section.

 

I tired below method but it does not work. Can you please help me here

 

useEffect(() => {
    tl.current = gsap.timeline().from(section1Asset1.current, {
      scrollTrigger: {
        trigger: section1.current,
        start: 'top 50%',
        end: '30% 40%',
        scrub: true,
        // markers: true,
      },
      autoAlpha: 0,
      x: '80%',
      duration: 1,
      ease: 'power2.out',
    });
    
    tl.current = gsap.timeline().to(section1Asset1.current, {
      scrollTrigger: {
        trigger: section1.current,
        start: '60% 50%',
        end: '80% 40%',
        scrub: true,
        markers: true,
      },
      autoAlpha: 0,
      scale: 0,
      duration: 1,
      ease: 'power2.out',
    });
   
  }, [tl]);

Thanks

Link to comment
Share on other sites

It's hard to say without a minimal demo. If I'm animating something more than once, I will usually make it part of a timeline, and you can usually get it like you want by adjusting the durations and position parameter.

 

Also, when you have a timeline, it's always best to keep the scrollTrigger part inside the timeline creation.

 

// bad
tl.current = gsap.timeline().from(section1Asset1.current, {
      scrollTrigger: {
        trigger: section1.current,
        start: 'top 50%',
        end: '30% 40%',
        scrub: true,
        // markers: true,
      },
      autoAlpha: 0,
      x: '80%',
      duration: 1,
      ease: 'power2.out',
    });

// good
tl.current = gsap.timeline({
    scrollTrigger: {
        trigger: section1.current,
        start: 'top 50%',
        end: '30% 40%',
        scrub: true,
        // markers: true,
    },
}).from(section1Asset1.current, {      
      autoAlpha: 0,
      x: '80%',
      duration: 1,
      ease: 'power2.out',
    });

 

Link to comment
Share on other sites

  • 3 weeks later...

Hi @OSUblake,

 

Can you help me with preloading the image sequence in the canvas. I have searched everywhere but i am unable to find any solution.

 

This is the same code I am using for my animation. The issue is that my images are around 7mb in total.

 

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

 

Thanks

Link to comment
Share on other sites

What do you mean by preloading, like  you want it display something else until they are loaded? Because I think the way I have set it up is probably the best approach as you don't have to wait for all the frames to be loaded.

Link to comment
Share on other sites

Hi @OSUblake,

 

By preloading i mean loading all the frames then playing the animation as currently there is a stutter between frames as it looks like some frames are not loaded.

Link to comment
Share on other sites

So what should happen while it's loading? Display nothing, have a placeholder image, etc?

Link to comment
Share on other sites

Yes like a counter of some sort. counting from 0% to 100%

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