
The word behind fluted glass
WebGL, Text, Hover
NewFree
A minimal-style WebGL animated headline: on the dark floor of a swimming pool the net of light drawn by the water, the caustics, moves and weaves; when the surface calms down the light gathers along the outline of the letters and the word reads written in light, with a blue flash. The pointer or a finger stirs the water, a click or a tap drops a pebble that opens a ring wave.
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>Lido Marne</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 written by caustics: the light on the floor of a pool, refracted by the water, focuses into the letters
when the surface calms down; the pointer stirs the water and a tap drops a pebble -->
<main class="pagina" data-pagina>
<canvas class="tela" aria-hidden="true" data-tela></canvas>
<h1 class="parola" data-parola>Lido</h1>
<header class="testa">
<p class="marchio" data-entra>Lido Marne</p>
<p class="testa__nota" data-entra>Open-air pool, since 1934</p>
</header>
<footer class="piede">
<p class="nota" data-entra data-nota>Move to stir the water, tap to drop a pebble</p>
<p class="misura" data-entra>Surface <span data-calma>calm</span></p>
</footer>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="script.js"></script>
</body>
</html>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
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The word written in light by pool water” from Animorio and fit it into my siteEverything is a single WebGL 2 fragment shader on one triangle as big as the page. For each pixel the shader asks how high the water is there and around it, at nine points two pixels apart, and works out the second derivatives. The surface acts as a lens: the light reaching the floor is 1 / |det(I + H)|, with H the matrix of second derivatives. Where the determinant goes through zero the light gathers into a bright line: that is the caustic, actually computed, not drawn.
The moving water is the sum of four long waves with different directions, lengths and speeds. Each wave is sin(k · x + ω · t) / k²: dividing by k² gives them all the same curvature, so none of them dominates the net. RIPPLE sets how high they are; the timeline takes them from 1 to 0.09 in CALM seconds, and that is when the net comes apart and the word remains.
The word is written once in a 2D canvas, blurred with three box-blur passes in JavaScript and turned into a 32-bit float texture: it is the relief under the water. In 8 bits the second derivatives would be a grain of noise, so no RGBA: a single R32F channel, interpolated by hand in the shader from the four neighbours, because 32-bit floats are not filtered on their own. The blur grows with the size of the word, so the lines of light keep the same design at every size.
Each pebble is a vec4 with position, time and strength, up to ten at once. The shader adds a ring wave running at 230 px per second, with a soft front and a fading tail. The pointer leaves a small wave every 26 px and every seven hundredths; a click or a tap leaves a strong one, PEBBLE. The tile joints shift slightly with the slope of the surface, as you see them through water.
A looping GSAP timeline: the water calms down over CALM seconds while the relief of the word rises; a blue flash of a second and a half when it is in focus; a moment later a pebble drops on the d (skipped if someone is using the pointer); then the wind stirs the water again and the relief sinks. The shader runs on GSAP's ticker, and the label at the bottom changes only when the state changes.
| Name | File | Default | What it changes |
|---|---|---|---|
WORD | script.js | Lido | The word written by the light. |
FOCUS | script.js | 1 | How much the word focuses the light: higher, sharper and more doubled lines. |
ROUND | script.js | 14 | How soft the relief of the letters is, in px: higher, wider lines further from the edge. |
RIPPLE | script.js | 1 | How rough the water is when it is not calm. |
CALM | script.js | 3.2 | How many seconds the water takes to calm down. |
PEBBLE | script.js | 1 | How strong the pebble of a click or a tap is. |
TILE | script.js | 46 | The side of the floor tiles, in px. |
WEIGHT | script.js | 860 | The weight of the word. |
As the opening headline of a swimming pool, a lido, a hotel with a pool or a seaside holiday home; behind the name of a spa, a swimming school or a summer festival; as the landing page of a studio that wants a living, calm headline that only breaks up when you touch it.
The same animation: the word is sized on both width and height, and the blur of the relief grows or shrinks with it, so the lines of light look the same. A dragging finger stirs the water, a tap drops a pebble; the line at the bottom says drag instead of move.
The water is already calm and still, and the word reads written in light from the first moment: no running waves, no pebbles, no timeline. The labels fade in.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 8.0 KB; the libraries: GSAP 28 KB.
Tested on 23 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.