Bringing mechanical clockwork and escapement physics into browser markup
Outcome
Simulated a ticking mechanical timepiece escapement directly in the browser DOM with zero heavy 3D engines.
- Sub-50KB bundle weight
- Pure DOM SVG and CSS transforms
- Synchronized escapement and recoil
Most modern websites feel weightless. A button fades in, a modal slides down, a dropdown snaps open. It’s clean, but it feels like pushing air. There’s no mass, no momentum, and no mechanical resistance.
I grew up on a ranch fixing equipment, building fences, and working with hand tools. When you turn a wrench or engage a gear, you feel the mechanical feedback immediately. A few months ago, while watching an antique clockmaker work on a balance wheel escapement, I wondered why digital interfaces can’t carry that same physical weight.
Instead of opening a canvas-heavy 3D framework or dumping a 2MB Three.js bundle onto the page, I spent a Saturday building a mechanical clock escapement directly in the DOM using Anime.js v4 and plain SVG markup.
Use the interactive rig below to start the assembly, watch the gear teeth catch the escapement pallet, and see the recoil piston respond in real time.
Why the Architecture Matters
If an animation takes hundreds of kilobytes of JavaScript or drops frames on a laptop fan, it’s not physical—it’s just laggy. A few practical constraints guided the build:
1. Pure SVG & DOM Transforms (No Canvas Overhead)
Canvas-based physics engines are great for games, but they trap elements inside a black box that screen readers and the browser layout engine can’t touch. Every gear tooth, escapement arm, and piston in this rig is an ordinary SVG node styled with CSS. That keeps the bundle tiny and lets the browser’s native compositing pipeline handle the heavy lifting.
2. Coupled Mechanical Timelines
In a physical timepiece, parts don’t move independently; one piece physically forces the next. The gear can only advance when the escapement pallet rocks out of the way. With Anime.js v4, the rotation of the main drive gear, the sinusoidal rock of the anchor arm, and the horizontal kick of the recoil piston are bound to a single master timeline clock. If you pause the timeline, the whole assembly freezes mid-tick.
3. Damped Springs Instead of Easing Curves
Standard cubic bezier easing curves look smooth, but real metal has inertia. When the recoil arm hits the backstop, it doesn’t decelerate linearly—it overshoots slightly and snaps back. Using parametric damped springs gives the piston an unmistakable snap that feels like metal seating against metal.
Honest Caveats
Animating dozens of SVG elements simultaneously in the DOM has real limits:
- Mobile Battery Impact: Running a continuous RAF (requestAnimationFrame) loop with multiple rotating SVG nodes will warm up a phone if left running indefinitely in the background. The rig automatically pauses when scrolled out of view.
- Precision at Scale: For true mechanical CAD or gear-ratio modeling with friction and torque transfer, the DOM is the wrong tool. This is an interactive design prototype designed to prove a point about tactile weight, not an industrial physics solver.
Live Rig Controls
Use the interactive controls below to run the cycle, reset the pins, or inspect the underlying timeline declaration.
Anime.js Kinetic Escapement Configuration
import { createTimeline, animate } from 'animejs';
// Instantiate Mechanical Escapement Timeline
const escapementTimeline = createTimeline({
autoplay: false,
loop: true
});
escapementTimeline
.add('#gear-rotor', {
rotate: 360,
duration: 3200,
ease: 'linear'
})
.add('#escapement-arm', {
rotate: [-14, 14],
duration: 400,
alternate: true,
ease: 'inOutSine'
}, '0')
.add('#recoil-piston', {
translateX: [0, 16],
duration: 400,
alternate: true,
ease: 'outBack(1.5)'
}, '0');