
The time wheel
Pickers, 3D, Physics
NewFree
A studio compressor’s ratio set on a steel coil spring: the knob is an anodized collar fixed to the middle of the spring, and moving it squeezes the turns on one side and opens them on the other. Dragged fast it sends compression waves down the helix; thrown, the collar runs on a little and the spring brings it back.
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 coil spring slider</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/inter-tight@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the ratio of a studio compressor, set on a steel coil spring: the knob is an anodized collar fixed to the
middle turn of the spring, and the spring runs from it to two end caps. Moving the collar squeezes the turns on
one side and opens them on the other. The spring, the rod inside it, the collar and the caps are drawn by the
script on the canvas; the grip only carries the keyboard's ring -->
<div class="ratio" data-ratio>
<div class="ratio__head">
<span class="ratio__label" id="ratio-label">
<svg class="ratio__icon" viewBox="0 0 24 24" aria-hidden="true">
<path class="ratio__axes" d="M3.5 3.5v17h17"/>
<path class="ratio__unity" d="M3.5 20.5L20.5 3.5"/>
<path class="ratio__curve" data-curve d="M3.5 20.5L10 14L20.5 11"/>
</svg>
Ratio
</span>
<span class="ratio__value" aria-hidden="true"><span class="ratio__number" data-number>4.0</span><span class="ratio__unit">:1</span></span>
</div>
<div class="ratio__track" role="slider" tabindex="0" aria-labelledby="ratio-label" aria-orientation="horizontal" aria-valuemin="1" aria-valuemax="20" aria-valuenow="4.0" aria-valuetext="4.0 to 1" data-track data-autoclic>
<canvas class="ratio__coil" aria-hidden="true" data-canvas></canvas>
<span class="ratio__grip" aria-hidden="true" data-grip></span>
</div>
<!-- the two ends of the range, right under the collar's two last stops: the script writes them from RANGE -->
<div class="ratio__scale" aria-hidden="true" data-scale>
<span data-low></span>
<span data-high></span>
</div>
</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.
29 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 coil spring slider” from Animorio and fit it into my siteEvery half turn of wire has its place along the axis; between them a smooth curve gives the place of every point of the wire, and the point goes round the axis: height R·cos θ, depth R·sin θ. Shifting it sideways by its depth (YAW) shows the spring a little from the side, and a touch of perspective makes the near half of each turn slightly bigger than the far one. On every frame the spring is drawn again on a canvas, into an off-screen picture that is then laid down twice: as it is, and upside down and faded for the reflection.
The order makes the depth: the right cap, then the right side of the spring (the far halves, dark and thin, then the rod, then the near halves), the collar, the left side of the spring and last the left cap. The near halves have a black edge that cuts the far ones and the rod, a colour running from the light on top to dark and a cool glint underneath, and a line of light on the side facing the lamp: the more upright the turn, the brighter, so squeezed turns flash as a wave goes by.
The spring is a chain of small weights, one for each half turn, tied by springs (COIL): worked out in steps of 1/600 of a second at most, with a brake on each one’s speed and a stronger one on the differences between neighbours, which kills the fine ripples. When the hand carries the collar fast the nearby turns fall behind: they close up in front, open behind, and the wave runs to the cap and back.
Held, the collar goes where the hand goes; pressed far from it, it catches up on a quick spring. Let go, it keeps the hand’s speed over the last 90 milliseconds times FLING, and a spring (COLLAR) brings it back to its value: of the coil it feels only the waves, not the steady load, or the stretched side would pull it off its value. When everything is slow and near its place the thread’s friction stops it, and the loop stops drawing.
Two turns cannot go through each other: after every step, where two half turns are closer than half the wire they are pushed apart, forwards and backwards, and move on together. Past the end of the range the collar gives less and less, until its side is solid steel and it stops dead. Arrows, Shift and the Page keys move the ratio, Home and End go to the ends; the scale is logarithmic as on compressors (LOG_SCALE).
| Name | File | Default | What it changes |
|---|---|---|---|
START_AT | script.js | 4 | The ratio when the page opens. |
RANGE | script.js | [1, 20] | The lowest and the highest ratio. |
STEP | script.js | 0.1 | How much the ratio moves at a time. |
KEYS | script.js | [0.1, 1] | How far an arrow key moves the ratio, and with Shift or the Page keys. |
LOG_SCALE | script.js | true | The ratio grows faster towards the right, as on compressors; off, the scale is even. |
TURNS | script.js | 16 | The turns of the spring, half on each side of the collar. |
COIL | script.js | [9000, 0.24] | The wire’s springs: how stiff they are (the stiffer, the faster the waves run) and how much they are held back. |
COLLAR | script.js | [6, 3000, 0.16] | The collar: how heavy it is, how hard its value pulls it back and how much it is held back. |
FLING | script.js | 0.9 | How much of the hand’s speed the collar keeps when it is let go. |
For a compressor’s ratio or threshold, the stiffness of the suspension in a bike’s app, the tension of a strap, the firmness of an adjustable mattress: wherever a value means how hard something pushes back.
The slider takes the width of the screen minus a margin; the spring keeps all its turns, only the range gets shorter. On the spring’s strip a finger drags the collar without scrolling the page (touch-action: none), which scrolls as usual outside it. Pressed anywhere, the collar runs there, and under the finger it catches the light as it does under the mouse.
No winding when the page opens, no waves and no run-on: the spring takes the right shape at once for where the collar is, which follows the finger and jumps to the value chosen with the keys. The number is at its value already; the light on the collar changes without any movement.
GSAP 3.15.0, Inter Tight (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 12 KB; the libraries: GSAP 28 KB.
Tested on 6 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.