
The needle gauge
Counters, Physics, SVG
NewFree
A tea timer set by turning the knob round the ring, as on a kitchen timer: the arc follows it on a spring and the figures roll; started, the arc runs round the whole ring and empties as the time goes by, and when it is up the ring rings, shaking like a bell and throwing out rays.
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 ring timer</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/urbanist@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the ring timer: the time is set by turning the knob round the ring (or with a kind of tea), runs down as the
arc shrinks back, and rings when it is up -->
<div class="timer" data-timer data-autoclic>
<div class="dial" data-dial>
<svg class="dial__art" viewBox="0 0 320 320" aria-hidden="true" data-art>
<circle class="dial__track" cx="160" cy="160" r="130"/>
<g class="dial__ticks" data-ticks></g>
<path class="dial__arc" data-arc/>
<g class="dial__rays" data-rays></g>
</svg>
<div class="dial__knob" role="slider" tabindex="0" aria-label="Time" aria-valuemin="5" aria-valuemax="300" data-knob></div>
<div class="dial__face">
<span class="dial__time" data-time></span>
<span class="dial__label" data-label></span>
</div>
</div>
<div class="teas" role="group" aria-label="Kinds of tea" data-teas></div>
<div class="controls">
<button class="ctl ctl--ghost" type="button" aria-label="Start over" data-reset>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5.5 9A7.5 7.5 0 1 1 4.6 14M5 4.5V9h4.5"/></svg>
</button>
<button class="ctl ctl--main" type="button" aria-label="Start" data-go>
<svg viewBox="0 0 24 24" aria-hidden="true"><polygon data-shape/><polygon data-shape/></svg>
</button>
</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.
18 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 ring timer” from Animorio and fit it into my siteThe arc is an SVG path from the top, with the large-arc-flag once it is past half (and two half arcs when it is whole); its length is a share of the ring that a spring (SPRING) brings to the right value, worked out on GSAP’s ticker in steps of 4 milliseconds. While setting, the share is the time on the dial’s scale (MAX seconds a whole turn); started, it is the share of the time left, so on starting the arc runs on to the whole ring. The knob sits at the end of the arc, placed by GSAP (x and y), and nods with scale at every step.
The angle from the middle to the pointer becomes seconds, rounded to STEP. Crossing the top the angle would jump by a whole turn: the difference from the angle before is corrected by a turn and the hand is held at the ends (no jump from 5:00 to 0:05).
Every figure has its own window (overflow hidden): when it changes, the new one comes from above if the time goes down, from below if it goes up, and the old one leaves the other way; a roll still going ends at once, so fast turns never pile up.
Play and pause are two four-sided shapes (the two halves of the triangle, the two bars) whose corners move. When the time is up the dial turns with rotation keyframes for RING seconds, sixteen rays (lines) fly out twice, lengthening and fading, and the figures flash (opacity in yoyo).
The knob is a slider (role slider): the arrows by STEP, Page Up and Down by a minute, Home and End to the ends, Enter or space start and stop; an aria-live region says started, paused, time is up. A click from a script (the library’s preview) turns the knob down to a few seconds and starts, then chooses a tea, starts, pauses and starts over, and leaves a short countdown alone until it has rung.
| Name | File | Default | What it changes |
|---|---|---|---|
MAX | script.js | 300 | The seconds of a whole turn of the dial. |
STEP | script.js | 5 | How many seconds the knob moves by. |
TEAS | script.js | [['Green tea', 120], ['Black tea', 240], ['Herbal', 300]] | The teas: name and seconds. |
SPRING | script.js | [220, 0.8] | The arc’s spring as it follows the hand or a tea: how stiff it is and how much it is held back. |
RING | script.js | 1.4 | The seconds the dial rings when the time is up. |
For a kitchen or tea timer, a rest between two sets at the gym, work and break times, a countdown in a game or for an offer.
The dial takes up to 82 per cent of the width and the knob turns under a finger: on the dial the page does not scroll (touch-action none) while it is turned.
The arc goes straight where it should, without spring or sweep, the figures change without rolling, the sign changes at once; when the time is up the dial does not shake or throw out rays: it says Ready and goes back to the time set.
GSAP 3.15.0, Urbanist (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.4 KB; the libraries: GSAP 28 KB.
Tested on 3 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.