
Stacking certificates
Hover, Images
NewFree
A tall pointed stained-glass window in a dim room. Where the pointer passes the sun shines through the panes, which light up in full colour with a small bounce and throw coloured light on the floor. A click lights the whole window in a wave from the centre.
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 stained-glass window that lights up</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/fraunces@5.3.0/wght-italic.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stanza" data-stanza>
<!-- the room: stone surround, sill and floor flags, drawn once by the script -->
<canvas class="strato" data-fondo aria-hidden="true"></canvas>
<!-- the warm wash the window throws on the walls -->
<div class="calore" data-calore aria-hidden="true"></div>
<!-- the coloured light on the floor: a small canvas, blurred, added on top with screen -->
<canvas class="strato strato--luce" data-pavimento aria-hidden="true"></canvas>
<!-- the window: panes of glass and lead came -->
<canvas class="strato" data-tela role="img" aria-label="A tall pointed stained-glass window with a rose and three tulips: the panes light up where the sun and the pointer pass, and throw coloured light on the floor"></canvas>
<!-- the glow around the lit panes and the dusty beams -->
<canvas class="strato strato--luce" data-alone aria-hidden="true"></canvas>
<header class="testata entra">
<p class="marchio">Hollin & Vane</p>
<p class="sotto">Glass studio and gallery</p>
</header>
<div class="luce entra" aria-live="polite">
<p class="luce__etichetta">In the light</p>
<p class="luce__riga"><span class="luce__nome" data-nome>Amber</span></p>
</div>
<div class="didascalia">
<h1 class="titolo entra">The Rose and Tulip Window</h1>
<p class="nota entra" data-nota>Move across the glass to let the sun through. Click and every pane lights up.</p>
</div>
<div class="buio" data-buio aria-hidden="true"></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.
30 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 stained glass that lights up” from Animorio and fit it into my siteThe script draws everything in window units: 1 wide, 2.45 tall. The outline is an equilateral arch (two arcs of radius 1 centred on the opposite springing point) plus the sides and the bottom, always in 64 points: so the outer outline and the inset one pair up point by point and the border panes are born between them. Rays, lozenges and backgrounds are clipped by the inner outline with Sutherland-Hodgman, which works because the pointed arch is convex. Petals and leaves are lenses, the rose is a disc, a crown and a button. Every pane becomes a Path2D, its centroid and a random tone between 0.86 and 1.08.
Every tick each pane works out how much light reaches it from three sources: the sun, a Gaussian bell 0.75 wide that GSAP carries back and forth in GIRO_SOLE seconds (yoyo, sine.inOut) along an arc; the pointer, a bell RAGGIO wide that turns on in 0.45 seconds when it enters and off in 1.4 when it leaves; the click wave. The three add up like real lights: 1 − (1 − a)(1 − b)(1 − c). The sun drops by 45% while the pointer is there, so the light that matters is yours.
No pane goes straight to its light: each has a spring with velocity. V += ((target − L) × RIGIDO − V × SMORZA) × dt and L += V × dt, with dt in sixtieths of a second (2 at most). With the starting values the spring is half damped: the pane lights up, goes a little past and comes back. Above 1 the colour mixes with white, so that small overshoot reads as a flash of sun in the glass.
The pane canvas is as big as the window, at full resolution: it fills the Path2Ds, multiplies the grain of blown glass (streaks and bubbles drawn once, clipped by the outline) and goes over the lead again. Glow and floor are quarter-resolution canvases, enlarged by CSS, blurred with filter: blur and added with mix-blend-mode: screen. On the floor every point of the glass goes into perspective: the top of the window lands closer to the viewer and wider, and the moving sun tilts the whole patch.
The click starts a GSAP timeline that takes the wave radius from −0.15 to 1.75 in ONDA seconds, waits 0.7 and fades it in 2.2. Each pane lights up with a smoothstep of its distance from the front, plus a Gaussian crest that fades near the edges. Ten times a second the script looks for the pane under the pointer (or under the sun) with a point-in-polygon test, from the last drawn to the first: if the name stays the same for two checks, the old one leaves upwards and the new one comes in from below with back.out, in the colour of its glass.
| Name | File | Default | What it changes |
|---|---|---|---|
RAGGIO | script.js | 0.42 | How wide the pointer's light is, in window widths. |
SOLE, GIRO_SOLE | script.js | 0.72, 12 | How much the passing sun lights up on its own, and in how many seconds it crosses the window. |
RIGIDO, SMORZA | script.js | 0.07, 0.2 | Each pane's spring: stiffer lights up sooner, less damped bounces more. |
ONDA | script.js | 1.7 | The seconds of the click wave, from the centre to the edges. |
MACCHIE, SFOCA | script.js | 0.9, 12 | How bright the patches on the floor are and how soft. |
--rubino, --cobalto, --ambra, --smeraldo, --viola, --opale, --notte | style.css | #d3233f, #2a5fd6, #f5a623, #1f9a5e, #7d48c0, #ecdfb6, #22358a | The seven glasses: the script reads them from the CSS, for panes, glow and floor. |
For the page of a stained-glass studio, a museum, a church or a place with a special light; and for any picture made of pieces (a logo, a mosaic) that should reward whoever passes over it.
Same animations, a window larger relative to the screen and higher up, so the floor has room. A dragged finger carries the light and it fades when the finger lifts; a tap starts the wave. The name of the glass moves to the top right.
The sun stands still and the panes do not bounce: the pointer's light comes and goes with a fade. The click lights the whole window at once in six tenths of a second, without a wave, and fades it slowly. The name of the glass changes with a fade.
GSAP 3.15.0, Mona Sans (font variabile) 5.3.0, Fraunces (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 11 KB; the libraries: GSAP 28 KB.
Tested on 11 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.