You Might Also Like
Physics2D Particle Burst — Free GSAP Physics Snippet
Physics2D Particle Burst · Animations · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Physics2D Particle Burst — Launch-Condition Animation, Not Keyframes

Every other tween in this library animates from a start value to an end value. This one doesn't: click the stage and 28 particles are given *launch conditions* — a speed, a direction, and gravity — and GSAP's Physics2DPlugin (free on the CDN since 3.13) integrates the resulting parabolic trajectories. No destination is ever specified; where each particle lands is an outcome, not an input. That inversion is what makes physics-based motion feel organic where eased tweens feel staged.
velocity + angle + gravity is the whole model
physics2D takes initial velocity (pixels/second), a launch angle (degrees, where 270 is straight up in screen coordinates), and a gravity acceleration. Each frame it advances position along the velocity vector while gravity bends it downward — projectile motion, integrated for you. Randomizing velocity (180–480) and angle (230–310, an upward cone) per particle produces the natural spread of a real burst: fast particles fly wide and high, slow ones flop shortly, all on true parabolas rather than eased arcs.
ease: 'none' is mandatory here
Easing curves remap time — which would distort the physics. With ease: 'none', simulation time runs linearly and the *acceleration itself* provides all the perceived easing: particles launch fast, hang weightless at apex, and accelerate into the fall. That's why physics motion needs no easing — gravity *is* the ease.
gsap.utils.random powers the variety
Size, color rotation, launch speed, direction, spin, and lifetime are all drawn from gsap.utils.random ranges — six randomized dimensions per particle. The string form rotation: '+=random(-180, 180)' shows GSAP's inline random syntax: a relative spin unique per particle without writing a loop variable. Uniform particles read as a rigid fountain; layered randomness reads as confetti.
Particles are disposable DOM, cleaned by their own tween
Each dot is a tiny absolutely-positioned div appended on click and removed in its own onComplete (via this.targets()[0]), so the DOM returns to baseline after every burst — no pooling, no leaks, no cap logic. At 28 particles per click with transform-and-opacity-only animation, even rapid clicking stays comfortably within compositor budget; past a few hundred simultaneous particles you'd graduate to canvas.
pointerdown, not click, for responsiveness
Bursts fire on pointerdown so the explosion lands at the instant of press — the 100–300ms a click waits for release makes celebratory feedback feel detached. Coordinates convert from client space to stage space via getBoundingClientRect, so the burst originates exactly under the pointer regardless of page scroll.
Where physics beats confetti libraries
Libraries like canvas-confetti own their canvas and their look. Physics2D applies the same math to *any tweenable target* — DOM nodes, SVG elements, WebGL objects — so branded shapes, emoji, or product icons can explode with identical physics, and every burst composes with the rest of your GSAP timeline system.
Customizing it
Narrow the angle cone for directional cannons, raise gravity for heavier debris, or swap dots for emoji spans. Related celebration and physics patterns: confetti button, confetti celebration card, gravity-and-collision in physics balls, and friction-based motion in physics props pucks.
Build with AI
Build, Understand, Optimize, and Extend It With AI
You don't have to puzzle out why this tween has no destination values on your own. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the physics2D object's velocity, angle, and gravity properties get integrated into a parabolic path each frame, and why ease: 'none' is mandatory rather than just a stylistic choice here. The same assistant can help optimize it, for example checking whether appending and removing 28 DOM particles per click stays cheap under rapid repeated clicking, or whether the random ranges for velocity, angle, and lifetime are actually producing the visual spread you want. It's also useful for extending the effect: ask it to swap the plain divs for emoji or SVG shapes, add a directional "cannon" mode with a narrower angle cone, or trigger a burst automatically on a milestone event instead of a click. Treat the code less like a finished artifact and more like a starting point for a conversation.
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:
Build a click-anywhere particle burst effect in plain HTML, CSS, and vanilla JavaScript using GSAP's core engine plus its Physics2DPlugin (load both from a CDN) — the motion must come from physics launch conditions, not from animating to fixed end coordinates.
Requirements:
- A full-viewport stage element that listens for pointerdown (not click) and computes the pointer's position relative to the stage using getBoundingClientRect so the burst originates exactly under the cursor.
- On each pointerdown, create around 28 small absolutely-positioned div elements, each with a randomized size and a color picked from a fixed palette array, and append them to the stage at the click position with gsap.set.
- Animate each particle with GSAP's physics2D property object specifying a randomized velocity (a wide range, e.g. 180 to 480), a randomized launch angle constrained to an upward-facing cone (not a full 360-degree spread), and a constant gravity value — do not specify any target x/y coordinates; the end position must be an emergent result of the physics integration.
- The tween's ease must be set to 'none' (linear time), since the gravity value itself is what should produce all the visual acceleration and deceleration — explain in a code comment why adding a separate easing curve would distort the simulated physics.
- Each particle should also spin by a random relative rotation amount and fade its opacity to 0 over its lifetime, and its onComplete callback must remove its own DOM element so nothing accumulates after repeated clicks.
- Vary at least five different properties per particle at random (size, color, velocity, angle, rotation amount, duration) so a burst reads as organic confetti rather than a uniform fountain.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
- 1Add the GSAP CDNsInclude gsap and Physics2DPlugin from the CDN panel.
- 2Paste HTML, CSS, and JSA dark stage renders with a crosshair cursor.
- 3Click anywhere28 particles burst upward from the pointer.
- 4Watch the arcsGravity bends every trajectory into a parabola.
- 5Click rapidlyEach burst cleans its own DOM on completion.
- 6Tune the physicsVelocity range, angle cone, and gravity are one object.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Normal tweens interpolate between known start and end values. physics2D takes launch conditions — velocity in px/sec, an angle in degrees, and gravity — and integrates the trajectory frame by frame; the end position is an outcome, never an input. That's why bursts look organic: each particle follows a genuine parabola instead of an eased path to a chosen point.
Easing remaps the tween's time, which would warp the simulation — gravity computed against distorted time stops looking like gravity. With linear time, the acceleration itself produces all perceived easing: fast launch, weightless hang at apex, accelerating fall. In physics animation, the forces are the easing curve.
Degrees in screen space: 0 points right, 90 points down (y grows downward in browsers), 270 points straight up. The demo's 230–310 range is an 80° cone centered on "up," so particles spray skyward with natural spread. Narrow the range for a cannon, use 0–360 for an omnidirectional explosion.
Not at this scale: each burst appends 28 tiny divs animated only via transform and opacity (compositor work), and every tween's onComplete removes its own element, so the DOM returns to baseline within two seconds of the last click. Hundreds of simultaneous particles remain fine; thousands is when a canvas approach earns its complexity.
Yes — Physics2D animates transforms on any target, so swap the div for a span containing 🎉, an inline SVG star, or an img of your logo; the identical launch math applies. That's the practical edge over confetti libraries, which own their canvas and particle look: here your branded elements are the physics objects.
Register the plugin at module scope and fire bursts from a pointerdown handler that appends particles to a stage ref — imperative DOM is correct here, since routing 28 short-lived particles through framework state would re-render per burst for nothing. Add a cleanup that kills active tweens on unmount so removals don't target dead nodes. The stage styles map directly to Tailwind.