Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
BastiArts

Scrolltrigger image sequence

Go to solution Solved by OSUblake,

Recommended Posts

Hi,

I'm currently experimenting with GSAP and I want to create a scrollanimation, where I can scrub through an image sequence. (The end result should be an animation like on Apple's Homepod Landingpage https://www.apple.com/at/homepod-mini/ )
I already implemented that functionality, but when I re-enter the video section and then scroll to the next box again, the following non-video containers are getting overlapped with the previous ones.


- Are nested timelines the right approach?

- How can I set different start timings & speeds for each element (in my case the Textbox) within a nested timeline? (e.g. if the image-sequence should last longer (= speed is slower than original)) Or do i need an extra timeline for that?

 

Thanks in advance!

See the Pen OJxoKPx by BastiArts (@BastiArts) on CodePen

Link to comment
Share on other sites

Welcome to the forums @BastiArts

 

I'm not sure why are you trying to use batch. That's for a very specific use case, usually when doing columns of similar elements.

 

And you should never nest timelines that contain ScrollTriggers, which is what you are doing by adding all your timelines to master. Check out article on the most common ScrollTrigger mistakes.

 

 

You should probably create a ScrollTrigger and timeline for each section. The speed is controlled by the scroll distance, so to make something slower you would need to increase how much you have to scroll. And of course you can position stuff on the timeline using the position parameter.

 

Related post on scrubbing and timelines...

 

 

 

Link to comment
Share on other sites

Thanks!

14 hours ago, OSUblake said:

I'm not sure why are you trying to use batch.

My intention was to load the necessary images of each sequence if the video-box is visible in the viewport, hence it reduces the loading time of the page significantly. (...or ideally load the frames one section before each video box).

Do I have to create a standalone ScrollTrigger in addition to the triggers per container or should I use the IntersectionObserver instead for this case?

 

Link to comment
Share on other sites

Hey there, sorry I don't understand this question.

 

Quote

Do I have to create a standalone ScrollTrigger in addition to the triggers per container


Could you provide an updated demo showing what you mean? 


Also - you shouldn't ever need to use intersection observer and ScrollTrigger together, ScrollTrigger can do everything intersection observer can and more.

 

 

Link to comment
Share on other sites

47 minutes ago, Cassie said:

Hey there, sorry I don't understand this question.

Sorry, I'll try to explain it better:

 

This is the updated Version.

See the Pen jOGeebj by BastiArts (@BastiArts) on CodePen

 

Instead of using the Scrolltrigger.batch() Method, I fetch my sections using gsap.utils.toArray() and looping through them.

This causes all my video-sections to initialize & fetch all images of the sequences.

When using the batch-Method, I was able to initialize only the visible section(s) in the viewport (onEnter Event). So just the necessary images were fetched when the box is entering the viewport. Ideally the frames of the next video box should be loaded one section ahead.

This will reduce the initial pageload and make sure, that the majority of the frames are loaded when the users scrolls through the video section.

 

This brings me to my question:

- How do I check, if a section enteres the viewport?

 

Link to comment
Share on other sites

Oh ok I get you,

If you're using a loop you can use the index value to work out which section you're entering.

 

boxes.forEach((box, i) => {
   
  ScrollTrigger.create({
    trigger: box,
    start: "top bottom", 
    onEnter: () => {
      initCanvas(box, i)
    }
  });
  
}
              
function initCanvas(box, i) {
  // get the image(s) you need based in the index value
}

 

See the Pen bGomQwp?editors=1011 by GreenSock (@GreenSock) on CodePen

 

Hope this helps!

  • Like 1
Link to comment
Share on other sites

Thanks for your quick reply!

 

See the Pen gOGBQBM by BastiArts (@BastiArts) on CodePen

 

Unfortunately I'm getting the same problem as yesterday again:

23 hours ago, BastiArts said:

when I re-enter the video section and then scroll to the next box again, the following non-video containers are getting overlapped with the previous ones.

 

Without the viewport detection it works like a charm (but loads all images at once), but as soon as I use the onEnter Method with the ScrollTrigger Object, it breaks.

I'm a bit confused now.

- Is there something wrong with my timeline(s)?

Link to comment
Share on other sites

I would suggest creating everything using a normal timeline and ScrollTrigger. Don't get creative with the loading process as it's not even tied to your timeline or ScrollTrigger. Your timeline and ScrollTrigger will work correctly with 0 images loaded.

 

Once you get it working, if you want to defer the loading of images, you can do that in the onEnter and onEnterBack callbacks. Just be careful you don't keep trying to load images after they are loaded. 

 

  • Like 2
Link to comment
Share on other sites

 

See the Pen KKXrXvP by BastiArts (@BastiArts) on CodePen

 

19 hours ago, OSUblake said:

it's not even tied to your timeline or ScrollTrigger

In my example above, I use the onUpdate Event of the timeline to replace the frames. So this part of the timeline depends on the loaded images.

Or can I intercept the onUpdate Event of the timeline at another point in the code?

And the other problem is, that I have two types of animations in the video section:

1) the main video part

