iggy

How to get draggable dragging speed?

Recommended Posts

I am learning how this water bottle slider Codepen by Chris Gannon works. I created my own SVGs and tried animating it myself and I was able to replicate it fairly well. 

 

However, there is a part of code that I still do not understand. They all have similar pattern and I think I know what they do, but I can't wrap my head around how they work. 

 

    TweenMax.to(this.follower, 1, {
      x:'+=1',
      repeat:-1,
      modifiers:{
     x: (x, target) => {   
      followerVX += (this.bottle._gsTransform.x - this.follower.x) * 0.08;
      followerVX *= 0.79;
      return this.follower.x + followerVX;    
     }
    }
   })   
    
    TweenMax.to(this.liquidFollower, 1, {
      x:'+=1',
      repeat:-1,
      modifiers:{
       x: (x, target) => {   
        liquidFollowerY += (this.bottle._gsTransform.x - this.liquidFollower.x) * 0.8;

        liquidFollowerY *= 0.7;

        return this.follower.x + liquidFollowerY;    
       }
      }
     })   
    
    TweenMax.to(this.bottleLiquid, 1, {
      rotation: '+=0',
      repeat: -1, 
      modifiers: {
        rotation: (rotation, target) => {
          let val = rotation + liquidFollowerY * 0.5;
          return val
        }
      }
    })

 

I think this code above rotates the water level based on how fast the dragger goes. If I drag it super quickly, it will create higher rotation. If I drag it verrryyy slowly, it would hardly make any rotation.

 

Therefore, the rotation value depends on draggable speed.

 

However, I can't figure out why the code above helps us to find draggable speed. Is this a somewhat common pattern to find draggable speed? If not, is there a more convenient way to find how fast a user drags an object/ what would you do to find how fast a draggable object is being dragged? I have checked out both draggable and modifiers plugin, but didn't find any clue. 

Share this post


Link to post
Share on other sites

Hi,

 

Nice work on the demo.

I don't know exactly how Chris finds the velocity and applies it but I suspect it's in here as it appears he is using the distance between 2 things to generate a value:

 

modifiers:{
       x: (x, target) => {   
        liquidFollowerY += (this.bottle._gsTransform.x - this.liquidFollower.x) * 0.8;

        liquidFollowerY *= 0.7;

        return this.follower.x + liquidFollowerY;    
       }
      }

 

The official way to track velocity with GSAP is with.... VelocityTracker which is a bonus utility for Club GreenSock members (Shockingly and higher)

 

https://greensock.com/docs/Utilities/VelocityTracker

  • Like 3

Share this post


Link to post
Share on other sites

As always, very helpful response! Thanks @Carl! Reading your response just triggered the answer haha! This person created an additional property (this.liquidFollower) which has {x: someValue}. It is supposed to be following wherever the draggable object is.

 

At the moment I dragged the water bottle, say, 100 distance away,  at that time, this.bottle._gsTransform.x will be at x = 100, whereas this.followerLiquid is still at x: 0. This triggers modifiers. Modifiers does the subtraction and... voila! The difference is 100. Difference is huge. Since difference is huge, liquidFollowerY value is also huge, creating huge rotation. As this.followerLiquid is catching up, the differences are diminishing. Since the differences are getting smaller/ diminishing, the rotation is also getting smaller.

 

If I dragged the water bottle only 5 distance away, that very instance, this.bottle._gsTransform.x - this.liquidFollower.x will have value of 5, not so great. So rotation will only be very small.

 

It is pretty smart way to achieve different effect depending how "fast" an object is being dragged. To recap:

1. Apply Draggable on object

2. Create a "follower" object. Applies Tween to it to follow that draggable object mentioned on step 1.

3. Measure the distance at ANY TIME using modifiers plugin. The distance tells how fast that object is initially dragged. Over time it will diminish and eventually catch up.

 

I hope my mumbling makes sense! This is ingenious! Wouldn't have thought it out without your help. Thanks!!

Share this post


Link to post
Share on other sites

Hi,

 

Chris' magic comes from this two instances:

 

TweenMax.to(this.liquidFollower, 1, {
	x:'+=0',
	repeat:-1,
	modifiers:{
	 x: (x, target) => {   
		liquidFollowerY += (this.dragger._gsTransform.x - this.liquidFollower._gsTransform.x) * 0.98;
		liquidFollowerY *= 0.97;
		return this.follower._gsTransform.x + liquidFollowerY;    
	 }
	}
 })   


 TweenMax.to(this.boxFill, 1, {
	rotation:'+=0',
	repeat:-1,
	ease: Linear.easeNone,
	modifiers:{
	 rotation:(rotation, target) => {
		 return (rotation+liquidFollowerY*0.35)
	 }
	}
 })

 

Basically He's using the modifiers plugin to track the difference between the x position of the dragger and a liquidFollower, all  dummy elements:

 

<circle class="follower" cx="0" cy="0" r="0" fill="green" fill-opacity="1" stroke="#FFFCF9" stroke-width="0"/>
<circle class="liquidFollower" cx="0" cy="50" r="0" fill="red" fill-opacity="1" stroke="#FFFCF9" stroke-width="0"/>
<circle class="dragger" cx="50" cy="305" r="100" fill="#62B6CB" fill-opacity="0" stroke="#FFFCF9" stroke-width="0"/>

 

If you play with those values (0.98, 0.97 and 0.35) you'll see how they are working in the code.

 

So the bigger the distance between them when the user drags, bigger the motion in the bottle fill.

 

The funny thing is that Chris is using the ThrowProps plugin, so He could have easily plugged the Velocity Tracker to it, but hey is working fantastic anyways, right? ;) 

 

Happy Tweening!!

Share this post


Link to post
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.