Jump to content
Search Community

Draggable, Inertia, Observer's onMove

Thisjustin test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hello,

 

I'm trying to create a Draggable element with Inertia but I would like it to without clicking down to drag. Elements would interact with the pointer as if they were being dragged and moving the pointer quickly would initiate a throw. I know this isn't technically dragging behaviour but it would be sort of similar to how Draggable works on a touch device no? Am I missing a very easy setting in Draggable to turn this on?

 

I know that with Observer you can define onMove which will fire for all movement when hovering over the trigger element. Not sure what to do from there though.

 

Is there some way to combine these two concepts to achieve what I'm imagining? Is there another approach I should be taking?

 

Thanks in advance for your help!

See the Pen qByjdKX by Thisjustin3141 (@Thisjustin3141) on CodePen

Link to comment
Share on other sites

  • Solution

Hi,

 

Basically you want a mouse following element (as @mvaneijgen points) but with inertia built in it?

 

You can use the startDrag() and endDrag() methods but I'm not sure the result is what you're after:

gsap.registerPlugin(Draggable, InertiaPlugin);

const element = document.querySelector(".element");

const myDrag = Draggable.create(".element", {
  bounds: $(".container"),
  type: "x,y",
  inertia: true,
  onMove: true
});

element.addEventListener("mouseenter", (e) => {
  myDrag[0].startDrag(e);
});

element.addEventListener("mouseleave", (e) => {
  myDrag[0].endDrag(e);
});

Maybe you could use this approach with the mouse follow logic in order to center the element at the pointer and use Inertia Plugin's Velocity Tracker to check the speed and at some speed trigger the endDrag in order to start the throw of the element.

https://greensock.com/docs/v3/Plugins/InertiaPlugin/VelocityTracker

 

Other than that you'll need a custom plugin or logic to accommodate what you want. That's definitely doable but not simple. You have to set a threshold for the pointer speed, track the speed and direction, estimate the landing point, set boundaries and finally create the GSAP Tween to move the element. Then consider touch devices.

 

As you can see both approaches have it's own complexities and, while a GSAP related situation, is more than we can tackle here in these forums.  Perhaps @GreenSock can think of an easier way that's eluding me right now. Maybe another user has the time and is willing to tackle this, other than that you can post in the Jobs & Freelance forums or contact us directly for a consulting job.

 

Good luck with your project and let us know if you have more questions.

 

Happy Tweening!

  • Thanks 1
Link to comment
Share on other sites

Thanks @Rodrigo!

 

This is pretty much what I was thinking, although you're right it's maybe a bit of a weird effect. Basically I wanted to have the element be somewhat effected by the mouse passing through it but not completely – like waving your hand through smoke or something. Not asking you to solve that problem just explaining myself.

 

I thought I had tried onMove in Draggable but perhaps I didn't have it set up right. Your example works but I'll keep playing with it!

Link to comment
Share on other sites

2 hours ago, Thisjustin said:

Basically I wanted to have the element be somewhat effected by the mouse passing through it but not completely

I see. That is a different scenario. Simpler, still not super easy but definitely simpler than what I envisioned from your first post.

 

What I'd do is register the X and Y position of the mouse (relative to the viewport, not the target element) and the time in ms (Date.now()) on mouse enter. Then on mouse leave do the same. With the elapsed time you the duration for the event of the mouse passing by soto speak. If you set a base speed for your animation (distance-in-px/time) and create some simple custom tabulated values that gives you the following result:

  • short time span -> longer duration
  • long time span -> shorted duration

Then with the start and end coordinates you should be able to draw an imaginary vector that gives you the end x and y points based on the center of the element and the previous calculations I mentioned for setting the distance the element should move. For that you need the element's current x and y (relative to the viewport or it's parent) and then you set the final x and y values based on the duration of the motion you get from your custom table (the one I mentioned above). For that my first attempt would be the linear motion equation:

x = vi•t + 0.5*a*t2

Where X is the final X position. Vi is the initial velocity (super easy 0. Make this 0 on mouse enter in order to make your life simpler for now). t is the duration of the motion (you got that already from the table). a is the acceleration (that is your base speed in px per seconds divided by the duration of the interaction. Here the base speed I mentioned and the duration of the interaction you already have it) and t2 is time square, which you also already have. Rinse and repeat for the Y axis.

 

As I mentioned this is simpler, not super easy but way easier than the previous approach. This is basically high school physics for projectile motion on one or both axis without gravity, just deceleration.

 

Hopefully this helps and thanks for sending me back to mechanics on my first year of college :D

 

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