
The dash relief
WebGL, 3D, Hover
Free
Scroll inside the preview
The product page of a made-up watchmaker, in the rich style and in WebGL: a mechanical watch in 3D, steel, sapphire crystal, green sunburst dial and leather strap, that comes apart piece by piece in an exploded view as you scroll, with thin callouts on every part, then turns over to show the movement working: wheels, escapement, balance and the gold rotor swinging with gravity.
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>Kestrel Field 38</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.178.0/build/three.module.min.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.178.0/examples/jsm/"
} }
</script>
</head>
<body>
<!-- the product page of a made-up watchmaker, Kestrel. The stage sticks while you scroll: a mechanical watch,
drawn in 3D, comes apart layer by layer (crystal, bezel, hands, dial, case, movement, rotor, caseback), then
turns over to show the movement ticking; the pointer or a finger tilts it, and the rotor swings with it -->
<main>
<section class="vista" data-vista>
<div class="palco" data-palco>
<canvas class="tela" data-tela role="img" aria-label="A mechanical wristwatch coming apart in an exploded view as you scroll"></canvas>
<svg class="fili" data-fili aria-hidden="true"></svg>
<div class="etichette" data-etichette aria-hidden="true"></div>
<header class="testata">
<p class="marchio">
<svg viewBox="0 0 32 32" aria-hidden="true"><circle cx="16" cy="16" r="12.5"/><path d="M16 8v8l5 3"/></svg>
<span data-marchio>Kestrel</span>
</p>
<p class="sotto">Watchworks</p>
</header>
<div class="racconto" data-racconto>
<div class="capitolo" data-capitolo>
<p class="occhiello">Field 38 Automatic</p>
<h1 class="titolo">A watch you can <em>read</em> inside out.</h1>
</div>
<div class="capitolo" data-capitolo>
<p class="occhiello">Seven layers</p>
<h2 class="titolo">Every part, <em>apart.</em></h2>
</div>
<div class="capitolo" data-capitolo>
<p class="occhiello">Turn it over</p>
<h2 class="titolo">A heart that beats <em>eight</em> times a second.</h2>
</div>
<div class="capitolo" data-capitolo>
<p class="occhiello">Calibre K-21</p>
<h2 class="titolo">Wound by your <em>wrist.</em></h2>
</div>
</div>
<p class="nota" data-nota>Scroll to take it apart</p>
</div>
</section>
<section class="ordina">
<p class="occhiello">Kestrel Field 38 · Automatic · 38 mm</p>
<p class="prezzo">€1,480</p>
<a class="pillola" href="#" data-pillola><span>Reserve yours</span></a>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.min.js"></script>
<script type="module" 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.
37 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 exploded view watch on scroll” from Animorio and fit it into my siteEverything is Three.js geometry built in code: case, bezel and caseback are profiles turned around the axis (LatheGeometry), the crystal is a cap of a very wide sphere, the dial a circle, while hands, gear wheels, bridges and rotor are extruded 2D shapes (ExtrudeGeometry). The wheels have their teeth drawn point by point and their spokes cut out as holes in the shape.
The light comes from a fake room (RoomEnvironment) passed through PMREMGenerator: that is what makes steel, gold and glass reflect. Steel is a metal with low roughness for polished parts and higher for brushed ones; the crystal is a transparent MeshPhysicalMaterial with clearcoat; dial, perlage, Geneva stripes, leather and the rotor and caseback engravings are textures painted in a 2D canvas.
ScrollTrigger with scrub drives a number from 0 to 1. Two curves come from it: how far it opens (between 0.1 and 0.46) and how far it turns over (between 0.55 and 0.8). Every piece sits in a group with its own distance along the watch’s axis: the position is distance times opening, plus a small float on its own sine. The camera pulls back as the parts spread, so everything stays in the box.
Everything follows the GSAP ticker. The seconds hand moves in steps, BEATS a second; the escape wheel snaps on the same beats, the pallet fork rocks on every beat, the balance swings on a sine. The rotor is a pendulum: world gravity is taken into the watch with the inverse quaternion, and the rotor is pushed towards it by a damped spring. When the watch turns over or tilts, the rotor really swings.
Each callout has a point on its part, in watch coordinates. Every frame the point is taken into the world (localToWorld) and onto the screen (project), and there go the dot, the SVG line and the words, right or left depending on the side, always inside the screen. The front ones appear when the watch is open, the back ones once it has turned over.
| Name | File | Default | What it changes |
|---|---|---|---|
BRAND | script.js | 'Kestrel' | The brand on the dial, the rotor, the caseback and at the top of the page. |
SPREAD | script.js | 1 | How far the parts move apart when the watch opens. |
TILT | script.js | 1 | How much the pointer or a finger tilts the watch. |
BEATS | script.js | 8 | How many times a second the seconds hand beats (8 is a 4 Hz movement). |
SPIN | script.js | 1 | How fast the movement’s wheels turn and how wide the balance swings. |
SWING | script.js | 1 | How freely the rotor swings with gravity. |
FLIP | script.js | 1 | How far the watch turns over to show the movement (1 = half a turn). |
FLOAT | script.js | 1 | How much each part floats on its own while the watch is apart. |
For the product page or the hero of a watchmaker, a watch or jewellery shop, and in general to present a product made of parts (a camera, headphones, a fountain pen): the exploded view on scroll tells how it is made and how much care went into it.
The same animation with adapted sizes: the words sit at the top, the watch below, and the camera pulls back as far as needed so that even when open it all fits in the box; a finger tilts the watch by dragging sideways, and the page keeps scrolling.
No long scroll and no motion: the watch is already open and still, with the front callouts, the hands stopped and the movement at rest.
Three.js 0.178.0, GSAP 3.15.0, Lenis 1.3.26, Fraunces (font variabile) 5.3.0, Bricolage Grotesque (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 14 KB; the libraries: GSAP + ScrollTrigger 45 KB, Lenis 5.3 KB, Three.js + RoomEnvironment 176 KB.
Tested on 23 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.