Skip to content
animorio
IT
Back to the library

The rings of the trunk

Scroll, SVGGSAPMediumCompressed weight: Demo 6.7 KBGSAP + ScrollTrigger 45 KBFreeDownload the zip

Scroll inside the preview

A furniture workshop’s story told by the oak planted the year it opened, in the minimal style: as you scroll, the cross-section of the trunk grows one ring a year under its bark, wide in the good years and narrow in the dry ones, while the year counts. The years that mattered are vermilion rings, marked on a thin ruler from the pith to the bark, and they change the note under the year.

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 rings of the trunk</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/newsreader@5.3.0/opsz.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the story of a made-up furniture workshop, Alder, told by the oak planted the year it opened. Scrolling, the
       cross-section of the trunk grows one ring a year under its bark, from the pith outwards, while the year counts;
       the years that mattered are drawn in vermilion and written on a thin radial ruler -->
  <main>
    <section class="apertura">
      <p class="piccolo">Alder, furniture workshop</p>
      <h1 class="titolo">The oak in our yard<br>keeps the books.</h1>
      <p class="piccolo piccolo--tenue">Scroll to count the rings.</p>
    </section>

    <section class="racconto" data-racconto>
      <div class="palco" data-palco>
        <header class="testa">
          <p class="marchio">Alder</p>
          <p class="piccolo piccolo--tenue">One ring a year</p>
        </header>

        <svg class="tronco" data-tronco aria-hidden="true"></svg>

        <div class="conto">
          <p class="anno" data-anno>1962</p>
          <p class="nota" data-note aria-live="polite"></p>
        </div>
      </div>
    </section>

    <section class="apertura apertura--fine">
      <h2 class="titolo titolo--medio">Every table we make<br>is a few of these rings.</h2>
    </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="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.

24 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 rings of the trunk” from Animorio and fit it into my site

What it does

The story of a made-up furniture workshop, Alder, on a warm white with black ink in hairlines and a single vermilion. After the opening the screen stops: on the right the pith of an oak, a small black ring with the bark just around it; on the left the year, 1962, large in a variable serif, and the first note below. As you scroll the trunk grows outwards one year at a time: every ring draws itself round starting from the ruler, just under the bark, and the bark widens with it. The rings are wide in the good decades and narrow in the dry ones, tighter and tighter as the tree gets older, and none is a perfect circle: they all share the slightly crooked shape of a real oak. The year counts in fixed-width figures; when a year that mattered arrives (1975, 1991, 2008) its ring is vermilion and thicker, a tick and the year appear on the ruler that runs from the pith to the bark, the big figure takes weight for a moment and the note changes in a window: the old one leaves upwards, the new one rises from below. At 2026 the bark goes a hair past the last ring and settles with a small elastic, and the year stays bold. Everything follows the scroll, forwards and backwards.

How it works

A tree from its seed

The widths of the rings come from a small seeded random number generator (SEED): the same seed always grows the same tree. Each width is a slow climate (two sine waves, the good decades and the dry ones) times the noise of the year, and it drops with age as in real trees. The running sums give the radius of every ring, from the pith’s up to 1.

One crooked shape for all

Each ring is a path of 144 points: the radius times 1 plus three sine waves (one, two and three waves per turn) that all the rings share, plus a small wave of its own. The first one moves the centre, like the off-centre pith of a real trunk; the others squash it. WOBBLE says how much. The paths start from the ruler’s angle, so every ring draws itself from there.

One ring a year

The timeline, tied to the scroll with scrub SCRUB, carries a number y from 0 to the number of years. Each ring has pathLength 1 and stroke-dasharray 1 1: its stroke-dashoffset goes from 1 to 0 while y passes through its year, drawing it round. The bark is a single path at full size, scaled every frame to the ring being drawn, with vector-effect non-scaling-stroke so the line stays thin.

The years that mattered

NOTES holds the notes by year: the years between the first and the last become vermilion rings, with a tick and the year on the ruler. The labels have an outline in the paper colour painted underneath (paint-order: stroke), so they read over the rings. The big figure takes weight for three years after each note, and the new note rises from below an overflow hidden window while the old one leaves upwards.

The settle and the measures

At the last year a second value of the timeline widens the bark by 1.2 per cent and lets it come back with elastic.out, while the year takes a little more weight with a back.out. Centre, radius and the place of the year are worked out again on every ScrollTrigger refresh and on every resize.

Values to change

NameFileDefaultWhat it changes
FROMscript.js1962The year the tree was planted: the pith.
TOscript.js2026This year: the ring under the bark.
NOTESscript.js{ 1962: …, 1975: …, 1991: …, 2008: …, 2026: … }The notes, by year: the years between the first and the last become vermilion rings on the ruler.
WOBBLEscript.js0.07How far the rings are from a perfect circle.
SEEDscript.js7Change it for another tree (wide and narrow rings in other years).
SCRUBscript.js0.6How many seconds the drawing takes to catch up with the scroll.

Try them in the Playground

When to use it

For the «our story» page of a craft shop, a woodworker, a winery, a plant nursery or any business with a few decades behind it: the years really go by under your eyes and the important ones stay marked. It also works for an anniversary.

On phones

The same, with adapted measures: the trunk sits centred near the top, the year and the note below, and the rings have a finer line because they are closer together.

With reduced motion

The trunk does not grow before your eyes: one still picture per note (1962, 1975, 1991, 2008, 2026) with all the rings up to that year, taking turns with a cross-fade; the notes cross-fade and there is no elastic at the end.

Pitfalls

  • The bark’s radius is read anywhere between two years (y is not a whole number): the sums of the widths must be interpolated between the two rings, otherwise the fractional index gives undefined and the drawing turns into NaN.
  • The last note came in half a year after the last year, that is never: every note reaches its place within its year and the old one leaves just before.
  • The year labels on the ruler got lost among the rings: with an outline in the paper colour painted underneath (paint-order: stroke) they read.
  • Without vector-effect non-scaling-stroke the scaled bark would start with an almost invisible line and end up thick.

Libraries

GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Newsreader (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 6.7 KB; the libraries: GSAP + ScrollTrigger 45 KB.

Testing

Tested on 19 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