ThrowPropsPlugin

ThrowPropsPlugin allows you to smoothly glide any property to a stop, honoring an initial velocity as well as applying optional restrictions on the end value. You can define a specific end value or allow it to be chosen automatically based on the initial velocity and ease or you can define a max/min range or even an array of snap-to values that act as notches. ThrowPropsPlugin even integrates VelocityTracker so that you can have it "watch" certain properties to keep track of their velocities for you and then use them automatically when you do a throwProps tween. This is perfect for flick-scrolling or animating things as though they are being thrown (where momentum factors into the tween).

For example, let's say a user clicks and drags a ball and and then when released, the ball should continue flying at the same velocity as it was just moving (so that it appears seamless), and then glide to a rest. You can't do a normal tween because you don't know exactly where it should land or how long the tween should last (faster initial velocity would usually mean a longer duration). You'd like it to decelerate based on whatever ease you define in your tween (always use some sort of easeOut, like Power1.easeOut, Strong.easeOut, etc.).

Maybe you want the final resting value to always land within a particular range so that the ball doesn't fly off the edge of the screen. But you don't want it to suddenly jerk to a stop when it hits the edge of the screen either; instead, you want it to ease gently into place even if that means going past the landing spot briefly and easing back (if the initial velocity is fast enough to require that). The whole point is to make it look smooth.

When you pair GreenSock's Draggable with ThrowPropsPlugin, you get the ultimate tag-team for making a DOM element draggable, spinnable, tossable, and even flick-scrollable! You can impose bounds, have things glide to a stop in a silky-smooth way, and do it all with as little as one line of code. No kidding. Works great on touch devices too. Below you'll find 3 examples of what Draggable can do when it's got some ThrowPropsPlugin love under the hood. Check out the code samples too (they auto-update as you change options).

Throw

By default, Draggable uses type:"x,y" meaning it'll use css transforms for positional movement (hardware accelerated when possible). Activate the some of the snapping options below and watch how nicely things glide into place exactly on the grid or snap into place as you drag. Notice the edge resistance as you try to drag past the edges; everything is configurable. [ View this on codepen.io ]


Drag and throw me
Drag and throw me too

  • Options

Code
Draggable.create(".box", {
    type: "x,y",
    edgeResistance: 0.65,
    bounds: "#container",
    throwProps: true
});

Spin

Set Draggable's type to "rotation" and watch what happens (grab the knob below and spin it). ThrowPropsPlugin tracks the velocity of the rotation and continues when you release your mouse (or finger for touch devices), gliding to a stop naturally. Activate the "Snap to 90-degree increments" option to see how easy it is to make it always land at certain rotational values without any jerking or awkwardness.



Code
Draggable.create("#knob", {type: "rotation", throwProps: true});

Scroll (Drag & Flick)

Draggable can even be used to control the scrollTop and/or scrollLeft properties of an element, complete with overscrolling, snap-back, momentum continuation, and edge resistance. It's as simple as changing the type to "scroll". And Draggable doesn't use artificial scrollbars like some other tools - it uses native scrolling with the standard OS/browser scrollbar UI. Play with the demo below and see for yourself.


Drag me to scroll me

Click and drag this content and then let go as you're dragging to throw it. Notice how it smoothly glides to a rest, respecting the initial velocity and even permitting overscolling with bounce-back without forcing fake/simulated scrollbars. It's actually using the scrollTop or scrollLeft of the container, and then if/when it exceeds the bounds, it'll apply a translate3d() transform for hardware-accelerated performance, and it'll even fall back to using padding when 3D transforms aren't available. Yes, it even works in IE8!

How does it work?

When you create the Draggable with type:"scroll" (or "scrollTop" or "scrollLeft"), it will create a <div> and wrap it around the native content of the target element so that it can move things appropriately. So that wrapper div ends up being the only child of the element. Then, as you drag, it updates the scrollTop/scrollLeft of the element until you exceed the bounds at which time it'll either add a translate3d() CSS transform (if supported) to that wrapper <div> or fall back to using padding for older browsers.

This gives you the best of both worlds - it delivers native scrolling with normal scrollbar UI that's built into the OS/browser, plus outstanding performance on mobile devices due to the translate3d() sweetness on overscroll, and compatibility even with IE8, all in a 3.4k gzipped footprint (not including TweenLite or CSSPlugin which are required).

Oh, and don't forget the kinetic-based flick scrolling that's enabled when you load ThrowPropsPlugin and set throwProps:true in the config object. When you drag past the normal scrolling limits, the edgeResistance kicks in (you control how much). It just "feels" natural and fluid, much more so than most other options out there.

Did we mention Draggable works great with touch events too? And if the user flick-scrolls and then while it's animating, they use their mouse wheel or grab the scrollbar to take control themselves, Draggable automatically releases control and stops the animation. Don't worry your pretty little head.

Usage

Setup is a breeze. One line is all you need:

Draggable.create("#container", {type:"scroll", throwProps:true, edgeResistance:0.35});

That's it!

Of course you can tweak the configuration however you please. Want to only scroll vertically? Use type:"scrollTop". Or for horizontal scrolling, use type:"scrollLeft". When you use simply type:"scroll", it allows scrolling in either direction.

Change the edgeResistance to 1 if you don't want the user to be able to drag past the edge.

Note that ThrowPropsPlugin is a membership benefit of Club GreenSock ("Shockingly Green" and "Business Green" levels), but the Draggable works fine without that - you just won't get the kinetic-based motion. You can still drag things.

Not just for scrolling

As you can see from the examples above, Draggable is multi-talented. Change the type to "x,y" to make the entire object draggable around the screen (literally moving it, not scrolling). Or type:"top,left" does the same thing, but uses the "top" and "left" css properties instead of translateX() and translateY() CSS transforms. Or if you want to be able to drag-spin an object, use type:"rotation". In fact, it'll even honor the transform-origin of the element.


  • Options

Code
Draggable.create("#scroller", {type:"scroll", edgeResistance:0.5, throwProps:true}); 

Get GSAP

Version: 1.20.3 updated 2017-10-02

  • Download zip

  • github

Core

    Extras

      Plugins

        By using GreenSock code, you agree to the terms of use.

        For an all-access pass to premium content

        Join Club GreenSock