Skip to content
animorio
IT
Back to the library

The word that grows like coral

WebGL, TextGSAP, WebGL, CanvasAdvancedCompressed weight: Demo 8.8 KBGSAP 28 KBFreeDownload the zip

A minimal-style WebGL animation: a big word that nobody writes, it grows. A shader runs a reaction-diffusion simulation (the Gray-Scott model, the one behind coral and fingerprints) and the pattern can only live inside the letters: from a few seeds of ink a maze grows and fills the word, with the growing edge in vermilion, while the word gains weight. The pointer plants new seeds.

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>Lichen</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>
  <!-- a word that grows like coral: a reaction-diffusion simulation (Gray-Scott) runs in a WebGL shader, and the letters
       of the word are the only place where the pattern can live; the pointer drops new seeds -->
  <main class="pagina" data-pagina>
    <canvas class="tela" aria-hidden="true" data-tela></canvas>
    <h1 class="sr">Lichen</h1>

    <header class="testa">
      <p class="marchio" data-entra>Lichen</p>
      <p class="testa__nota" data-entra>Living materials lab</p>
    </header>

    <p class="nota" data-entra data-nota>Draw to plant a seed</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.

19 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 word that grows like coral” from Animorio and fit it into my site

What it does

On a warm white sheet lies the faint shadow of a word, Lichen, the name of an invented living-materials lab. Nobody writes it: in each letter eight small seeds of vermilion ink appear, and from there a living pattern starts to grow, a mesh of black stripes that branch, split and close up again into many little cells, like lichen, coral or a fingerprint. The pattern can only live inside the letters: when it reaches the edge it stops and follows it, so the word fills up by itself, letter by letter, until every stroke is a small maze. The edge that is still growing is vermilion, the only colour, and turns black when it settles. Meanwhile the word gains weight: the letters slowly widen in place and the coral follows them. Once it is full it stays still for a few seconds, then it melts, the stripes wear away and the paper is clean again, and it starts over from the same seeds. The pointer, or a finger, plants new seeds where it passes: inside the letters they grow and join the rest, outside they make a little curl and die.

How it works

Two substances per cell

The simulation is a grid of cells as big as the page divided by the cell size (CELLS makes a stroke of the word about 22 cells wide). Each cell has two numbers, u and v, the two substances of the Gray-Scott model, stored in the red and green channels of a floating-point texture (RGBA16F, WebGL 2 with EXT_color_buffer_float). There are two textures that take turns: the shader reads from one and writes into the other, then they swap (ping-pong).

One Gray-Scott step

At every step the shader takes the nine-point Laplacian of u and v (minus the centre, 0.2 for the four neighbours, 0.05 for the four diagonals), then the reaction r = u·v²: u becomes u + Δu − r + F·(1 − u) and v becomes v + 0.5·Δv + r − (F + k)·v. With F = 0.0545 and k = 0.062 the pattern is coral, a branching maze. GROW_SPEED steps per sixtieth of a second set how fast it grows.

The word as ground

The word is drawn white on black in a 2D canvas as big as the grid and uploaded as an R8 texture: that is the mask. Inside the mask k is KILL, outside it is 0.0075 higher and v wears away by 0.4 per cent per step: the pattern cannot stay there. Each letter is drawn at the centre of its slot measured at the final weight, so as the weight rises from 460 to 780 the letter widens in place and the seeds stay inside.

The seeds and the vermilion edge

A second shader plants the seeds: inside a circle of cells v goes to 0.9 and u drops to 0.45. The opening ones are picked with a fixed-seed random among points at least six cells from the edge, eight per letter and far apart; the pointer's land where it passes. The blue channel counts how long a cell has been full: where it is young the third shader, the one that draws, uses vermilion instead of black.

The direction

The round runs on GSAP's ticker and growth is counted in steps: the steps keep up with time (seven seconds), but the phase only ends when they are all done, so on a slow graphics card the word takes longer but always fills. The weight rises from 460 to 780 on the same curve as the steps, then the word stays full for HOLD seconds and k rises everywhere over 2.4 seconds: the coral wears away and the paper is clean again. The drawing reads v with a hand-written bilinear filter and a soft threshold, so the stripes have smooth edges even with two-pixel cells. With reduced motion 1400 steps run at once, before the word is shown, and then nothing moves.

Values to change

NameFileDefaultWhat it changes
WORDscript.jsLichenThe word that grows.
GROW_SPEEDscript.js3How many simulation steps per sixtieth of a second: higher grows faster.
FEEDscript.js0.0545How much feed comes in: it changes the pattern (lower, spots; higher, mazes).
KILLscript.js0.062How much is taken away inside the letters: higher, thinner and sparser stripes.
SEEDSscript.js8How many seeds per letter at the start: more seeds, more little cells and faster growth.
HOLDscript.js4.5How many seconds the word stays full before it melts.
WEIGHT_FROMscript.js460The weight of the word when it starts to grow.
WEIGHT_TOscript.js780The weight it reaches.
PENscript.js4The radius of the seed the pointer leaves, in cells.
CELLSscript.js22How many cells wide a stroke of the word is: more cells, finer coral (and more work for the graphics card).

Try them in the Playground

When to use it

As the opening of a biology lab, a materials studio, a natural cosmetics brand or a plant nursery; as the title of an exhibition about nature and growth; as the landing page of a generative design studio that wants to show its name made by a process rather than a hand.

On phones

The same animation: the word is sized on the width and the simulation grid follows the word, so on a phone there are fewer cells (and less work) but the coral fills the letters the same way. A finger that touches or drags plants the seeds.

With reduced motion

The word has already grown and is still, full of its black coral: the simulation steps all run before it is shown, then it fades in. A touch plants a seed and the coral grows at once, with no animation.

Pitfalls

  • Gray-Scott with 8 bits per channel does not work: u and v change by thousandths at every step and round down to zero. It needs floating-point textures you can also render into: WebGL 2 with RGBA16F and the EXT_color_buffer_float extension (or the half-float one). Without them the demo shows the word filled with ink.
  • Half-float textures do not filter linearly on every phone: the state is read with NEAREST and the bilinear filter used to draw it is written by hand in the shader, with four reads.
  • With the whole word centred, every change of weight moved it and the seeds ended up outside the thin letters (the L's ones died). Now each letter sits at the centre of its slot measured at the final weight, and the seeds are picked at least six cells from the edge.
  • With cells too big (a stroke nine cells wide) the coral has no room for its maze and turns into a solid worm: the cell is sized from the word's font size (CELLS), not from the page.
  • With three seeds per letter it took more than five thousand steps to fill the word: on software WebGL (the servers' kind, SwiftShader) a minute was not enough. With eight seeds per letter about twelve hundred are enough, and on software WebGL a stroke drops from 22 cells to 18.
  • The canvas and textures are rebuilt on every resize, even mid-growth: the seeds are planted again and the round goes on.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Testing

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