GSAP Draggable Inertia — Free Momentum Drag & Snap Snippet

GSAP Draggable Inertia · Animations · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Real momentum
InertiaPlugin continues motion from release velocity.
Bounded stage
Drag and coast both stay inside #diStage.
Edge resistance
Soft push-back near the boundary while dragging.
Unified pointer handling
Mouse, touch, and pen all work identically.
Grab feedback
Scale and shadow shift on drag start and end.
No manual physics
No velocity tracking or animation loop to write.
touch-action: none
Prevents scroll hijacking the drag on mobile.
Single Draggable.create call
One declarative config drives the whole interaction.

About this UI Snippet

GSAP Draggable Inertia — Flick-and-Coast Dragging With Bounded Momentum

Screenshot of the GSAP Draggable Inertia snippet rendered live

The GSAP Draggable Inertia snippet is the difference between a drag interaction that feels mechanical and one that feels physical — release the token mid-flick and it keeps traveling in the direction and speed you threw it, decelerating naturally instead of stopping dead the instant your pointer lifts. It's built with GSAP's Draggable utility plus the InertiaPlugin, loaded from a CDN, and a single bounded stage element.

Draggable does the pointer work

Draggable.create('#diToken', { type: 'x,y', bounds: '#diStage', ... }) hands off all the pointer and touch tracking — mouse, touch, and pen input are normalized into one API, so the token drags smoothly across desktop and mobile without you writing a single pointermove listener. type: 'x,y' lets it move freely in both axes.

Inertia is the momentum

Setting inertia: true (with InertiaPlugin registered) is what turns a plain drag into a throw. When you release the token while it's still moving, GSAP calculates its velocity at release and continues the motion, decaying it smoothly to zero rather than an abrupt stop — the same feel as flicking a card across a table.

Bounds keep it honest

bounds: '#diStage' constrains both the drag and the inertial coast to the stage element, and edgeResistance: 0.65 adds resistance as the token nears the edge during an active drag, so it feels like it's pushing against a soft wall rather than hitting a hard stop. The coast phase respects the same bounds, so a hard flick toward the edge settles just inside it instead of overshooting.

Feedback on grab and release

onDragStart and onDragEnd callbacks scale the token up slightly and deepen its shadow while held, then relax it back — a small tactile cue that reinforces the drag without interfering with Draggable's own transform handling.

Customizing it

Swap type: 'x,y' for 'x' or 'y' to constrain to one axis, tune edgeResistance for a softer or firmer edge feel, or add onThrowComplete to react once the coast finishes. Pair it with a drag sort list or drag throw notes for a board of independently-flickable items.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain how InertiaPlugin derives release velocity from Draggable's pointer history to produce the coast-and-decelerate motion, and why bounds constrains both the active drag and the inertial phase rather than just the drag. The assistant can also help you extend it — ask for multiple independently-throwable tokens with collision avoidance, a snap-to-grid behavior once the coast finishes, or a version that swaps InertiaPlugin for a hand-rolled velocity tracker if licensing is a concern for your project. Treat the code as a starting point to interrogate, not a black box to copy blindly.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "draggable inertia" interaction in plain HTML, CSS, and JavaScript using GSAP with its Draggable and InertiaPlugin plugins (load all three from a CDN).

Requirements:
- A bounded stage container and a single draggable token inside it, styled with a gradient background and rounded corners.
- Use Draggable.create with type: 'x,y', bounds set to the stage element (not the viewport), inertia: true, and a moderate edgeResistance so the token resists near the stage edges during an active drag.
- On release, the token must continue moving in the direction and at a speed derived from the drag's release velocity, decelerating smoothly to a stop rather than stopping instantly where the pointer lifted — this is the core inertia behavior, do not fake it with a manual CSS transition.
- The inertial coast must still respect the stage bounds, so a hard flick toward an edge settles just inside the boundary instead of exiting the stage.
- Add onDragStart and onDragEnd callbacks that give the token a subtle scale-up and shadow change while held, reverting on release, without interfering with Draggable's own transform updates.
- Set touch-action: none on the token so touch drags do not trigger page scrolling on mobile.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Add the GSAP CDNsInclude gsap, Draggable, and InertiaPlugin from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSA bounded stage with one draggable token renders.
  3. 3
    Drag the tokenIt follows the pointer and resists near the edges.
  4. 4
    Flick and releaseIt keeps coasting with momentum, then eases to a stop.
  5. 5
    Try a slow drag and releaseWith little velocity, it stops close to where you let go.
  6. 6
    Adjust bounds or resistanceChange #diStage or edgeResistance to retune the feel.

Real-world uses

Common Use Cases

Sortable boards
Pair momentum with a drag sort list.
Sticky note walls
Similar feel to drag throw notes.
Onboarding demos
Show a flingable token beside bento grid tiles.
Kanban cards
Add throwable motion to a kanban board card.
Game pieces
Reuse the physics for casual canvas-adjacent games.
Widget repositioning
Let users fling a floating panel into a corner.

Got questions?

Frequently Asked Questions

Plain Draggable stops the element exactly where the pointer releases it. InertiaPlugin calculates the element's velocity at the moment of release and continues its motion, decelerating it smoothly to zero — that's what produces the throw-and-coast feel instead of an abrupt stop.

InertiaPlugin is a Club GreenSock bonus plugin. Recent versions of the public gsap npm/CDN package have bundled it for no-signup use in many contexts, but licensing terms can change and commercial use may require a Club GreenSock membership depending on your use case — check GreenSock's current licensing page before shipping this in a commercial product.

Yes. bounds: '#diStage' constrains both the active drag and the inertial coast, so a hard flick toward an edge decelerates and settles just inside the boundary rather than flying out of the stage.

Yes. Draggable normalizes mouse, touch, and pen input into one API, and touch-action: none on the token stops the browser from interpreting the drag as a page scroll, so flicks register cleanly on mobile.

Render the stage and token, then in a mount effect register Draggable and InertiaPlugin and call Draggable.create scoped to the container. Store the returned Draggable instance and call .kill() in the cleanup function to avoid duplicate instances on re-render or unmount.