Jump to content
Search Community

GSAP Observer velocity drag

thehaes test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hey guys, I convinced (well, I didn't have to convince, just asked hah) my company to buy shockingly green package and started to playing around with some stuff.

 

I have a horizontal, looping slider setup with scrollTrigger.observe and it works as I want it, except for one thing - dragging.

I am using velocityY to speed up & reverse slider left/right (actually it updates timeScale of timeline based on velocityY) as you normally scroll down using scroll wheel. I add 'pointer' type to the observer but the problem is it only works on dragging up/down (velocityY). Is there any way to "switch" the velocityY for X just for pointer event? I was thinking to just create another observer, but I'm not sure if I can create more observers and it won't affect performance or create conflicts? Or will I have to use draggable (didn't try it yet so I'm not sure if I can wrap my head around it). I've been thinking about it for too long and my mind feels full of different ideas and I'm confused. The solution is probably right in front of me and it's easy, but I can't see it. I need a break :D

 

I will appreciate any help, direction or suggestion. Thanks!

 

EDIT: I actually made second observer just for pointer, it works and I think it doesn't affect performance, but I'm not sure if it's a good practice, so still would want to know.

 

See the Pen qBoVXXx by thehaes (@thehaes) on CodePen

Edited by thehaes
Link to comment
Share on other sites

  • Solution

First of all, congrats on getting your employer to join Club GreenSock💚 Welcome aboard.

 

I'm not entirely sure I understand your goal here. 

 

By the way, you can directly animate the timeScale on another animation without using a proxy object, so you can simplify this code: 

// OLD
if (container.classList.contains("paused")) {
  gsap.fromTo(object, { 
    value: v 
  }, {
    value: 0,
    duration: 1,
    onUpdate: () => {
      tl.timeScale(object.value);
    }
  });
} else {
  gsap.fromTo(object, { 
    value: v 
  }, {
    value: resting,
    duration: 1,
    onUpdate: () => {
      tl.timeScale(object.value);
    }
  });
}

To just this: 

// NEW
gsap.to(tl, {
  timeScale: container.classList.contains("paused") ? 0 : resting,
  duration: 1
});

 

And yeah, I can't imagine that having a 2nd Observer would cause any performance issues whatsoever. 

 

But honestly, you really should look at the helper function in the docs that probably solves a ton of the problems you're trying to solve with this. Here's a fork with that: 

See the Pen yLKPpVY?editors=0110 by GreenSock (@GreenSock) on CodePen

  • It's draggable
  • It's responsive
  • It applies smooth inertia (flick-dragging)
  • It spits back a timeline that you can do whatever you want with
  • It can ensure that it always smoothly stops when the left edge of one of the elements is lined up with the left of the container.

I hope that helps.

  • Like 1
Link to comment
Share on other sites

Wow, thanks @GreenSock This is much better than what I had. Just few last questions:

 

1) Do I need to include draggable & inertia plugin, or just inertia plugin is fine?

2) In the original script, if you scroll/drag outside slider, it continues looping after scroll stops and if you scroll and stop while cursor is on the slider, the looping stops (just so you can hover over other images in peace), but in your build if you scroll with cursor over slider, it continues to move. In my script I used if statement with 2 different tweens depending if slider had 'paused' class. Not sure how to achieve it here.

3) And last thing - if you scroll with cursor over slider and move your cursor while the velocity goes up, slider starts to move very fast and won't stop or just stops abruptly, I think it's related to mouseenter event? (You need to change body heeight to 100vh to see that)

Link to comment
Share on other sites

17 hours ago, thehaes said:

1) Do I need to include draggable & inertia plugin, or just inertia plugin is fine?

If you want it to be draggable, you need Draggable :)

 

If you want inertia to work, you'll need InertiaPlugin. 

 

17 hours ago, thehaes said:

in your build if you scroll with cursor over slider, it continues to move.

You can just add conditional logic to handle that if you want. I updated my demo with a simple check, but you may need to tweak to get whatever behavior you want. 

 

17 hours ago, thehaes said:

if you scroll with cursor over slider and move your cursor while the velocity goes up, slider starts to move very fast and won't stop or just stops abruptly, I think it's related to mouseenter event?

I'm having a tough time reproducing that, but it's probably resolved anyway by the tweak mentioned above. My intention here wasn't to build everything for you, but rather to get you going in a helpful direction. 👍

 

