Skip to content
animorio
IT
Back to the library

The exploded view watch on scroll

WebGL, 3D, Scroll, HoverGSAP, WebGL, CanvasAdvancedCompressed weight: Demo 14 KBGSAP + ScrollTrigger 45 KBLenis 5.3 KBThree.js + RoomEnvironment 176 KBFreeDownload the zip

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.

The code

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>

Playground

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

Or ask Claude Code for it

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 site

What it does

On a warm paper background there is a mechanical watch drawn in 3D, tilted to show its dial: brushed steel case with polished lugs, polished bezel, a domed sapphire crystal that reflects the room, a green sunburst dial with applied gold indices and lume, gold hands and an orange seconds hand beating eight times a second, a knurled crown and a leather strap with stitching, holes and a buckle. On opening it rises from below and settles on a spring. Scrolling down, the watch comes apart along its axis, piece by piece: the crystal and the bezel rise, then the three hands, the dial; under the case the movement, the rotor and the caseback drop away, and the crown slides out on its stem. Each layer floats a little on its own, and callouts appear beside the parts, with a dot on the part and a thin line. Then the watch turns over and shows the movement working: the wheels turn, the escape wheel snaps on every beat with the pallet fork rocking, the balance swings with its blued hairspring, under bridges with Geneva stripes, jewels and blued screws; the gold rotor engraved with the brand swings downwards whenever the watch tilts. The pointer or a finger tilts the watch on a spring; when nobody touches it, it sways slowly on its own. At the bottom, the line to order it.

How it works

A watch made of simple shapes

Everything 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.

Materials that look real

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.

The scroll opens the watch

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.

The movement at work

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.

The callouts

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.

Values to change

NameFileDefaultWhat it changes
BRANDscript.js'Kestrel'The brand on the dial, the rotor, the caseback and at the top of the page.
SPREADscript.js1How far the parts move apart when the watch opens.
TILTscript.js1How much the pointer or a finger tilts the watch.
BEATSscript.js8How many times a second the seconds hand beats (8 is a 4 Hz movement).
SPINscript.js1How fast the movement’s wheels turn and how wide the balance swings.
SWINGscript.js1How freely the rotor swings with gravity.
FLIPscript.js1How far the watch turns over to show the movement (1 = half a turn).
FLOATscript.js1How much each part floats on its own while the watch is apart.

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

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.

Pitfalls

  • The camera has a setViewOffset to move the watch to the right of the words (or below, on the phone): projecting the callouts already accounts for it, because project() uses the same matrix.
  • The transparent crystal does not write to the depth buffer (depthWrite false), otherwise it hides the hands underneath.
  • Canvas-painted textures must be marked sRGB, otherwise colour management washes them out.
  • The dial fonts are drawn in the canvas only once loaded: wait for document.fonts.load before painting.

Libraries

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.

Testing

Tested on 23 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All animations