Skip to content
animorio
IT
Back to the library

The index that comes into focus

Text, TransitionsGSAP, CSS only, CanvasMediumCompressed weight: Demo 6.6 KBGSAP 28 KBFreeDownload the zip

The project index of a portfolio: a column that slides and keeps the current project in the middle, dark, while the others fade; at every change the facts, the palette and the cover blur out and come back in focus.

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 index that comes into focus</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the project index of a made-up designer. On the right the projects stand in a column that slides so the current
       one is always in the middle, sharp and dark, and the others fade; on the left the facts of the project and its
       palette, in the middle its cover. At every change the facts and the cover blur out and come back in focus -->
  <main class="indice" data-indice>
    <header class="testata">
      <p class="firma">KAI VERO<sup>&reg;</sup></p>
      <p class="sopra">Index</p>
    </header>

    <aside class="fatti" data-fatti aria-live="polite">
      <dl>
        <div><dt>Role</dt><dd data-campo="ruolo">Design, art direction</dd></div>
        <div><dt>Launch</dt><dd data-campo="anno">March 2019</dd></div>
        <div><dt>Recognition</dt><dd data-campo="premi">Type Directors Club</dd></div>
      </dl>
      <div class="tavolozza">
        <p class="tavolozza__nome">Palette</p>
        <div class="tavolozza__campioni" data-campioni></div>
      </div>
    </aside>

    <figure class="copertina" data-copertina>
      <canvas class="copertina__tela" data-tela aria-hidden="true"></canvas>
    </figure>

    <div class="colonna" data-colonna>
      <ol class="voci" data-voci>
        <li class="voce" data-ruolo="Design, art direction" data-anno="March 2019" data-premi="Type Directors Club" data-palette="#f6efe6 #ff4b3e #181818" data-forma="luna">
          <button type="button"><span class="voce__tipo">Brand &middot; editorial</span><span class="voce__nome">Paper Moons</span><span class="voce__frase">A lunar calendar printed on tracing paper.</span></button>
        </li>
        <li class="voce" data-ruolo="Design, development lead" data-anno="June 2020" data-premi="Site of the Day" data-palette="#e9e4da #181818 #ff4b3e" data-forma="solchi">
          <button type="button"><span class="voce__tipo">Label &middot; website</span><span class="voce__nome">Low Tide Records</span><span class="voce__frase">A record label that only releases at high tide.</span></button>
        </li>
        <li class="voce" data-ruolo="Product design" data-anno="January 2021" data-premi="Product of the Week" data-palette="#eef0f6 #3b5bdb #0b1b5b" data-forma="griglia">
          <button type="button"><span class="voce__tipo">Product &middot; launch</span><span class="voce__nome">Field Notes Co.</span><span class="voce__frase">Notebooks with a ruler printed on the spine.</span></button>
        </li>
        <li class="voce" data-ruolo="App design" data-anno="May 2022" data-premi="App of the Month" data-palette="#1d1b18 #f2b705 #f4f2ec" data-forma="onde">
          <button type="button"><span class="voce__tipo">Travel &middot; app</span><span class="voce__nome">Sunday Ferry</span><span class="voce__frase">Timetables for a ferry that runs once a week.</span></button>
        </li>
        <li class="voce" data-ruolo="Design, illustration" data-anno="September 2023" data-premi="Honourable mention" data-palette="#f3f1ea #2f9e44 #1b4d2a" data-forma="foglie">
          <button type="button"><span class="voce__tipo">Studio &middot; website</span><span class="voce__nome">Greenhouse 9</span><span class="voce__frase">A plant nursery with a room for every season.</span></button>
        </li>
        <li class="voce" data-ruolo="Campaign, motion" data-anno="April 2024" data-premi="Poster of the Year" data-palette="#191919 #e64980 #f59f00" data-forma="cerchi">
          <button type="button"><span class="voce__tipo">Music &middot; campaign</span><span class="voce__nome">Neon Choir</span><span class="voce__frase">Posters for a choir that sings in car parks.</span></button>
        </li>
        <li class="voce" data-ruolo="Brand identity" data-anno="October 2025" data-premi="Website of the Day" data-palette="#f1ede4 #1971c2 #f59f00" data-forma="righe">
          <button type="button"><span class="voce__tipo">Hospitality &middot; brand</span><span class="voce__nome">Blue Hour Hotel</span><span class="voce__frase">Rooms named after the minutes after sunset.</span></button>
        </li>
        <li class="voce" data-ruolo="Archive design" data-anno="February 2026" data-premi="In progress" data-palette="#efe9df #e8590c #181818" data-forma="scala">
          <button type="button"><span class="voce__tipo">Archive &middot; collection</span><span class="voce__nome">Orange Steps</span><span class="voce__frase">Every staircase of a hill town, one a day.</span></button>
        </li>
      </ol>
    </div>

    <p class="aiuto">Scroll, use the arrows or pick a project</p>
  </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.

