Skip to content
animorio
IT
Back to the library

The word at the waterline

Hover, Text, PhysicsGSAPMediumCompressed weight: Demo 8.3 KBGSAP 28 KBFreeDownload the zip

In the minimal style: a floating word, cut in half by a thin line of water. Above the line it is black, below it is the same word seen through the water: wider, lighter and blue. The pointer stirs the water, the ripples run along the line, the letters ride them like buoys and rock, and the part under the water bends and shifts with the slope of the surface.

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>Afloat</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>
  <!-- one word afloat on one hairline of water: above the line it is ink, below it is refracted -->
  <main class="stage" data-stage>
    <h1 class="title" data-title>Afloat</h1>
    <div class="layer layer--air" data-air aria-hidden="true"></div>
    <div class="layer layer--water" data-water aria-hidden="true"></div>
    <svg class="lines" aria-hidden="true">
      <path class="line" data-line d="" />
    </svg>
    <div class="measure" data-measure aria-hidden="true"></div>
    <p class="hint" data-hint>Run the pointer through the water.</p>
    <p class="read" data-readout aria-hidden="true"><span class="read__label">Water</span> <span class="read__win"><b class="read__value" data-read>still</b></span></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.

22 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 at the waterline” from Animorio and fit it into my site

What it does

On a paper-coloured ground a very thin black line runs across the whole page: the surface of the water. At the start the line draws itself from the middle outwards, then the letters of Afloat drop from above one after another, left to right, a little askew. Each one goes into the water, sinks under its own speed and comes back up rocking, and where it fell a ripple runs along the line both ways and sets the neighbours swaying. Above the line the letters are solid black; below it you see the same letter through the water, blue, wider and lighter on the axes of the variable typeface, slightly magnified, so the word looks broken right at the waterline, like an oar in a lake. Moving the pointer through the water, or just skimming it, pushes the line down under the finger with a little bow wave in front; going in or out of the water sharply makes a small splash. The ripples run, cross each other and die out at the edges. Every letter follows the water under it like a buoy, a little late: it rises and falls, tilts with the slope and drifts slightly downhill; its submerged part shifts sideways and bends with the slope, the way things look under moving water. Bottom right, small print says how the water is: still, rippled or choppy (in blue). If nobody touches the page, an invisible finger now and then dips into the water by a letter, runs through it and comes out again.

How it works

Two layers cut at the waterline

Every letter is drawn twice, in the same place, in two page-sized layers: the air layer, black, and the water layer, blue, with the typeface wider and lighter (font-stretch and font-weight from :root variables) and slightly magnified in height. Every frame both layers are cut with clip-path: polygon() along the surface of the water, the air above and the water below. So the cut follows the wave to the pixel, right through the letters, without working anything out for each letter.

The water is a row of springs

The surface is a row of columns, about one every seven pixels: each column has a height and a speed and is tied to its two neighbours like a string, so a push becomes a ripple running both ways. The stiffness comes from SPEED (in letter heights per second), the damping from CALM; at both ends a sponge of more damped columns soaks the waves up instead of bouncing them back. The physics runs in fixed steps of a two-hundred-and-fortieth of a second inside gsap.ticker, and a wave never goes past a fifth of a letter.

The finger in the water

The speed of the pointer is measured every frame. When the pointer is under the surface or skims it, the column under it gets a downward push in proportion to the speed (STIR), shaped like a bell, and a little ahead, in the direction of travel, an upward push: the bow wave. Crossing the surface adds a splash, downwards going in and upwards coming out, as big as the vertical speed.

The letters as buoys

Every letter has three springs: a soft, lightly damped vertical one that chases the height of the water under its centre (FLOAT), one for the tilt that chases the slope (ROCK) and a slow one that lets it drift slightly downhill. Being soft, the letters arrive late and swing: that is the rocking. The submerged part also gets a sideways shift and a skewX in proportion to the slope (REFRACT), turning around the point where the letter meets the water: that is the refraction.

Directing: the entrance, the reading and the invisible finger

The entrance is a GSAP timeline: the line draws itself with expo.out, then every letter drops with power2.in and, when it gets there, hands over to the physics with a downward speed and gives the water the push of the splash. The reading of the water changes word by rolling through a little window with back.out. After IDLE seconds with no pointer a timeline moves an invisible finger that dips into the water, runs through it and comes out; a real pointer sends it away. When water and letters are still, drawing stops.

Values to change

NameFileDefaultWhat it changes
WORDscript.js'Afloat'The word on the water (up to 14 letters; a short one stays big).
DEPTHscript.js0.46How deep the letters sit: the share of the x-height under the water.
SPEEDscript.js2.4How fast the ripples run, in letter heights per second.
CALMscript.js1How quickly the water calms down: 0.4 long ripples, 2.5 thick water.
STIRscript.js1How much the pointer stirs the water.
FLOATscript.js0.9How much the letters ride the waves (0 = they stay put and only the water moves).
ROCKscript.js0.85How much the letters tilt with the slope of the water.
REFRACTscript.js1How much the submerged part bends and shifts away from the part in the air.
IDLEscript.js2.2After how many seconds without a pointer the invisible finger runs through the water (0 = never).
--deepstyle.css#2b3cffThe colour of the word under the water, the only accent.
--under-widthstyle.css116How wide the word is under the water, in percent: the water magnifies.
--under-weightstyle.css380The weight of the word under the water.

Try them in the Playground

When to use it

For a calm heading you can touch: the opening of the site of a beach club, a sailing or swimming school, a spa or a lake hotel, the name of a swimwear or drinks brand, a quiet 404 page. It works with any short word.

On phones

The same water with the sizes adapted: the word fills almost the whole width and the speed and height of the waves are measured in letter heights, so they work small too. You drag a finger through the water; the hint becomes «Drag a finger through the water.» and hides if there is no room beside the water reading.

With reduced motion

Nothing moves: the line and the word fade in with the water still, the top half black and the bottom half blue, wide and light. The pointer makes no waves and the reading stays on still.

Pitfalls

  • With waves up to a third of a letter and the full push of the pointer, the crest went over the letters and the word could no longer be read: a wave stops at a fifth of a letter and the finger pushes more gently.
  • With the ends of the row of springs fixed, the ripples came back from the sides of the page and the water never calmed down: at each end a sponge of heavily damped columns soaks them up.
  • In the entrance drawing stopped between one letter and the next, because the water was still, and the falling letters hung in mid-air: drawing can only stop after the entrance.
  • The reading said choppy for water that was barely rippled: the state is read on the highest wave, smoothed (it rises fast and falls slowly), with thresholds measured in letter heights.
  • Turning the letter around its centre, the submerged part came apart from the part in the air: both turn and bend around the point where the letter meets the water (transform-origin worked out in pixels).

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 8.3 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