
Falling tools
Physics, Hover
NewFree
An oil bottle that tips while you hold: the oil inside always stays level, runs out of the neck once it reaches it and falls in a stream the pointer aims. The bowl fills with rings where the stream lands; whatever misses it ends on the board.
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>Hold and pour</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/young-serif@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="bar">
<a class="brand" href="#">Casale Verde</a>
<nav class="bar__nav" aria-label="Sections">
<a href="#">The oil</a>
<a href="#">Groves</a>
<a href="#">Shop</a>
</nav>
</header>
<main class="page">
<section class="copy">
<p class="kicker">Cold-pressed, first harvest</p>
<h1 class="title">Pour it slowly. We pressed it slowly.</h1>
<p class="note">Hold the table to tip the bottle, and move to aim. Fill the bowl without spilling a drop.</p>
<button class="pour" type="button" data-pour data-autoclic>Pour a measure</button>
</section>
<!-- the table: a bottle that tips while you hold, a stream that falls, a bowl that fills; all drawn on the canvas -->
<section class="stage" data-stage aria-label="Pouring olive oil into a bowl">
<canvas class="stage__canvas" data-canvas aria-hidden="true"></canvas>
<p class="served" data-served aria-live="polite"></p>
<p class="hint" data-hint>Hold to pour</p>
</section>
</main>
<!-- the round cursor that says what to do, stretched by its speed -->
<div class="cursor" data-cursor aria-hidden="true">
<span class="cursor__disc" data-disc></span>
<span class="cursor__text" data-cursor-text>Hold &<br>pour</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.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.
28 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 “Hold and pour” from Animorio and fit it into my siteThe bottle is a polygon in its own space. Every frame the script turns and moves it to where it is and looks, by bisection, for the horizontal line that leaves exactly the oil there is below it: the area is measured by cutting the polygon with that line. The piece of polygon below the line is the oil, and it is drawn in the page’s own space, so it stays level whatever the bottle does. When the bottle speeds up or slows down the surface tilts a little and swings back, like a spring.
The neck pours when its lower lip is under the level, at a rate that grows like the square root of how far under it is, like water from a hole (Torricelli), times FLOW. So a full bottle pours early and a nearly empty one must be tipped further. While you hold, the bottle reaches ANGLE degrees in TILT seconds on a soft curve, and loses whatever runs out.
Ninety drops a second are born at the neck, in its direction, at a speed that grows with the flow plus a little of the bottle’s own; GRAVITY pulls them down and the air slows them sideways. They are drawn as a ribbon through all of them in the order they left, in three passes: ink, gold and a thread of light. Its width comes from the flow (THICK at full flow) and falls with speed, because the same oil goes through a narrower section. A new ribbon only starts after a real pause, so the stream never splits in two.
The bowl is seen a little from above: rim and foot are ellipses. The oil is an ellipse that rises from the bottom and widens; since the bowl widens upwards, the level for a share of oil comes from a cube root, as for a cone’s frustum. Where the drops land a ring is born every RINGS seconds, spreading and fading; the near side of the bowl is drawn after the stream and covers its end. SHARE of the bottle fills it; full, if you keep pouring, it overflows onto the board.
A disc follows the pointer with a lag, a tenth of the distance every frame. Its speed, smoothed, stretches it the way it moves and narrows it across by a tenth (STRETCH, four times as much while you hold); pressing shrinks it to half and the words disappear.
Bottle, bowl and board are filled white and hatched with patterns of wavy lines (the canvas’s createPattern), three versions per pattern; every outline also has a different wobble in each version. The versions take turns BOIL times a second.
| Name | File | Default | What it changes |
|---|---|---|---|
TILT | script.js | 1.1 | The seconds the bottle takes to tip right over while you hold. |
ANGLE | script.js | 112 | How far it tips, in degrees from upright. |
FLOW | script.js | 1 | How fast the oil runs out of the neck. |
GRAVITY | script.js | 2600 | How hard the stream is pulled down, in pixels a second squared. |
THICK | script.js | 10 | The stream’s width at full flow, in pixels. |
MEASURE | script.js | 1.5 | The seconds the button keeps the bottle tipped. |
RINGS | script.js | 0.12 | The seconds between two rings where the stream meets the oil. |
FOLLOW | script.js | 0.1 | How quickly the bottle follows the pointer, each sixtieth of a second (0 to 1). |
SHARE | script.js | 0.22 | How much of the bottle it takes to fill the bowl. |
BOIL | script.js | 8 | How many times a second the engraving changes drawing. |
STRETCH | script.js | 0.01 | How much the round cursor stretches with its speed. |
For a product that pours: oil, wine, coffee, syrups, paints. Holding turns the wait into a game: it suits the opening of a product page, or the place of a loader.
You hold the table with a finger and move it to aim; at the bottom a label says «Hold to pour». The table lets the page scroll vertically (touch-action: pan-y): if the finger goes up or down the page scrolls and the bottle stands up again.
The bottle still tips and pours, because it answers a gesture, but it does not sway, the oil’s surface does not swing, no rings spread on the oil and the hatching does not change drawing; the cursor does not stretch.
GSAP 3.15.0, Young Serif 5.3.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 12 KB; the libraries: GSAP 28 KB.
Tested on 21 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.