Click anywhere in the frame to launch coloured balls subject to gravity — they bounce off the walls, gradually lose their momentum and pile up on the floor. Each click adds a new one, indefinitely.
JSPhysicsInteractive
Updated
Click to add balls
Hover or click the scene to interact
This effect is free — the Hover category contains 48 effects total, including 5 free. Effect.Labs has 840 vanilla effects. Explore the category →
① Physics playground — visualising gravity for primary school students
WhenIn the Grallux school app, students tap the screen or click inside the zone to drop coloured balls and watch their trajectories and bounces.
WhyManipulating virtual objects under gravity makes the concept tangible and playful; each ball added shows they all fall at the same rate, illustrating gravitational equality.
SettingsNight-blue background to evoke a physics blackboard; standard ball size (30 px); random colours to distinguish each student's drops.
Live events● Live
314
Sign-ups today
73
Purchases
$3 180
Revenue
New events appear here
② Metrics dashboard — real-time new-event visualisation
WhenEach new conversion or sign-up automatically drops a ball into the zone at the bottom of the dashboard; the rhythm of falling balls conveys a sense of activity without reading a number.
WhyA peripheral animated indicator draws the eye without interrupting work; the physical behaviour (accumulation, bouncing) is more expressive than a plain incrementing counter.
SettingsSolid-colour balls (green) on a dark dashboard background; the data-scenes script simulates new arrivals every 1.6 s via dispatchEvent on the container.
Drevorn✓ Booking confirmed
See you on 24 December!
Confirmation sent to your inbox
③ Booking confirmation celebration — online accommodation app
WhenAfter a booking is confirmed, an "Add to calendar" button launches coloured balls as a background layer — each click on the CTA button drops a ball at the right position inside the gravity container.
WhyAn exuberant visual reaction at the confirmation moment creates a positive memory and reinforces the sense of achievement from completing the booking.
SettingsColoured balls overlaid on the confirmation message (high z-index on text); balls bounce in the background without hiding essential information.
How it works
The .fx-0381-root frame (250 px tall) contains the .gs381-container. On each click (or touchstart), the script creates a div.gs381-ball positioned where the cursor or finger touched the frame, with a small random initial velocity (vx between −2 and +2 px, vy between −4 and −1 px upward). Each ball's colour is chosen at random from a palette of five hues (violet, pink, indigo, cyan, green).
The requestAnimationFrame loop updates each ball on every frame with a step normalised to 60 fps: f = dt / 16.67. Gravity adds 0.5 × f to vy; friction multiplies both components by 0.99 × f. On floor bounce, vy is multiplied by −0.7 and vx by 0.8. Side bounce: vx reversed. An IntersectionObserver pauses the loop when the frame is off screen.
Accessibility
Touch: the touchstart event adds a ball at the finger's position, with preventDefault() to avoid page scrolling. The effect works fully on mobile.
Keyboard: the effect does not respond to keys. If accessible use is required, add an "Add a ball" <button> that simulates a click at the container's centre.
Reduced motion: under prefers-reduced-motion: reduce, the loop does not start. Clicks still create a visible ball at the click point, but no gravity or bouncing occur — the resulting state is readable and static.
Decorative role: the balls are purely visual. The label is readable, and its English equivalent is provided in html_en.
Browser compatibility
Pure DOM and CSS, no dependency. IntersectionObserver available since Chrome 51, Firefox 55, Safari 12.1. Physics via requestAnimationFrame normalised to elapsed time. Not verified on real Safari; expected full.
Chrome 51+✓ Full (measured)
Firefox 55+✓ Full (measured)
Safari 12.1+✓ Expected full (not measured)
Edge 79+✓ Full (measured)
Mobile iOS 12.2+✓ Full on touch (not measured)
Android Chrome 51+✓ Full on touch (not measured)
Without JavaScript, the frame appears empty with the label centred. Without IntersectionObserver, the loop also runs off screen.
The code
Copy the three blocks into your page. No dependencies.
Yes, by default. To cap the count, add at the start of the click handler: if (balls.length >= 30) balls.shift().el.remove();. This removes the oldest ball when the limit is reached.
Can balls be added from code, without a click?
Yes. Creating a ball is a simple function called with a position {x, y} inside the container. Extract it and call it on an external event: WebSocket message, timer, or API response.
Does the effect work in a frame smaller than 250 px?
Yes, down to about 80 px tall. Below that, the balls bounce very quickly between floor and ceiling and give a chaotic effect. Adjust height on both .fx-0381-root and .gs381-container.