
The needle gauge
Counters, Physics, SVG
NewFree
A channel's Subscribe button, with a brass bell. Pressed, the bell swings like a pendulum and inside it the clapper is a second pendulum: it lags behind, strikes the rim and at every strike drawn rings of sound go out, as strong as the blow, while the subscriber count rolls up figure by figure. Unsubscribing, the bell is caught and a bar is drawn through it.
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 bell subscribe button</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/onest@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the subscribe button, with the subscriber count beside it and a hint under it. Subscribing, the bell swings
like a pendulum with its clapper as a second pendulum inside it: each time the clapper strikes the rim, rings
of sound go out, and the count rolls up like an odometer. Unsubscribing, the bell is stopped and a bar is
drawn through it -->
<div class="subscribe" data-subscribe>
<div class="subscribe__row">
<button class="sub" type="button" aria-pressed="false" aria-label="Subscribe to the channel" data-sub data-autoclic>
<span class="sub__bell" aria-hidden="true">
<svg class="sub__waves" viewBox="-90 -90 180 180" data-waves></svg>
<svg class="sub__icon" viewBox="0 0 32 32" data-icon>
<defs>
<linearGradient id="brass" gradientUnits="userSpaceOnUse" x1="7" y1="0" x2="25" y2="0" data-light>
<stop offset="0" class="brass-a"/><stop offset="0.45" class="brass-b"/><stop offset="1" class="brass-c"/>
</linearGradient>
</defs>
<g data-bell>
<g data-clapper>
<path class="bell__rod" d="M16 9v15.6"/>
<circle class="bell__ball" cx="16" cy="26.6" r="2.7"/>
</g>
<path class="bell__loop" d="M14.2 5.6a1.8 1.8 0 1 1 3.6 0"/>
<path class="bell__body" d="M16 5.4c-5.4 0-8 4-8 8.8v4.6c0 2.3-1.3 3.7-2.8 4.6-.6.4-.3 1.3.4 1.3h20.8c.7 0 1-.9.4-1.3-1.5-.9-2.8-2.3-2.8-4.6v-4.6c0-4.8-2.6-8.8-8-8.8z"/>
<path class="bell__shine" d="M11.2 11.2c.7-1.8 2-2.9 3.4-3.3"/>
</g>
<path class="bell__slash" d="M5.4 4.6l21.8 23.6" pathLength="1" data-slash/>
</svg>
</span>
<span class="sub__labels">
<span class="sub__label" data-label="subscribe">Subscribe</span>
<span class="sub__label" data-label="subscribed">Subscribed</span>
<span class="sub__label sub__label--off" data-label="unsubscribe">Unsubscribe</span>
</span>
</button>
<dl class="stat">
<dt>Subscribers</dt>
<dd><span class="count" data-count aria-hidden="true"></span><span class="sr" data-count-text></span></dd>
</dl>
</div>
<p class="subscribe__hint"><span data-hint></span></p>
<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.
21 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 bell subscribe button” from Animorio and fit it into my siteThe bell turns round its loop (angle θ) and the clapper hangs a little lower (angle φ from the vertical). Every frame the script writes the equations of motion of the two angles: a 2 × 2 mass matrix that depends on cos(θ − φ), the centrifugal terms with sin(θ − φ), the weight of each and a damping on the bell. It solves the system with the determinant formula and steps on in 1/600 of a second, with the frame's step capped at 1/30. The two pendulums' own frequencies are the BELL and CLAPPER values: from them the script works out the gravity and stiffness it needs.
The clapper is slower than the bell, so it lags behind. When its angle against the bell passes the rim (0.5 radians) and it is still heading outwards, it bounces: an impulse with a restitution of 0.3 swaps momentum between the two, so the bell feels the blow too. If the speed of the impact is above a threshold it is a real strike, and its strength decides the rings.
Pressed, the bell gets a kick of speed and for half a second a force in the direction it is going, like a hand shaking it: so it reaches about 45 degrees and the clapper strikes at once. Unsubscribing, the hand stops it: a force against its speed and its angle brings it down in a moment.
At every strike, round the middle of the bell (turned with it) WAVES SVG arcs open on the side that was hit and as many fainter ones on the other. Each is a path with an «A» arc redrawn at every step of a GSAP tween: the radius grows, the stroke thins, the opacity rises fast and falls slowly. The strength of the strike decides how far they go and how bright they are.
Each figure of the number has its own slot with hidden overflow and a mask that fades it at the top and bottom. A figure that changes becomes a strip with every figure in between, from the old one to the new, that rolls up with back.out; the right-hand figures go first. The bar on the bell is a path with pathLength 1 drawn with stroke-dashoffset, with an edge in the button's colour made of two drop-shadows, so it cuts the bell cleanly.
| Name | File | Default | What it changes |
|---|---|---|---|
COUNT | script.js | 48299 | The subscribers before you. |
SWING | script.js | 1 | How hard the bell is rung (1 = about 45 degrees). |
RING | script.js | 0.8 | The seconds the swing takes to die down to a third. |
BELL | script.js | 2.2 | The bell's own swings per second. |
CLAPPER | script.js | 1.3 | The clapper's own swings per second: slower than the bell, so it lags and strikes. |
WAVES | script.js | 3 | How many rings of sound go out at each strike. |
QUIET | script.js | 2.4 | The seconds the bar stays through the bell after unsubscribing. |
For subscribing to a channel, a newsletter, notifications from a product or an author: wherever the bell means «I will let you know». The movement is short and dies down on its own, so it holds up on a busy page too.
The button is 60 pixels tall, big enough for a thumb, and at 390 pixels the count still sits beside it; on a narrower screen it goes under it. At a touch it gives and the bell rings as with the mouse; without a mouse there is no Unsubscribe under the finger: a second tap unsubscribes and shows the bar.
The bell does not swing: subscribing, two still arcs light up on either side of it and fade, the words change without sliding and the number changes at once. Unsubscribing, the bar is already there and the bell dims.
GSAP 3.15.0, Onest (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 8.7 KB; the libraries: GSAP 28 KB.
Tested on 12 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.