Skip to content
animorio
IT
All components

The faceted tabs

Tabs, 3D, Transitions, PhysicsCanvas, GSAPAdvancedCompressed weight: Demo 17 KBGSAP 28 KBFreeDownload the zip

A jeweller’s guide to the cuts in four tabs, Round, Oval, Pear and Emerald, with the stone below swaying under the lights: the chosen tab sits in a sliver of crystal cut like its stone. Choosing another, the crystal slides there and is re-cut on the way, through every shape it meets, and the stone re-cuts itself with it as it turns once in the light: the facets slide, split and merge, the outline draws out, grows a point, squares into the steps of an emerald. The crystal can be dragged, and the stone follows the hand.

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>The faceted tabs</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/noto-serif-display@5.3.0/wdth.css">
  <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">
    <!-- a jeweller's guide to the shapes of a diamond, in four tabs. The chosen tab sits in a sliver of crystal cut
         like its stone; choosing another, the crystal slides there and is re-cut on the way, and the stone under the
         tabs re-cuts itself with it while it turns in the light. The crystal and the stone are drawn by the script -->
    <div class="guide" data-guide>
      <div class="seg" data-seg>
        <canvas class="seg__crystal" aria-hidden="true" data-crystal></canvas>
        <div class="seg__tabs" role="tablist" aria-label="Diamond shapes" data-tabs>
          <button class="seg__tab" type="button" role="tab" id="tab-round" aria-controls="cut-round" aria-selected="true"><span class="seg__name">Round</span></button>
          <button class="seg__tab" type="button" role="tab" id="tab-oval" aria-controls="cut-oval" aria-selected="false" tabindex="-1"><span class="seg__name">Oval</span></button>
          <button class="seg__tab" type="button" role="tab" id="tab-pear" aria-controls="cut-pear" aria-selected="false" tabindex="-1"><span class="seg__name">Pear</span></button>
          <button class="seg__tab" type="button" role="tab" id="tab-emerald" aria-controls="cut-emerald" aria-selected="false" tabindex="-1"><span class="seg__name">Emerald</span></button>
        </div>
      </div>

      <div class="stone" aria-hidden="true" data-stone-box>
        <canvas class="stone__view" data-stone></canvas>
      </div>

      <div class="pages" data-pages>
        <section class="page" role="tabpanel" id="cut-round" aria-labelledby="tab-round" tabindex="0">
          <h2 class="page__title">The one that shines most</h2>
          <p class="page__text">Every facet is angled to send the light back up through the top, so no other shape sparkles as much. The classic for a solitaire.</p>
          <dl class="page__facts">
            <div><dt>Length to width</dt><dd>1.00</dd></div>
            <div><dt>One carat</dt><dd>6.5 mm</dd></div>
            <div><dt>Facets</dt><dd>Brilliant</dd></div>
          </dl>
        </section>
        <section class="page" role="tabpanel" id="cut-oval" aria-labelledby="tab-oval" tabindex="0" hidden>
          <h2 class="page__title">Longer, and looks larger</h2>
          <p class="page__text">A brilliant drawn out lengthwise. It looks bigger than a round stone of the same weight, and it slims the finger.</p>
          <dl class="page__facts">
            <div><dt>Length to width</dt><dd>1.40</dd></div>
            <div><dt>One carat</dt><dd>7.7 × 5.5 mm</dd></div>
            <div><dt>Facets</dt><dd>Brilliant</dd></div>
          </dl>
        </section>
        <section class="page" role="tabpanel" id="cut-pear" aria-labelledby="tab-pear" tabindex="0" hidden>
          <h2 class="page__title">A drop with a point</h2>
          <p class="page__text">Round at one end and pointed at the other. Worn with the point towards the nail, it makes the hand look longer.</p>
          <dl class="page__facts">
            <div><dt>Length to width</dt><dd>1.55</dd></div>
            <div><dt>One carat</dt><dd>8.5 × 5.5 mm</dd></div>
            <div><dt>Facets</dt><dd>Brilliant</dd></div>
          </dl>
        </section>
        <section class="page" role="tabpanel" id="cut-emerald" aria-labelledby="tab-emerald" tabindex="0" hidden>
          <h2 class="page__title">Steps of clear light</h2>
          <p class="page__text">Long flat steps instead of sparkle: broad flashes, like a hall of mirrors, and a clear look deep into the stone.</p>
          <dl class="page__facts">
            <div><dt>Length to width</dt><dd>1.40</dd></div>
            <div><dt>One carat</dt><dd>7.0 × 5.0 mm</dd></div>
            <div><dt>Facets</dt><dd>Step</dd></div>
          </dl>
        </section>
      </div>
    </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>

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.

56 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 faceted tabs” from Animorio and fit it into my site

What it does