2) The text animation

and I want the text animation to last shorter than the video sequence, but still react to a scrollTrigger, so i created a separate scrolltrigger only for that textbox.

Also only the video sections get pinned and the text-containers don't.

 

Link to comment
Share on other sites

Update:

I finally brought it on the right track :)

The last thing I noticed, is a little flicker when my images are replaced after scrolling through two following video boxes. I think this is because of the scrolltriggers.. 🤔

 

See the Pen vYeQrLe by BastiArts (@BastiArts) on CodePen

 

One question:

I used one scrolltrigger on the timeline itself (viewport detection & text animation) and another scrolltrigger for the image animation (for scrubbing, pinning, etc.) within the same timeline.

- Am I doing it right this time?

 

By the way: Many thanks for the excellent support!

Link to comment
Share on other sites

14 minutes ago, BastiArts said:

I used one scrolltrigger on the timeline itself (viewport detection & text animation) and another scrolltrigger for the image animation (for scrubbing, pinning, etc.) within the same timeline.

- Am I doing it right this time?

Actually no - that's one of the common mistakes :)

 

Logic-wise, it's impossible. When you nest an animation in a timeline, that means that the playhead of the parent timeline is what controls the playhead of the child animations (they all must be synchronized otherwise it wouldn't make any sense). When you add a ScrollTrigger with scrub, you're basically saying "I want the playhead of this animation to be controlled by the scrollbar position"...you can't have both. For example, what if the parent timeline is playing forward but the user also is scrolling backwards? See the problem? It can't go forward and backward at the same time, and you wouldn't want the playhead to get out of sync with the parent timeline's. 

 

So definitely avoid putting ScrollTriggers on nested animations. 

 

18 minutes ago, BastiArts said:

The last thing I noticed, is a little flicker when my images are replaced after scrolling through two following video boxes. I think this is because of the scrolltriggers.. 🤔

It's a lot to ask - digging through 200+ lines of JS to find whatever logic might be causing it would take time and goes beyond what we generally provide for free in these forums. You'll greatly increase your odds of getting a solid answer if you can isolate just that one thing in a minimal demo that has the smallest amount of code possible. Troubleshooting is typically all about working to isolate, isolate, isolate. Simplify. So just a few images, maybe only two short sections, etc.

 

From a quick glance at the code, it looks like you might be using a single animation {frame:0} object for ALL of your canvas animations, so that may explain the issue. In other words, if scrolling backwards canvas 2 animates animation.frame back to 1 and then you hit canvas 1 whose frame should be at the end (let's say 60) but animation.frame is at 1 from canvas 2 - it may render that canvas at frame 1 initially. Solution: use a different proxy object for each canvas so they don't screw with each other's values :)

 

Looks like a cool effect, though - nice work. 

  • Thanks 1
Link to comment
Share on other sites

  • Solution

It looks like GreenSock answered most of the issues while I was in the middle of making a simplified demo.

 

You keep passing around different variables which makes your code hard to follow, but you are also creating a bunch of mistakes, like your animateContent function keeps getting called over and over again, creating additional animations and ScrollTriggers.

 

I would try to keep everything scoped to a particular function kind of like this.

 

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

 

5 hours ago, BastiArts said:

So this part of the timeline depends on the loaded images.

 

And again, the timeline will still work correctly if 0 images are loaded. The timeline has no concept of whether or not the images are loaded. All the timeline is doing is animating a simple object with a frame property. 

 

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

19 hours ago, GreenSock said:

Logic-wise, it's impossible. When you nest an animation in a timeline, that means that the playhead of the parent timeline is what controls the playhead of the child animations (they all must be synchronized otherwise it wouldn't make any sense). When you add a ScrollTrigger with scrub, you're basically saying "I want the playhead of this animation to be controlled by the scrollbar position"...you can't have both.

Ahhh now I understand.

 

19 hours ago, GreenSock said:

It's a lot to ask - digging through 200+ lines of JS to find whatever logic might be causing it would take time and goes beyond what we generally provide for free in these forums.

Totally understandable! I'm sorry. Next time I'll try to isolate it as much as possible.

 

Thank you so much @GreenSock @OSUblake & @Cassie for your excellent support! :)

It finally works now 🎉

 

Here's my working version:

 

See the Pen PoJXqVX by BastiArts (@BastiArts) on CodePen

 

  • Like 2
Link to comment
Share on other sites

  • 3 months later...

Sorry for hopping onto an old thread, but @OSUblake how would you port the demo you've built into React ?

Because I've changed it to useRef and my actual words animate, It's just the canvas that gives and error ?

Link to comment
Share on other sites

Hi @GrantCahn

 

It would be better if you started a new topic and include a minimal demo of what you've tried. We don't need to see your whole project, just what's relevant to the animation at hand. If you need to use React, you can use CodeSandbox.

 

Link to comment
Share on other sites

Hey hey.

Okay cool thanks will do. 

 

Think I'm just missing one small thing but can't for the life of me figure it out 🙃

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