
The slide-to-confirm button
Buttons, Physics, Transitions
NewFree
The Freeze card button of a banking app: pressed, frost really grows over the card and the button from the corners, in branching crystals (diffusion limited aggregation), until everything is pale blue and opaque and says Card frozen. Pressed again, the ice melts from the point that was touched and leaves drops that slide down.
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>The freeze card button</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/manrope@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the freeze button of a banking app, under the card it freezes. Pressed, frost grows over the card and the
button from their corners in branching crystals (drawn in the canvas over both); pressed again, it melts from
where it was touched and runs down in drops -->
<div class="freeze" data-freeze>
<div class="card" data-card>
<div class="card__face" aria-hidden="true">
<svg class="card__chip" viewBox="0 0 40 30"><rect x="0.75" y="0.75" width="38.5" height="28.5" rx="6"/><path d="M0.75 10.5h11.5M0.75 19.5h11.5M27.75 10.5h11.5M27.75 19.5h11.5M12.25 0.75v28.5M27.75 0.75v28.5M12.25 15h15.5"/></svg>
<svg class="card__wave" viewBox="0 0 24 24"><path d="M8.5 8.2a5.5 5.5 0 0 1 0 7.6M12 5.6a9.2 9.2 0 0 1 0 12.8M15.5 3a13 13 0 0 1 0 18"/></svg>
</div>
</div>
<canvas class="freeze__frost" aria-hidden="true" data-frost></canvas>
<!-- the words of the card, over the frost so that they never go under it -->
<div class="card__words" data-words>
<span class="card__kind">Everyday debit</span>
<span class="card__name">Alex Morgan</span>
<span class="card__end"><span class="card__end-label">ending</span> 4821</span>
</div>
<button class="freeze__btn" type="button" aria-pressed="false" aria-describedby="freeze-live" data-btn data-autoclic></button>
<!-- the words of the button, over the frost too -->
<span class="freeze__label" aria-hidden="true" data-label>
<svg class="freeze__flake" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2.5v19M3.8 7.25l16.4 9.5M3.8 16.75l16.4-9.5M9.4 3.9L12 6.4l2.6-2.5M9.4 20.1L12 17.6l2.6 2.5M4.1 10.6l3.5-.9-.9-3.5M19.9 13.4l-3.5.9.9 3.5M6.7 17.8l.9-3.5-3.5-.9M17.3 6.2l-.9 3.5 3.5.9"/></svg>
<span class="freeze__words">
<span class="freeze__main" data-main>Freeze card</span>
<span class="freeze__sub" data-sub>Tap to unfreeze</span>
</span>
</span>
<p class="sr" id="freeze-live" aria-live="polite" data-live></p>
</div>
</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.
26 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 freeze card button” from Animorio and fit it into my siteThe card and the button lie on a grid of 2 pixel cells (160 by 139). Every cell knows whether it is on the card, on the button or outside (rounded rectangles), and has a smooth noise value for the patches of the frost and the uneven edge of the thaw.
When the page opens a diffusion limited aggregation runs: walkers start at random on the surface and wander until they touch the frost, and stick there with probability STICKY. To keep it quick a map of distances to the nearest crystal (updated around each cell that sticks) allows long jumps far from the ice; walkers stay on their own surface. It stops when the ice covers BRANCHES of the surface.
A breadth first walk through the crystal, from the six seeds, gives every crystal cell its distance along the branches: so each branch grows from its root to its tips. A second walk from all crystal cells gives the others the time of the nearest branch plus a delay that grows with distance: the haze comes in behind the branches. The animation is only a threshold T raised by GSAP: fast and reversible.
Every frame the grid is written into an ImageData: haze and crystals composited with their alpha, newborn tips in blue, then drawImage scales it up smoothly onto the canvas. The glow is the same picture shrunk and scaled up again, added in lighter mode. The words of the card and the button sit above the canvas and change colour before the frost reaches them, so they always stay readable.
Pressing again every cell gets a thaw time: distance from the touched point plus noise. A second threshold M moves out and erases the frost, leaving a wet film for a moment. Cells that were covered and have just melted give birth to drops: little bodies that stick and slip in fits, with their trail, down to the bottom edge of their surface, moved in requestAnimationFrame with the step capped at 1/30.
| Name | File | Default | What it changes |
|---|---|---|---|
FREEZE | script.js | 2.2 | The seconds the frost takes to cover the card. |
MELT | script.js | 1.6 | The seconds the thaw takes to cross it. |
BRANCHES | script.js | 0.3 | How much of the surface the crystals take before the haze fills in, from 0.1 to 0.45. |
STICKY | script.js | 0.55 | How readily a walker sticks to the frost: less, thicker and bushier crystals. |
HAZE | script.js | 0.78 | How opaque the frost gets. |
DROPS | script.js | 26 | The most drops of water running down at once. |
GLOW | script.js | 0.4 | The blue white glow of the crystals. |
For the switch that locks a card, an account, a subscription or an access: an important, reversible action, where the frozen state must show at a glance and unlocking should feel like a warm gesture.
Card and button are 320 pixels wide and fit a 390 pixel screen; below 360 everything shrinks a little. The canvas follows the screen's density (up to 2) and the thaw starts where the finger touched. A pressing finger brings the first frost into the corners like the mouse over it.
No growth and no drops: the full frost fades in over the card and the button, which say Card frozen; unfreezing, the frost fades away and the card turns warm again.
GSAP 3.15.0, Manrope (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 11 KB; the libraries: GSAP 28 KB.
Tested on 5 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.