
Standing letters with a long shadow
Text, Scroll, 3D
NewFree
Scroll inside the preview
A minimal-style scroll animation on warm white: a sentence drawn in thin outlines, like glass letters, fills with blue water as you scroll down, from the bottom line to the top. The surface sways on its own, sloshes when you scroll fast, leans towards the pointer and takes a drop where you tap; small bubbles climb and a thin gauge on the side reads the millilitres.
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>Brimvale Glass</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- a made-up maker of glass carafes, Brimvale. The stage sticks while you scroll: the sentence is drawn as thin glass
outlines and water rises inside the letters as you scroll, with a surface that sways, sloshes when you scroll
fast, leans towards the pointer and takes a drop where you tap. A thin gauge on the side reads the millilitres.
The water, the surface and the bubbles are drawn by the script -->
<main>
<section class="corsa" data-corsa>
<div class="palco" data-palco>
<header class="testa">
<a class="marchio" href="#" data-entra>Brimvale</a>
<p class="testa__nota" data-entra>Glass carafes, blown by hand</p>
</header>
<svg class="tela" data-tela viewBox="0 0 1000 640" role="img" aria-label="Slowly, then all at once.">
<defs>
<clipPath id="lettere" data-lettere>
<text class="riga" x="470" y="190" text-anchor="middle">Slowly,</text>
<text class="riga" x="470" y="360" text-anchor="middle">then all</text>
<text class="riga" x="470" y="530" text-anchor="middle">at once.</text>
</clipPath>
<linearGradient id="acqua-grad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="acqua__alto"/>
<stop offset="1" class="acqua__basso"/>
</linearGradient>
</defs>
<!-- the glass: a thick outline with the paper colour laid over its inner half, so only the outer edge shows
and the overlapping parts inside the letters stay hidden; the water goes on top -->
<g class="contorni" data-contorni>
<g class="contorni__bordo">
<text class="riga" x="470" y="190" text-anchor="middle">Slowly,</text>
<text class="riga" x="470" y="360" text-anchor="middle">then all</text>
<text class="riga" x="470" y="530" text-anchor="middle">at once.</text>
</g>
<g class="contorni__vetro">
<text class="riga" x="470" y="190" text-anchor="middle">Slowly,</text>
<text class="riga" x="470" y="360" text-anchor="middle">then all</text>
<text class="riga" x="470" y="530" text-anchor="middle">at once.</text>
</g>
</g>
<g clip-path="url(#lettere)">
<path class="acqua" data-acqua d="M0 640 H1000 V640 Z"/>
<path class="acqua__riflesso" data-riflesso d="M0 0"/>
<g data-bolle></g>
<path class="acqua__pelo" data-pelo d="M0 0"/>
</g>
<circle class="goccia" data-goccia r="7" cx="0" cy="-20"/>
<g class="scala" data-scala>
<path class="scala__asta" d="M944 80 V560"/>
<g data-tacche></g>
<g class="scala__indice" data-indice>
<path d="M926 0 H962"/>
<text class="scala__numero" data-numero x="914" y="5" text-anchor="end">0 ml</text>
</g>
</g>
</svg>
<p class="cenno" data-entra>Scroll to pour, tap for a drop</p>
<p class="stato" data-entra>Carafe <span class="stato__parola" data-stato>empty</span></p>
</div>
</section>
<footer class="piede">
<p>Each Brimvale carafe holds 500 ml and is blown, cooled and polished in one small workshop.</p>
</footer>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.
25 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 sentence that fills with water on scroll” from Animorio and fit it into my siteThe sentence is in the SVG twice: once inside a clipPath, which masks the water, and once on top, with no fill and only a one-and-a-half pixel outline. The water is a path as wide as the drawing, from the surface down to the bottom: the mask only shows it inside the letters, so it rises line by line by itself.
Every frame the surface is redrawn every ten units: two waves running opposite ways, a third longer one for the slosh, the lean towards the pointer and the ripples of the drops, each a wave train that spreads and fades. The level comes from the scroll, eased a little.
The slosh follows the scroll speed on a spring, so it grows when you scroll fast and dies down when you stop; the lean follows the pointer on another spring, with a small overshoot. When nobody moves, a fake pointer sways on its own and now and then a drop falls.
The gauge has a tick every 25 ml and numbers every 100; the marker is a group that moves with the level. The word at the bottom changes with a small bounce, and once the carafe is full the waves calm down and the marker jumps.
| Name | File | Default | What it changes |
|---|---|---|---|
RIDE | script.js | 1 | How much scroll the pour takes: 2 is twice as long. |
FULL_AT | script.js | 0.9 | How far down the page the water reaches the top (0 to 1). |
WAVES | script.js | 1 | How much the surface sways on its own. |
SLOSH | script.js | 1 | How much a fast scroll makes the water slosh. |
TILT | script.js | 1 | How much the surface leans towards the pointer. |
BUBBLES | script.js | 12 | How many bubbles climb in the water. |
For the opening of a glassworks, a mineral water, a bar or a spa: a sentence that fills up as you read it, scrolling.
The same animation with adapted sizes: the drawing shrinks to the width and height of the page, the note at the top right is hidden and the drop falls where you tap.
Nothing moves and the scroll is not smoothed: the sentence is already full of water, the surface is still, no bubbles or drops, and the page fades in.
GSAP 3.15.0, ScrollTrigger 3.15.0, Lenis 1.3.26, Fraunces (font variabile) 5.3.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.9 KB; the libraries: GSAP + ScrollTrigger 45 KB, Lenis 5.3 KB.
Tested on 24 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.