47 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 index that comes into focus” from Animorio and fit it into my site

What it does

The work index of Kai Vero, a made-up designer, in three columns. On the right the projects stand in a column, each with its kind, its name and a line: the current project is in the middle, black, and the others fade the further they are; the column never ends. On the left are the project’s facts, the role, the launch, the recognition, and its three colours; in the middle its cover. With the wheel, the arrows, by dragging or by clicking a project, the column slides by one step and stops softly; meanwhile the facts, the colours and the cover blur in a moment, change while they cannot be read and come slowly back in focus. On arrival the page appears, the projects come in one at a time from the middle outwards and the colours one after another. If nobody touches it, the index moves on by itself.

How it works

A column in steps

Every project sits in the middle of the column and the script moves it up or down by as many steps as it is from the current project, each --passo tall. The distance is taken the short way round, with a modulo on all the projects: so the column has no end and the first follows the last.

Catching up

The wheel, the keys and the clicks move a target; every frame the column covers FOLLOW of the way left, as on the site, so it starts quickly and arrives slowly. The opacity of each project goes down with the distance, to FADED. At the end of a gesture it settles on a project, and a small gesture still counts as one step.

The blur

When the project in the middle changes, the facts and the cover go to a blur of BLUR pixels in BLUR_OUT seconds with power2.out; after SWAP_AT seconds, when nothing can be read any more, the script writes the new words, draws the cover and brings them back in focus in BLUR_IN seconds. It is the site’s trick: the text changes while it is blurred, so you never see the jump.

The arrival

The page appears in 0.62 seconds; the projects come in over 0.44 seconds one every ENTRY_STAGGER, starting from the one in the middle and spreading out, and the palette colours one every 0.05. The entry value of each project multiplies its opacity, so the arrival and the distance from the middle work together.

The covers

The covers are drawn by the script on a canvas, with the shapes and colours of each project read from the data- attributes of its entry: for a new project you just add an entry with its facts.

Values to change

NameFileDefaultWhat it changes
FOLLOWscript.js0.22How much of the way the column covers every frame (0.22 on the site).
FADEDscript.js0.24How visible the projects away from the middle are (0.24 on the site).
BLURscript.js8How many pixels the facts blur by at a change (8 on the site).
BLUR_INscript.js0.85How long they take to come back in focus (0.85 on the site).
ENTRY_STAGGERscript.js0.07The gap between one project and the next on arrival (0.07 on the site).
AUTOscript.js3.4The seconds of stillness before the index moves on by itself; 0 for never.

Try them in the Playground

When to use it

For the work list of a portfolio, a studio or an archive: a few projects, each with some facts and a picture, to go through one at a time.

On phones

The same, in a single column: the cover at the top, the facts below and the projects at the bottom, moving with a finger or a tap.

With reduced motion

The column jumps from one project to the next without sliding and the facts change without blurring; no arrival and no moving on by itself.

Pitfalls

  • The new words must be written once the blur is already strong, not at once: written on the first frame, you see the text change before it blurs.
  • The blur back in must be stopped if another change arrives before it ends, with killTweensOf and by killing the pending call: otherwise the old writing arrives after the new one.
  • The distance from the middle must be taken the short way round: without the modulo, going from the last project to the first the column scrolls back through all of them.
  • The column step must be read from the CSS every frame (or on every resize): on a phone it is different, and a fixed number in the script would throw the positions off.

Libraries

GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0, Geist (font variabile) 5.3.0.

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

Testing

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