Skip to content
animorio
IT
Back to the library

One side at a time

SVG, TextGSAPAdvancedCompressed weight: Demo 7.6 KBGSAP 28 KBFreeDownload the zip

A thin outline takes one side at a time, triangle, square, pentagon, up to the octagon, and then rounds into a circle. Every new corner is born in the middle of an edge and pushes its neighbours with a spring; beside it the name of the shape changes in a variable typeface that gets wider as the shape gets rounder. Minimal style.

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>One side at a time</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- one thin outline that takes a side at a time, triangle to circle: every new corner is born on an edge and
         pushes its neighbours round the guide circle; the name of the shape changes beside it -->
    <svg class="figure" viewBox="-130 -130 260 260" role="img" aria-label="Triangle" data-figure>
      <g class="guide" data-guide>
        <circle r="100"></circle>
        <path d="M-5 0H5M0 -5V5"></path>
      </g>
      <g class="shape" data-shape>
        <path class="shape__line" data-line></path>
        <path class="shape__tick" data-tick></path>
      </g>
    </svg>
    <div class="caption">
      <p class="name" data-name aria-live="polite"></p>
      <p class="spec"><span class="spec__text" data-spec></span></p>
    </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.

12 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 “One side at a time” from Animorio and fit it into my site

What it does

On a warm white page there is a dashed guide circle, almost invisible, with a small cross in the middle. A thin black triangle draws itself from its top corner as it turns upright and settles; beside it the letters of “triangle” drop in one by one, narrow, and “3 sides” rises underneath. Then a blue mark appears on one edge: that is where the new corner is born, starting from the middle of the edge, jumping out to the guide circle, going a hair past it and coming back. The neighbours are pushed along the circle one after the other, the nearest first, and each one feels the knock with a small bounce towards the centre. Meanwhile the name changes: the letters the two names share stay and slide to their new place (the final “e” from triangle to square, “agon” from pentagon to hexagon, “he” and “agon” from hexagon to heptagon), the others drop out of the window and the new ones drop in, a little heavier, and get lighter as they land. With every extra side the name gets wider on the wdth axis. After the octagon the edges bow out towards the guide circle and the line opens at the top; the two ends meet, the circle closes with a small elastic kick and turns blue, the guide circle fades because they now coincide, and the name “circle” takes weight letter by letter. Then the circle unwinds as it turns, the words leave and the triangle draws itself again. A click or a tap starts it over.

How it works

Corners on the circle

The shape is a list of corners, each with an angle and a distance from the centre. The regular polygons all stand on a flat edge: corner k of an n-sided polygon sits at the angle 90° + 180°/n + k·360°/n, so the triangle has its point at the top, the square stands straight and the pentagon has a flat base. The guide circle, radius 100 on a drawing 260 wide, is the circle all the corners sit on.

Where the new side is born

To go from n to n+1 sides the script tries every place for the new corner and every way round for the others, and keeps the one that moves the corners least (the sum of the squares of the angles to travel). The new corner starts exactly in the middle of the edge between its two neighbours, so at first nothing shows: the shape is the same, only with one more corner in the middle of an edge.

The spring and the wave

The new corner goes out to the guide circle with back.out, which goes a hair past the spot and comes back. The neighbours go to their new angle with the SPRING ease, each one WAVE seconds later for every place away from the new one, so the push runs round the ring like a wave; at the same moment each one sinks a couple of units towards the centre and comes back with elastic.out: that is the knock they feel. A blue mark points at the corner being born and then flies off.

From polygon to circle

Every edge is drawn with 24 points. A single value, round, pulls every point towards the guide circle along its own ray: at 0 the edges are straight, at 1 they are arcs. Drawing and wiping are a stroke-dasharray worked out on the true length of the outline and counted from its highest point, and the same trick opens the small gap at the top that closes when the circle is done.

The changing name

The name is split into letters. At every change the script looks for the letters the two names share at the start and at the end: those stay, and with the FLIP technique (position before, position after, then a tween of x back to zero) they slide to their new place; the others are taken out of the flow and drop out of a window cut with clip-path, the new ones drop in from above. The width of the name on Archivo's wdth axis goes from 70 for the triangle to 116 for the circle, and at the end the weight climbs from 340 to 760 one letter after the other. A paused timeline only holds the moments with tl.call, and at the end it starts again clean with reset and restart.

Values to change

NameFileDefaultWhat it changes
MAX_SIDESscript.js8The last polygon before the circle, from 3 (triangle) to 12 (dodecagon).
STEPscript.js1.25How many seconds every shape stays before it takes another side.
SPRINGscript.js'back.out(1.5)'How the pushed corners land: back.out goes a hair past and settles; elastic.out(1, 0.5) swings more, power3.out stops dead.
WAVEscript.js0.05How many seconds the push takes to reach the next corner: 0 moves them all at once.
STROKEscript.js1.5How thick the outline is, in pixels.
WIDENscript.js46How much wider the name gets from triangle to circle, on the typeface's wdth axis: 0 keeps it narrow all along.
HOLDscript.js2.2How many seconds the closed circle stays before it unwinds and starts again.

Try them in the Playground

When to use it

For an elegant loading screen or the opening of a page about shapes and growth: a design or architecture studio, a geometry or drawing course, an about page telling of a project that comes together step by step, a brand made of thin lines. Also to explain something that gets closer to an ideal one piece at a time.

On phones

The same animation with the sizes adapted: the shape sits on top, almost as wide as the screen, and the name is centred underneath, smaller; the shared letters slide in the same way. A tap starts it over.

With reduced motion

Nothing moves: each shape fades into the next one already in place, the new letters fade in, the circle arrives already closed and blue and the name takes weight without moving.

Pitfalls

  • GSAP animating font-variation-settings straight from one string to another did not read the starting value properly and the name went narrow for a moment at every change: now a plain number is animated and the string is written on every frame.
  • In the wide layout the name was left aligned, but its container was a grid item with justify-items: center, so it shrank to the name and centred itself: with every new name the whole word moved sideways. The container now stretches over the whole column (justify-self: stretch), and the column is as wide as the widest name, measured at start with its wdth width.
  • A fromTo inside a timeline renders at once, when the timeline is built: the “5 sides” line jumped down before rising away. It needs immediateRender: false.
  • The blue mark withdrawing by shrinking towards the corner left a dot: now the outer end goes out first, then the inner end runs out after it, and below a minimum length the mark is hidden.
  • Letters dropping out of the window with a yPercent of 118 let the tops of the ascenders and the tail of the g show under the name: the window has room for the descenders, so the letters travel 150%.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Testing

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