
The needle gauge
Counters, Physics, SVG
NewFree
A table’s length set with a tape measure: pull the brass hook and the printed steel tape slides out of the yellow case with its numbers travelling, while the table drawn above grows with its end always over the hook. Let go, it settles on a whole centimetre; with the lock off the tape whips back in, the numbers blur and the hook clacks against the mouth.
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 tape measure slider</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the tape measure slider: the length of a table, set with a retractable steel tape measure. The table is drawn
above it with its length on a dimension line, and its right end always stands over the brass hook. Pull the
hook and the printed tape slides out of the yellow case, the numbers travel past the mouth and the table grows;
let go and it settles on a whole centimetre. With the red lock slider off, the tape whips back into the case
and the hook clacks against the mouth. The chips glide it to a length for four, six or eight people -->
<div class="tm" data-tm data-lock="on">
<div class="tm__rig" data-rig>
<!-- the drawing: the table, its dimension line with the length, and the tape measure; the script draws it to
the width it gets -->
<svg class="tm__art" aria-hidden="true" focusable="false" data-art></svg>
<!-- the hook is the slider's thumb: an empty handle that the script keeps over the brass hook -->
<div class="tm__hook" role="slider" tabindex="0" aria-label="Table length" aria-orientation="horizontal"
aria-valuemin="80" aria-valuemax="240" aria-valuenow="160" aria-valuetext="160 centimetres" data-hook></div>
</div>
<div class="tm__controls">
<div class="tm__lockrow">
<button class="tm__lock" type="button" aria-pressed="true" aria-describedby="tm-hint" data-lock-btn>
<svg class="tm__padlock" viewBox="0 0 20 20" aria-hidden="true">
<path class="tm__shackle" d="M6.2 9V6.6a3.8 3.8 0 0 1 7.6 0V9"/>
<rect class="tm__body" x="4" y="8.6" width="12" height="9" rx="2.2"/>
<path class="tm__keyhole" d="M10 11.6v2.6"/>
</svg>
<span>Lock</span>
<span class="tm__badge" aria-hidden="true" data-badge></span>
</button>
<span class="tm__hint" id="tm-hint" data-hint></span>
</div>
<!-- the chips: data-preset is the length each one sets, and the script writes it under the name -->
<div class="tm__presets" role="group" aria-label="Table sizes">
<button class="tm__chip" type="button" data-preset="120">Seats 4<span class="tm__cm" data-cm></span></button>
<button class="tm__chip" type="button" data-preset="180" data-autoclic>Seats 6<span class="tm__cm" data-cm></span></button>
<button class="tm__chip" type="button" data-preset="230">Seats 8<span class="tm__cm" data-cm></span></button>
</div>
</div>
<p class="sr" aria-live="polite" data-live></p>
</div>
</main>
<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.
47 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 tape measure slider” from Animorio and fit it into my siteThe scale comes from the width: k pixels per centimetre, so the longest length (MAX) fits in the drawing. The tape’s mouth sits MIN·k from the table’s left end, so with the hook against the mouth the table is MIN long, and its right end is always exactly over the hook. The table, the dimension and the dashed line are drawn again from the same length; the case gets smaller when there is little room left of the mouth.
There is one state: how much steel is out of the mouth. The tape runs straight inside the case and then, when it is pulled up or down, follows the curve of a shelf loaded at its tip, y = dy·(3t² − t³)/2, taken at 25 points with their slope. The strip is the polygon of its two edges moved along the normals; the cupping is made of strokes along parallel lines, not a gradient, so the light follows the bend. The print is measured from the tip: u pixels from the hook the tape reads MIN + u/k, and every tick and number is laid on the curve at its distance, turned with it. So that bending does not change the length, the tip sits at x = ℓ − 0.6·dy²/ℓ.
Outside there are two or three pixels per centimetre: too few for millimetres. The window on the case shows the same reading as the mouth, magnified to 30 units per centimetre, with millimetre, half centimetre and centimetre ticks, the numbers beside their tick so the red hairline never cuts them and the tens in red. When the tape runs, a horizontal-only feGaussianBlur, as big as the speed, blurs the print outside and inside the window.
The hook sits on its rivets in two slots: pulled by the hand it moves PLAY pixels forward, pushed it goes back, and when the tape moves on its own it lags behind by inertia; at the ends of the slot it bounces. It turns a little on the rivets on an angular spring (SWING) pushed by the tape’s acceleration. The bend is a damped spring (BEND): while dragging it follows the finger, held to a few pixels on a short tape, and let go it quivers until it is straight.
With the lock off, on release the spring inside the case pulls the tape with a steady force (PULL): it speeds up until the hook slams into the mouth, bounces with BOUNCE of its speed, is pushed back on its rivets, and the case jolts and rocks on two springs. The buttons and the keys take the tape to its length on the GLIDE and KEYS springs, a release with the lock on settles on the whole centimetre on SNAP. It all steps on GSAP’s ticker, with the step held to 1/30 of a second, and nothing is drawn again when nothing moves.
| Name | File | Default | What it changes |
|---|---|---|---|
MIN | script.js | 80 | The shortest length, in centimetres: the hook against the mouth. |
MAX | script.js | 240 | The longest length: the hook at the end of the drawing. It also sets the scale, and so how tall the table is. |
START | script.js | 160 | The length when the page opens. |
STEP | script.js | 1 | How many centimetres an arrow key moves the tape. |
BIG_STEP | script.js | 10 | How many centimetres Shift with an arrow and the Page keys move it. |
GLIDE | script.js | [72, 8.6] | The spring of the Seats buttons: stiffness and damping (less damping, more overshoot). |
KEYS | script.js | [420, 36] | The quicker spring of the keys: stiffness and damping. |
SNAP | script.js | [900, 54] | The small spring that takes the tape to the whole centimetre on release. |
PULL | script.js | 4200 | How hard the case’s spring pulls the tape in with the lock off, in pixels per second squared. |
BOUNCE | script.js | 0.14 | How much of its speed the hook keeps when it bounces off the mouth. |
BEND | script.js | [250, 6.5] | The spring of the steel when it is bent and let go: stiffness and damping. |
PLAY | script.js | 1.6 | How far the hook slides on its rivets, in pixels. |
SWING | script.js | [380, 14] | The hook’s little swing on its rivets: stiffness and damping. |
SAY_ON | script.js | Stays where you leave it | The line under Lock when the lock is on. |
SAY_OFF | script.js | Springs back when let go | The line under Lock when the lock is off. |
data-preset | index.html | 120, 180, 230 | The length each button sets, in centimetres; the script writes it under the name. |
For the length of a table, a desk or a bookcase in a furniture configurator, the width of a curtain or a rug, a cut of fabric or cable: wherever the value is a length in centimetres and it helps to see the thing that changes.
The drawing takes the width of the screen minus a margin: the centimetre scale shrinks so the whole range fits, the table with it, and the case keeps its size. The tape keeps its ticks every 5 and every 10 centimetres and a number every 20; the millimetres stay in the window. A finger drags the hook without scrolling the page only on the hook itself (touch-action: none); the Lock button and the three buttons go on two rows.
No bend, no swing or slide of the hook, no blur and no jolt of the case: without the lock, on release the tape goes back in a third of a second with a plain ease; the buttons and the keys take it to its length in 0.28 seconds, and when the page opens it is already at its length. The preview, instead of pulling the hook, goes from one button to the next.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 18 KB; the libraries: GSAP 28 KB.
Tested on 7 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.