webdevpuneet.com

Matter.js Ball Pit Hero Section — Free Interactive Physics Hero

Matter.js Ball Pit Hero Section · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

Requires
<section class="bp" id="bpHero">
  <div class="bp-copy">
    <span class="bp-kicker">New · v3.0 is here</span>
    <h1>Design tools that<br><em>bounce back</em></h1>
    <p>Move your cursor through the pit. Tap a ball to pop it, and it'll drop right back in.</p>
    <div class="bp-cta">
      <a href="#" class="bp-btn" id="bpShake">Shake it up</a>
      <a href="#" class="bp-btn ghost" id="bpGravity">Flip gravity</a>
    </div>
  </div>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Cursor collider
Static body with synced velocity.
Tap to pop
Query.point plus ring animation.
Area-based fill
Right ball count for any size.
Responsive rebuild
ResizeObserver, no squashed circles.
Readable overlay
pointer-events and text backdrops.
Pauses off-screen
IntersectionObserver toggles the runner.
Reduced motion
Starts settled, no rain-in.
Shake and gravity flip
Fun CTA-driven interactions.

About this UI Snippet

An Interactive Physics Hero with Matter.js — Cursor Pushing, Popping, Resizing and Performance

Screenshot of the Matter.js Ball Pit Hero Section snippet rendered live

Physics ball-pit heroes are a popular way to make a landing page feel playful. The hard parts aren't the physics — they're making it responsive, readable and cheap to run. This snippet handles all three.

Pushing balls with the cursor

The pointer is represented by an invisible static circle. Each frame it's moved to the pointer with Body.setPosition(cursor, pointer, true) — the third argument, updateVelocity, gives it a velocity equal to how far it moved. Without it balls are just shoved out of the way; with it, a fast flick sends them flying while a slow drift nudges them gently. Big jumps (the pointer entering or leaving) skip the velocity so balls aren't blasted.

Tap to pop

Query.point(balls, point) finds the ball under the tap. It's removed, a fading ring is drawn where it was, and a new ball drops back in a moment later from whichever edge gravity pulls from.

Filling any size

The number of balls is computed from the hero's area (about 45% coverage), with smaller balls on narrow screens, so it looks full on a phone and a wide monitor alike.

Resizing without squashing

Scaling a canvas with CSS stretches circles into ovals. Instead, a ResizeObserver (debounced) recreates the renderer at the new size, rebuilds the four walls and nudges any ball that ended up outside back in. Walls are extra-thick so fast balls can't tunnel through them.

Readable content on top

The headline and copy sit above the canvas with pointer-events: none so the cursor reaches the balls, while the CTA buttons re-enable pointer events. Text gets a strong shadow and a translucent backdrop so it stays legible over any colour.

Performance and accessibility

An IntersectionObserver sets runner.enabled = false when the hero leaves the viewport, so it costs nothing while you read the rest of the page. With prefers-reduced-motion, balls start settled at the bottom instead of raining in.

Step by step

How to Use

  1. 1
    Move through the pitYour cursor pushes the balls around.
  2. 2
    Pop a ballTap or click one; a new one drops in.
  3. 3
    Shake it upLaunch every ball into the air.
  4. 4
    Flip gravitySend the pile to the ceiling and back.
  5. 5
    Resize the windowThe pit rebuilds at the new size.

Real-world uses

Common Use Cases

SaaS landing hero sections
Open with a playful first impression, where visitors push balls with the cursor and tap one to pop it with a ring animation.
Release celebration heroes
Celebrate a release with colourful physics balls, with an area-based fill so the right number appears at any screen size.
Portfolio introductions
Show personality on the first screen, rebuilding on resize with a ResizeObserver so circles never appear squashed.
Event and brand-coloured pages
Use balls in event or brand colours, pausing when off-screen and respecting reduced-motion preferences to stay light on resources.
Playful 404 pages
Give lost visitors something fun, with Shake and flip gravity buttons providing more things to try.
Related: Matter.js Physics Playground
Spawn and drag shapes: Matter.js Physics Playground.
Related: Matter.js Soft-Body Jelly
Squishy instead of bouncy: Matter.js Soft-Body Jelly Blobs.

Got questions?

Frequently Asked Questions

Add an invisible static circle, and every frame move it with Body.setPosition(body, pointer, true); the updateVelocity flag sets its velocity to how far it moved, which makes collisions transfer the right amount of energy.

Don't stretch it with CSS. On resize (debounced with ResizeObserver), create a renderer at the new size, rebuild the walls, and move any bodies left outside back into bounds.

Yes. Position the content above the canvas with pointer-events: none so the cursor reaches the canvas, then set pointer-events: auto on buttons and links.

Use an IntersectionObserver on the hero and set runner.enabled to false when it leaves the viewport and true when it returns.

Matter.Query.point(bodies, {x, y}) returns the bodies containing that point.