On a black background a dark tray with four tabs, Round, Oval, Pear and Emerald. The chosen one sits inside a sliver of smoky crystal cut like its stone: a pill for the round, an eye for the oval, a drop for the pear, an octagon of steps for the emerald, with the facets of its rim catching the light. Below is the stone, a faceted diamond swaying slowly under the lights of a studio: through the table you see the star of the pavilion, the facets go from black to white and the smallest ones flash colours. Further down a title, two lines and three figures: the ratio of length to width, the size of one carat and the kind of facets. Choosing another tab, the crystal slides there on a spring and is re-cut on the way, taking the shape of every tab it crosses, and the name under it lights up and grows heavier as it arrives; when it settles, a gleam runs across it. The stone follows a moment later: it re-cuts itself through the same cuts and turns once in the light, then faces you again; if the turn takes it out of its frame it draws back just enough. The old text leaves blurring towards the side being left and the new one comes in from the other, one line after another. The crystal can be taken and dragged: the stone follows the hand through the cuts and, let go, the crystal settles on the nearest tab, thrown a little further by the speed of the hand. The stone leans towards the mouse and turns under a finger or a drag; clicking the chosen tab again turns it once. When the page opens the facets are cut into the crystal and the stone comes in turning.

How it works

The stone

Six rings of sixteen points: table, crown, the two edges of the girdle, pavilion and culet. Each ring is the outline of the cut (a circle, an ellipse, a drop, an octagon) made smaller and set at its own height; in the brilliant the crown and pavilion rings are turned half a step and kites and triangles grow between the rings, in the emerald they stay in line and steps grow instead. The four cuts have the same points in the same order, so going from one to another is just blending them point by point.

The facets and the light

On every frame the stone is turned and looked at from above (VIEW degrees), the normals are worked out and it is drawn from the back to the front. The back facets are solid: the eye’s ray bounces off them and off the facet opposite, and where it comes out the light comes from a studio made of a softbox above, a ring of strip lights with dark gaps, a dim floor and the viewer’s own head. Red, green and blue come out a little apart (FIRE), but only on small facets. The front facets add their reflection by Fresnel in lighter mode, and every edge shows as much as its two facets differ.

The crystal

The four flat shapes (the stadium and the octagon found with a ray cast from the centre, the ellipse, the drop) sampled by angle and blended by where the crystal is, counted in tabs. Three rings of facets with their heights give the normals for a light that leans with the speed; on landing a slanting band of light runs across. Every name takes its colour and weight from how much crystal is under it: the script writes --lit, the CSS uses it in color-mix and font-weight.

The springs

The crystal goes to its tab on a spring (SLIDE), stiffer when it is held; the stone follows the crystal’s position on a second spring (RECUT), so it passes through the cuts in between. The turn is a spring to the next whole turn (SPIN); turned by hand it coasts, slowed by friction, then settles on the nearest whole turn. It is worked out in steps of a two hundred and fortieth of a second, and off screen everything stops.

Hand, keyboard and phone

It is a real tablist: role tab and tabpanel, aria-selected, aria-controls and a single tab reachable with the Tab key; the arrows, Home and End change tab and bring the focus along. The crystal is dragged with a captured pointer, gives like rubber past the ends and, let go, takes the speed of the hand into account; touch-action pan-y lets the page scroll vertically.

Values to change

NameFileDefaultWhat it changes
STARTscript.js0The tab chosen when the page opens (0 Round, 1 Oval, 2 Pear, 3 Emerald).
SLIDEscript.js[240, 24]The spring the crystal slides on: its stiffness, and its damping (less, the more it overshoots).
RECUTscript.js[110, 19]The spring the stone is re-cut on, following the crystal a moment later.
SPINscript.js1How many times the stone turns round when the tab changes (0 none).
SWAYscript.js10How far the stone sways at rest, in degrees (0 still).
VIEWscript.js74How steeply the stone is looked at from above, in degrees (90 straight down on its table).
FIREscript.js0.6How far the stone splits the light into colours (0 none, 1 a lot).
TEXTscript.js0.5The seconds the new text takes to come in.

Try them in the Playground

When to use it

For choosing among a few variants of a product that change in shape, material or finish: the cuts of a stone, the shapes of a frame, the finishes of a metal. Three to five tabs with short names.

On phones

Everything fits in 390 pixels: the tabs narrow and the stone shrinks with its frame. The crystal is dragged with a finger while the page scrolls vertically as usual, and the stone turns under a finger; without a mouse it does not lean towards the pointer.

With reduced motion

No sliding and no turning: the crystal and the stone fade out where they are and back in on the new tab, and the text changes with a fade. The stone stays still and straight, does not sway and cannot be dragged.

Pitfalls

  • A ResizeObserver on the whole component made the crystal jump at every change of tab, because the text below changes height: only the tray and the stone’s frame are observed, only a change of width counts, and the crystal keeps its place counted in tabs.
  • During the turn the pear, point towards the viewer, left its canvas and was cut off: on every frame the stone’s size is measured and, when needed, it draws back just enough to stay inside.
  • Fire on every facet made the emerald’s table look like brown stained glass: the split of the colours shrinks with the facet’s area on the screen.
  • A culet made of a single point gave triangles with no area and no normal, and the map of the edges broke: the culet is a tiny ring (a tiny facet on the round, a short keel on the others), so the mesh is closed and every edge has two facets.
  • Each step of the emerald is made of two triangles, and drawing every edge showed the diagonal: edges take their opacity from the angle between their two facets, and two halves of one plane show no line.
  • The chosen tab’s name turned white at once, before the crystal arrived: colour and weight follow the crystal’s position.
  • Shrinking the crystal’s rings along their normals crossed the points near the tip of the drop: the rings shrink in width and height separately, and stay inside even at the tip.

Libraries

GSAP 3.15.0, Noto Serif Display (font variabile) 5.3.0, Urbanist (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 17 KB; the libraries: GSAP 28 KB.

Testing

Tested on 6 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 components