Good luck!

  • Like 1
Link to comment
Share on other sites

Thanks @GreenSock

Sorry if I overused your help, I just spent much time trying to figure this out before I came on the forums and I felt like I was running circles and not knowing what I'm doing anymore. Now it's much more clear and I'll continue on my own from this point, thanks again! :)

  • Like 1
Link to comment
Share on other sites

13 hours ago, thehaes said:

Thanks @GreenSock

Sorry if I overused your help, I just spent much time trying to figure this out before I came on the forums and I felt like I was running circles and not knowing what I'm doing anymore. Now it's much more clear and I'll continue on my own from this point, thanks again! :)

No no, it's fine - I didn't meant to imply you have overused our help. I just like to manage expectations, that all. We're happy to help, particularly with GSAP-specific questions!

 

Good luck and let us know if you get stuck. 

Link to comment
Share on other sites

On 7/31/2022 at 3:20 AM, GreenSock said:

No no, it's fine - I didn't meant to imply you have overused our help. I just like to manage expectations, that all. We're happy to help, particularly with GSAP-specific questions!

 

Good luck and let us know if you get stuck. 

Actually, I still can't get over one issue and I really don't know what I'm doing anymore. This is the last and only thing I need to make it work the way I want to - I'll try to explain it as best as I can:

 

First of all, I removed the isOver, as I still want to be able to scroll slider loop, while cursor is over the images.

The thing I have problem with setting up right is:

- when you start scrolling and won't move your cursor, the slider slowly stops as it should (using a touchpad currently, but same behaviour happens on mouse wheel scroll). - this is working good.

- but when you start scrolling and move your cursor, it starts to move the slider at continues speed, based on the last velocity value before you moved the mouse

- this behaviour only occurs on scroll, the drag works fine

 

I'm attaching a video to show what I mean:

https://www.dropbox.com/s/us0q2n29wuxq17t/slider-recording.mov?dl=0

 

I really have no idea what to change here, I tried using if statement like last time, but it didn't work with this setup. The only thing I found out is that similar behaviour happens on basic browser scroll: if you scroll with mouse/touchpad and won't move cursor, the scroll will get to its final position smoothly, but when you move your mouse while this is happening, the scrolling will stop instantly. So I guess what's happening here is that when you start moving the cursor and scroll stops abruptly, the latest value of velocityY before the stop is being read and it continues to scroll at that value and it doesn't change anymore (normally the velocity will gradually go down to 0).

 

Sorry for bringing this up again, but I really cannot solve it...

Link to comment
Share on other sites

  • 3 months later...
15 hours ago, Rodrigo said:

Hi,

 

In what particular browser/device combination this is not working?

 

Everything is working as expected on Chrome and Firefox on an Android device as I swipe left/right.
 

Happy Tweening!

Doesn't work in Safari browser on iPhone =/

Link to comment
Share on other sites

3 minutes ago, GreenSock said:

Can you please be more specific? I just tried dragging/swiping on my iPhone and it appeared to work perfectly. What am I missing? What exactly must we do to reproduce the problem you're seeing? 

image.thumb.png.480f60fe53eae90994a0fdc7dc879a08.png

 

Also, for some reason the indentation is small when cards are added.

Link to comment
Share on other sites

Hi,

8 hours ago, vadbiz said:

That is, after the drag, the animation seems to stop and is no longer played at all.

 

OK, thanks for that information, I can see the confusion now. There is no issue at all here, everything is working as expected. The difference between desktop and a touch device are these event handlers:

container.addEventListener("mouseenter", () => {
  reversedOnPause = tl.timeScale() < 0;
  isOver = true;
  gsap.to(tl, {timeScale: 0, duration: 1, overwrite: true});
  container.classList.add("paused");
});
container.addEventListener("mouseleave", () => {
  isOver = false;
  gsap.to(tl, {timeScale: reversedOnPause ? -1 : 1, duration: 1, overwrite: true});
  container.classList.remove("paused");
});

So when there is a touch start event in a device it acts as a mouse enter, but the touch end doesn't act like a mouse leave, you actually have to touch elsewhere, outside the boundaries of the container element, to trigger the mouse leave. If you remove those event listeners or add a different logic for touch events it should work as expected.

 

Happy Tweening!

  • Like 1
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...