
Falling tools
Physics, Hover
NewFree
The header of a made-up greengrocer, in the rich style: under a red and cream striped awning the fruit falls into the wooden crates with real physics, apples, pears, oranges, lemons, cherry pairs and a watermelon, rolls and piles up; with the pointer or a finger you push it, grab it, throw it and carry it onto the brass scale, whose needle swings and settles on the weight.
A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The fruit stall</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/caveat@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stall" data-stall>
<!-- the header of a made-up greengrocer, Pippin Market: a striped awning with a scalloped fringe, wooden crates on
a counter, chalk prices on little slates and a brass grocer's scale. The fruit falls from under the awning into
the crates with real physics; push it with the pointer, grab it and throw it, or carry it onto the scale -->
<canvas class="stall__canvas" data-canvas aria-label="A fruit stall: apples, oranges, lemons, pears, cherries and a watermelon in wooden crates, with a brass scale. Drag the fruit to move it, put it on the scale to weigh it." role="img"></canvas>
<header class="stall__bar">
<span class="stall__brand">Pippin Market</span>
<span class="stall__hours">Open daily, seven to two</span>
</header>
<section class="stall__copy">
<h1 class="stall__title">Picked this <br><em>morning.</em></h1>
<p class="stall__lede">Boxes of seasonal fruit from the stall, at your door by noon.</p>
<a class="stall__button" href="#order"><span>Order a box</span></a>
</section>
<p class="stall__hint" data-hint>Drag the fruit onto the scale</p>
<p class="sr-only" aria-live="polite" data-weight-text></p>
<ul class="sr-only">
<li>Apples, 2.40 a kilo</li>
<li>Oranges, 1.90 a kilo</li>
<li>Pears and lemons, 3 for 1</li>
</ul>
</main>
<script src="https://cdn.jsdelivr.net/npm/matter-js@0.20.0/build/matter.min.js"></script>
<script src="script.js"></script>
</body>
</html>Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.
31 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The fruit stall” from Animorio and fit it into my siteThe wall, the poles, the counter, the inside of the crates and the scale column only change when the size changes: they are drawn once on a hidden canvas and copied with drawImage every frame. On top, in order: the back of the pan, the fruit, the boards across the crates with their slates, the pan rim with the dial and last the awning, so falling fruit appears from under the fringe.
Each fruit is a Matter.js circle; the cherries are two circles tied by a soft constraint, so they hang and turn like a real pair. Each crate is three static walls (floor and two sides), the scale pan a static shelf with two rims. The physics runs at a fixed step, a sixtieth of a second, with an accumulator: with variable steps Matter becomes unstable.
Each fruit is drawn in its body’s frame (position and angle), so stalk, leaf, calyx, stripes and pores turn with it and stay attached. The gradient that gives the volume is computed in screen space instead, with the light always top left: a rolling fruit changes face but not light. For the cherries, the point where the stalks meet is computed every frame above the middle of the pair, and the leaf grows from there.
Pressing on a fruit creates an elastic constraint between the grabbed point and the pointer: the fruit follows the finger a little late and, released, keeps its speed, so it gets thrown. Moving through the fruit without pressing gives every nearby fruit a small force in the pointer’s direction, stronger the closer it is.
Every frame the grams of the fruit resting on the pan are added up (an apple 180, an orange 200, a lemon 110, a cherry 8). The needle is a spring: its speed takes a share of the distance to the weight and loses some every step, so it swings and settles. The pan sinks a few pixels with the weight.
If nobody touches it for six seconds, every PACE seconds the stall makes a move: a fruit jumps up, or the top fruit is carried onto the scale along a curve, pulled by a moving constraint; with three fruits on the pan one goes back to its crate. The randomness has a fixed seed, so every round is the same.
| Name | File | Default | What it changes |
|---|---|---|---|
GRAVITY | script.js | 1.15 | Gravity: higher, the fruit falls and settles faster. |
BOUNCE | script.js | 0.32 | How much the fruit bounces. |
FRUIT | script.js | 36 | How many fruits on a computer; fewer than half on a phone. |
DROP | script.js | 70 | Milliseconds between one fruit and the next as they fall. |
PUSH | script.js | 1 | How hard the pointer pushes the fruit when passing through it (0 none). |
PACE | script.js | 3.2 | Seconds between the autopilot’s moves. |
SCALE_MAX | script.js | 2 | The kilos at the end of the scale’s dial. |
--awning, --wood, --brass… | style.css | rosso, legno, ottone | The colours in :root: the canvas reads them again at every resize. |
For the header of a greengrocer, a farmers’ market, an online fruit and veg shop or a box delivery service. It is a toy: the real prices also need to be in plain text.
Same physics and same drawing, adapted sizes: the words sit on top across the width, the crates and the scale below, and there is less than half the fruit. A finger grabs and throws; the canvas has touch-action none.
No falling or bouncing: the fruit is already in the crates, still (the physics runs once before the first frame), with two cherries on the pan and the needle already on the weight.
Matter.js 0.20.0, Fraunces (font variabile) 5.3.0, Caveat (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 14 KB; the libraries: Matter.js 25 KB.
Tested on 22 October 2026
Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.