Demo: Draggable & ThrowPropsPlugin by GreenSock

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


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 ]

Drag and throw me
Drag and throw me too

  • Options

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


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.

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.


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

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


  • Touch enabled - works great on tablets, phones, and desktop browsers.
  • Even works in IE8! - all major browsers are supported.
  • Incredibly smooth, optimized performance - GPU acceleration is used whenever possible and animation looks great even on mobile devices. Compared to other options, Draggable just feels far more natural and fluid, particularly when imposing bounds.
  • Momentum-based animation with deceleration - if you have ThrowPropsPlugin loaded, you can simply set throwProps:true in the config object and it'll automatically apply natural, momentum-based movement after the mouse is released (or the touch ends), causing the object to glide gracefully to a stop. You can even control the amount of resistance, maximum or minimum duration, etc.
  • Impose bounds - tell a draggable element to stay within the bounds of another DOM element (like a container) as in bounds:document.getElementById("container") or define bounds absolutely like bounds:{top:100, left:0, width:1000, height:800} or you can define specific maximum and minimum values like bounds:{minX:10, maxX:300, minY:50, maxY:500} or bounds:{minRotation:0, maxRotation:270}. Plus you can apply edge resistance instead of having objects suddenly stop when they encounter the edge.
  • Sense overlaps with hitTest() - see if one element is overlapping another and even set a tolerance threshold (like at least 20 pixels or 25% of either element's total surface area) using the super-flexible Draggable.hitTest() method. Feed it a mouse event and it'll tell you if the mouse is over the element. See for a simple example.
  • Define a trigger element - maybe you want only a certain area to trigger the dragging (like the top bar of a window) - simply define that child element as the trigger, like trigger:"#topBar".
  • Drag position, rotation, or scroll - lots of drag types to choose from: "x,y" | "top,left" | "rotation" | "scroll" | "x" | "y" | "top" | "left" | "scrollTop" | "scrollLeft"
  • Limit movement to horizontal or vertical - when lockAxis is true, dragging more than 2 pixels in either direction (horizontally or vertically) will lock movement into that axis so that the element can only be dragged that direction (horizontally or vertically, whichever had the most initial movement). No diagonal movement will be allowed. Or you can set the type to "top" or "y" or "scrollTop" to only allow vertical movement, or set type to "x", "left", or "scrollLeft" to only allow horizontal movement.
  • Rotation honors transform origin - by default, spinnable elements will rotate around their center, but you can set transformOrigin to something else to make the pivot point be elsewhere. For example, if you call TweenLite.set(yourElement, {transformOrigin:"top left"}) before dragging, it will rotate around its top left corner. Or use % or px. Whatever is set in the element's css will be honored.
  • Rich callback system and event dispatching - use any of the following callbacks: onPress, onDragStart, onDrag, onDragEnd, onRelease, onThrowUpdate, onThrowComplete and onClick along with their associated params or scope associates (like onDragStartParams and onDragStartScope). Inside the callbacks, "this" refers to the Draggable instance, so you can easily access its "target" or bounds, etc. If you prefer event listeners instead, Draggable dispatches events too so you can do things like yourDraggable.addEventListener("dragend", yourFunc);
  • Sense clicks when the element moves less than 3 pixels - a common challenge is distinguishing between when a user is trying to click/tap an object or drag it, so if the mouse/touch moves less than 3 pixels from its starting position, it will be interpreted as a "click" and the onClick callback will be called (and a "click" event dispatched) without moving the element.

Where can I get it?

Draggable is included in the public downloads at and in GreenSock's github repository. Just go to and click the "get GSAP" button (you'll need GSAP's TweenLite and CSSPlugin too because Draggable uses those under the hood). Draggable is what handles all of the actual dragging and user interaction and it can be used without ThrowPropsPlugin if you don't need the momentum-based animation. It's a very useful tool on its own. However, to get the slick animation after the mouse is released (or touch ends), you'll need to load ThrowPropsPlugin which is a membership benefit of Club GreenSock ("Shockingly Green" and "Business Green" levels). Joining Club GreenSock gets you a bunch of other bonus plugins and tools as well, so check out to get details and sign up today. The support of club members has been critical to the success of GreenSock - it's what makes building these tools possible.

Sign up today


  1. Are there any dependencies on things like jQuery? answer...
    The only dependency is on GreenSock's very own TweenLite and CSSPlugin (which are also inside TweenMax). There are no dependencies on jQuery or any other libraries, although they work great together.
  2. Can I post a comment or offer feedback somewhere? What if I run into trouble or have a question? answer...
    We'd love to hear from you. Post a comment on the blog page announcing this demo at If you have a question, please use our forums at
  3. Is this behavior only for DOM elements? Can I get it in a canvas-based app answer...
    Draggable is just for DOM elements, yes, but the real magic behind all the fluid motion and snapping is ThrowPropsPlugin, and that can be used to tween any property of any object, not just DOM elements. So yes, you can absolutely get this kind of motion in other contexts but you'd need to wire up the actual dragging logic yourself and then fire off a ThrowPropsPlugin tween when the user releases their mouse/touch. ThrowPropsPlugin can even track the velocity of any property for you too (even function-based getters/setters!), so it's quite a powerful tool.
  4. What browsers are supported? answer...
    Pretty much every major browser is supported including Chrome, Firefox, Opera, iOS, Android and IE even back to version 8! We're not aware of any significant browsers that don't work, but please let us know if you stumble across an issue.
  5. How big are the JavaScript files? answer...
    Here are the rough sizes, assuming they're gzipped and minified:
    • Draggable: 6kb
    • ThrowPropsPlugin: 3kb
    • TweenLite: 7kb
    • CSSPlugin: 12kb
  6. Are CSS3 transitions or animations used for the motion? answer...
    Nope. CSS3 transitions and animations have some significant limitations that make them ill-suited for the type of motion that these tools require, so highly optimized JavaScript is used instead. In order to tap into GPU compositing, 3D transforms are used when possible (in browsers that support them) and updates are made using requestAnimationFrame (when available) for maximum efficiency. See for yourself in Chrome Dev Tools - you should see very snappy performance in the timeline. Many other tools like jQuery UI use top/left properties for positioning which don't generally perform as well. These tools have been fully "GreenSocked" so performance is smoking fast, just like the core tweening engine.
  7. Do I have to purchase a license to use this code? Can I use it in commercial projects? answer...
    Everything demonstrated on this page is covered by GreenSock's standard "no charge" license which is quite permissive. ThrowPropsPlugin is a membership benefit of Club GreenSock, so you need to sign up to get that. Draggable, however, is included in all the standard downloads and you don't need a membership to get that; Draggable can be used apart from ThrowPropsPlugin as long as you don't need the momentum-based motion. GreenSock's standard license allows you to use GreenSock tools for free in everything except a very specific type of commercial project (if you collect a fee from multiple customers for the app/product/game/site that uses GreenSock tools) which makes it extremely accessible and business-friendly while providing a small funding mechanism to sustain ongoing support, enhancement, and innovation. The web is littered with abandoned “open source” projects, but GreenSock has a years-long track record of commitment to the platform. This unique licensing model is a key component of its sustainability. If you charge multiple customers a usage/access/license fee, please simply sign up for a “Business Green” Club GreenSock membership which comes with a special commercial license granting you permission to do so. Click here for details. Joining the club also gets you members-only bonus plugins, utilities, update notifications, and more.
  8. Where can I find the official docs? answer...
    Find all the docs for GreenSock at Draggable is in the "utils" package, and ThrowPropsPlugin is in the "plugins" package.
  • Twitter
  • Facebook
  • Digg
  • StumbleUpon
  • Yahoo! Buzz
  • Google Bookmarks
  • RSS
  • LinkedIn
  • Reddit