Mouse Cursor Confetti (GSAP Physics2D)
Clicking anywhere on the page bursts 3–10 coloured dot particles from the cursor position. Each dot pops in, then scatters outward in a random direction under simulated gravity before fading away.
GSAPPhysics2DConfettiClickInteractive
Setup — External Scripts
GSAP CDN
html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>Physics2DPlugin CDN
html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/Physics2DPlugin.min.js"></script>Code
styles.css
css
body {
overflow: clip;
}
.dot {
position: absolute;
background-color: #D3DCCD;
width: 1rem;
height: 1rem;
border-radius: 50%;
will-change: transform, opacity;
pointer-events: none;
}script.js
javascript
gsap.registerPlugin(Physics2DPlugin);
document.addEventListener("click", (event) => {
const dotCount = gsap.utils.random(3, 10, 1);
const colors = ["#D3DCCD", "#F5FEEF", "#6C7E5F", "#818A7B", "#94A787"];
for (let i = 0; i < dotCount; i++) {
const dot = document.createElement("div");
dot.classList.add("dot");
document.body.appendChild(dot);
gsap.set(dot, {
backgroundColor: gsap.utils.random(colors),
top: event.clientY,
left: event.clientX,
scale: 0,
});
gsap.timeline({ onComplete: () => dot.remove() })
.to(dot, {
scale: gsap.utils.random(0.5, 1),
duration: 0.3,
ease: "power3.out",
})
.to(dot, {
duration: 2,
physics2D: {
velocity: gsap.utils.random(200, 650),
angle: gsap.utils.random(0, 360),
gravity: 500,
},
autoAlpha: 0,
ease: "none",
}, "<");
}
});Notes
- •Each dot is created as a fresh DOM element on click and removed via the timeline's `onComplete` callback — no pooling needed for this particle count.
- •`overflow: clip` on `body` prevents scrollbars appearing when dots fly near the edges; use a scoped wrapper element instead if you don't want to constrain the whole page.
- •The `"<"` position parameter starts the physics tween at the same time as the scale-in tween, so the dot moves and pops simultaneously.
- •Swap the `colors` array and dot size to match your brand — or replace the `.dot` div with an SVG or image element for custom shapes.