
The liquid glass button
Buttons, WebGL, Hover, Physics
NewFree
The week's weather in a small valley town, seen through the glass of an oak window: behind it the town out of focus with its lit windows; on the glass real raindrops, which merge, slide in fits and starts and leave a trail, and each one is a small lens that shows the town sharp and upside down. Choosing a day the weather on the glass changes: the wind drives the drops sideways, the sun dries them, the snow freezes them and grows frost from the edges, the storm flashes. On the inside the glass mists up, and a finger wipes a strip of it clear.
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 weather behind the glass</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>
<main class="stage">
<!-- the week's weather in a small valley town, seen through the pane of an oak window: behind the glass the town,
out of focus, drawn by the script; on the glass real raindrops, which merge, slide and leave their trails, and
every drop is a small lens that shows the town upside down and sharp. The sun dries them, the snow puts frost
on the edges and a drift on the sill, the wind drives them sideways, the storm flashes. The day and the
temperatures are burnt into the frame; a brass plate slides under the day chosen. A finger, or the mouse held
down, wipes a clear strip in the mist on the inside of the glass -->
<section class="window" aria-label="Weather in Ashcombe" data-window data-autoclic>
<span class="window__wood window__wood--top" aria-hidden="true"></span>
<span class="window__wood window__wood--left" aria-hidden="true"></span>
<span class="window__wood window__wood--right" aria-hidden="true"></span>
<span class="window__wood window__wood--bottom" aria-hidden="true"></span>
<span class="window__flash" aria-hidden="true" data-flash></span>
<header class="head">
<div class="head__where">
<h2 class="head__place">Ashcombe</h2>
<p class="head__note"><span class="swap" data-note></span></p>
</div>
<p class="head__temp">
<span class="head__num" aria-hidden="true" data-temp></span><span class="head__deg" aria-hidden="true">°</span>
<span class="head__low" aria-hidden="true"><span class="swap" data-low></span></span>
<span class="sr" data-temp-sr></span>
</p>
</header>
<div class="pane" data-pane>
<canvas class="pane__glass" aria-hidden="true" data-glass></canvas>
<span class="pane__bead" aria-hidden="true"></span>
</div>
<div class="days" role="radiogroup" aria-label="Day" data-days>
<span class="days__plate" aria-hidden="true" data-plate></span>
</div>
<p class="sr" aria-live="polite" data-live></p>
</section>
</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.
67 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 weather behind the glass” from Animorio and fit it into my siteThe town behind the glass is painted on a canvas, always the same (one seed for the hills, the houses, the church tower, the trees and the lamps) in the light of the day's weather: sky, clouds, haze on the hills, windows lit or with the sky in them, snow on the roofs, a low sun. It is wider than the glass by 30 pixels a side, for the lenses near the edge. Under the sharp copy sits the out-of-focus one, made by halving the canvas four times and enlarging it again. Changing day, the new town is painted on the other canvas and the shader fades one into the other.
Each drop has a position, a radius and a threshold of its own: they land at random, when two touch they become one with the volume of both (the radius is the cube root of the sum of the cubes) and the centre nearer the bigger one. Over its threshold a drop slides, faster the more it is over, but the glass holds it in fits and starts, more often when it is only just heavy enough; it wavers a little as it finds its way, swallows the droplets it meets, leaves one behind now and then and loses its water. The fine droplets sit on a layer of their own that slowly dries. The time step is at most 1/30 of a second.
Every frame each drop is drawn on a canvas as a small dome, adding up (lighter), so two drops close together melt into one shape. Green holds the outline, the same for all, so a fixed level is the edge; red holds the height, which grows with the radius, so the slope at a given point of the dome is the same for a small drop and a big one; blue holds how big it is, so the droplets get only a faint rim. Moving drops stretch out the way they run and three smaller domes behind them become the tail.
The shader reads the map: from the slope (four readings round the point) times the height it works out how far to bend the view, towards the middle of the drop and past it, so the town inside is small, sharp and upside down. The same slope gives the normal: a dark rim, a crescent of light below, a glint at the top left. Outside the drops the town is as blurred as the glass is misted; in front of it go the far rain in lines and the flakes, worked out in the shader, which the drops turn upside down too. Then the milky mist with its grain, the frost, the drift on the sill and a reflection of the room.
The mist is a small grey canvas that every frame leans towards its aim (thicker at the bottom and in the corners); the finger draws on another canvas, which turns white again much more slowly: the mist you see is the product of the two, so new weather comes quickly but the wiped strip stays. The frost is worked out only once: ferns of ice growing from the edges with branches at sixty degrees, and every little piece keeps in red the moment the frost reaches it; the shader shows the frost up to a time that grows on a snowy day.
The days are a group of choices (arrows, Home and End); the weather on the glass turns to the new day with GSAP tweens on its values (rain, wind, mist, frost, ice, sun, drift). A click from a script on the window (the library's preview) makes the round: a finger wipes the mist, then wind, snow, sun and storm, and back to today. When it does not rain and nothing moves (after the sun) the drawing stops. Without WebGL the same simulation is drawn on a 2D canvas: the town out of focus, every drop a piece of the sharp town clipped and flipped, the mist and the frost over it.
| Name | File | Default | What it changes |
|---|---|---|---|
DAYS | script.js | [['Today', 'rain', 11, 7, 'Rain all afternoon'], …] | The days: the name on the frame, the weather (rain, wind, snow, sun or storm), the high, the low and a line about it. |
CHANGE | script.js | 1.6 | The seconds the weather on the glass takes to turn. |
RAIN | script.js | 1 | How hard it rains on the glass: 0 never, 2 twice as hard. |
DROP_SIZE | script.js | 1 | How big the drops are when they land. |
SLIDE | script.js | 1 | How readily the heavy drops slide down. |
LENS | script.js | 1 | How strongly each drop bends the town behind it: 0 no lens. |
MIST | script.js | 1 | How much the inside of the glass mists up: 0 never. |
WIPE | script.js | 34 | How wide the strip a finger wipes, in pixels. |
FROST | script.js | 1 | How far the frost grows in from the edges on a snowy day. |
For the site of a holiday cottage, a mountain hut, a farm stay or a mountain hotel (the weather you will see from the window), for a town's weather app, for a home screen widget or a weather station, and in general for a forecast you want to feel, not only read.
The window is 380 pixels wide and on a phone it narrows to the screen (358 on a 390 screen), always 424 tall; the high is a little smaller. The days are tapped with a finger. On the glass a finger wipes the mist: there the page does not scroll (touch-action none), on the wood above and below it does. The canvas is drawn at a density of 2 at most, the drops and the mist at a density of 1.
The drops do not move: for each day the glass is worked out at once, out of sight (three seconds of its rain, then everything still), and the old town fades into the new one in 0.45 seconds. No rain or flakes falling behind, no lightning, no moving entrance: the window fades in. A finger still wipes the mist, which does not come back; when nothing changes the canvas is not drawn again.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 23 KB; the libraries: GSAP 28 KB.
Tested on 17 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.