
Marquee that speeds up with scroll
Scroll, Text, Hover
Free
A minimal-style animated headline: a big word of ivory wax on warm white, with the volume, gloss and soft shadow of real wax. A small flame follows the pointer or the finger: near it the letters warm up, soften and slump, and slow drips run from their lower edges, stretch, let go and spread into pools on the ledge. Away from the flame the wax sets and slowly returns into the word.
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>Ember</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- a big word made of ivory wax on warm white: near the flame the letters soften, slump and drip slow drops that
pinch off and pool on the ledge below; away from the flame the wax sets again and keeps its drips -->
<main class="pagina" data-pagina>
<header class="testa">
<p class="marchio" data-entra>Ember</p>
<p class="stato" data-entra><span class="stato__nome">Wax</span> <span class="stato__valore" data-stato>set</span></p>
</header>
<h1 class="parola" data-parola>Ember</h1>
<svg class="scena" viewBox="0 0 1000 600" aria-hidden="true" data-scena>
<defs>
<!-- the wax: the drips melt into the letters (blur and alpha threshold), then a soft volume, a gloss that
follows the flame and a warm shadow on the paper -->
<filter id="cera" filterUnits="userSpaceOnUse" x="0" y="0" width="1000" height="600" color-interpolation-filters="sRGB">
<feGaussianBlur in="SourceGraphic" stdDeviation="2.2" result="sfocato" />
<feColorMatrix in="sfocato" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 22 -8" result="forma" />
<feGaussianBlur in="forma" stdDeviation="5" result="rilievo" />
<feDiffuseLighting in="rilievo" surfaceScale="3" diffuseConstant="1" lighting-color="#fff7ea" result="ombreggiato">
<feDistantLight azimuth="250" elevation="58" />
</feDiffuseLighting>
<feComposite in="forma" in2="ombreggiato" operator="arithmetic" k1="1.1" k2="0" k3="0" k4="0.035" result="volume" />
<feSpecularLighting in="rilievo" surfaceScale="5" specularConstant="0.9" specularExponent="20" lighting-color="#fff4de" result="lucido">
<fePointLight x="500" y="120" z="170" data-luce />
</feSpecularLighting>
<feComposite in="lucido" in2="forma" operator="in" result="lucidoDentro" />
<feComposite in="volume" in2="lucidoDentro" operator="arithmetic" k1="0" k2="1" k3="0.55" k4="0" result="cera" />
<feComposite in="cera" in2="forma" operator="in" result="ceraPulita" />
<feGaussianBlur in="forma" stdDeviation="9" result="ombraMolle" />
<feOffset in="ombraMolle" dx="0" dy="9" result="ombraGiu" />
<feFlood flood-color="#6e5334" flood-opacity="0.2" result="tinta" />
<feComposite in="tinta" in2="ombraGiu" operator="in" result="ombra" />
<feMerge>
<feMergeNode in="ombra" />
<feMergeNode in="ceraPulita" />
</feMerge>
</filter>
<linearGradient id="fiamma" x1="0" y1="1" x2="0" y2="0">
<stop offset="0" stop-color="#fff6dc" />
<stop offset="0.38" stop-color="#ffd27a" />
<stop offset="0.78" stop-color="#f29a3c" />
<stop offset="1" stop-color="#e2672a" />
</linearGradient>
<radialGradient id="alone">
<stop offset="0" stop-color="#ffb860" stop-opacity="0.42" />
<stop offset="0.45" stop-color="#ffb860" stop-opacity="0.12" />
<stop offset="1" stop-color="#ffb860" stop-opacity="0" />
</radialGradient>
</defs>
<path class="mensola" data-mensola d="M80 500 H920" />
<g filter="url(#cera)">
<g data-lettere></g>
<g data-colate></g>
</g>
<g class="fiamma" data-fiamma>
<circle r="120" fill="url(#alone)" data-alone />
<path fill="url(#fiamma)" data-lingua />
<path class="fiamma__cuore" data-cuore />
</g>
</svg>
<footer class="piede">
<p class="nota" data-entra data-nota>Bring the flame close to melt the wax</p>
<p class="nota nota--destra" data-entra>Hand-poured candles</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.
23 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 wax word that melts” from Animorio and fit it into my siteThe word is written in a canvas as large as the drawing (1000 by 600 units), one letter at a time, at the size that makes it 800 wide. For each column we look for the lowest point with wax at least 10 units thick: a drip can start there. The SVG letters are placed in the same spots, so drips start right from their edge.
Letters, drips, drops and pools sit in an SVG group with one filter: a blur and an alpha threshold weld them into a single mass (the drip’s neck blends into the letter by itself), then the same blurred shape is the height map for a diffuse light, which gives the volume, and for a point specular light, which is the gloss and sits on the flame. Below, a warm shadow, blurred and moved down.
Each letter has its own heat, which moves towards how close the flame is: it rises slowly and falls even more slowly. The heat drives Fraunces’ SOFT axis and weight, the tint from ivory to light amber and a spring that slumps the letter on the line; when the wax cools the spring brings it back straight with a one-unit settle.
Above a heat threshold, drips start at random in the columns near the flame, at least 22 units apart. Each runs down at a viscous speed that grows with heat and length; past its length the neck pinches in a third of a second and the drop falls with gravity, stretching, and becomes a pool on the ledge that spreads on a spring. The ledge bends where the drop lands and straightens again.
A drip that has been cold for RECAST seconds slowly retracts into the letter, and old pools shrink too: the demo can run for hours without the wax piling up. There are at most MAX_DRIPS drips.
The flame is a path redrawn every frame: it flickers on its own, and its tip lags behind the movement on a spring. It has a pale core, a wide amber glow and carries the gloss light with it. With no real pointer for more than 2.2 seconds, a fake flame passing along the word takes over.
| Name | File | Default | What it changes |
|---|---|---|---|
WORD | script.js | 'Ember' | The wax word: short, it fits on one line. |
WEIGHT | script.js | 600 | The weight of cold wax (Fraunces goes from 100 to 900). |
SWELL | script.js | 60 | How much weight a warm letter gains. |
HEAT_RADIUS | script.js | 200 | How far the flame’s heat reaches, in units of the 1000-wide drawing. |
MELT_SPEED | script.js | 1 | How fast the wax warms up and runs. |
DRIP_RATE | script.js | 0.5 | How many drips per second a warm letter starts. |
MAX_DRIPS | script.js | 12 | The most drips on the word at once. |
DROP_CHANCE | script.js | 0.5 | How often a long drip lets its drop fall (0 never, 1 always). |
FLAME_SIZE | script.js | 1 | The size of the flame. |
GLOSS | script.js | 0.55 | How much the wax gloss shines. |
RECAST | script.js | 6 | After how many seconds in the cold a drip returns into the letter (0 never). |
As the opening of a candle studio, a perfumery or fragrance house, a candlelit restaurant, a chocolate or pastry shop (the wax becomes icing), an autumn event; anywhere a single word should feel made of a real material and answer the warmth of the hand.
The same with a finger: dragging, the flame follows the finger, and without a finger it passes along the word on its own. The word fills 92% of the width and the scene is also sized on the height, so it fits the box. Over the demo the finger moves the flame instead of scrolling the page.
The wax word fades in already dripped, with five drips and a pool standing still; there is no flame, nothing moves and the state stays ‘set’.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 10 KB; the libraries: GSAP 28 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.