Skip to content
animorio
IT
Back to the library

The stained glass that lights up

Hover, ImagesCanvas, GSAPMediumCompressed weight: Demo 11 KBGSAP 28 KBFreeDownload the zip

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.

The code

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 &amp; 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>

Playground

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

Or ask Claude Code for it

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 site

What it does

A dark room with a pointed window framed in stone: at the top a rose with petals, leaves and a two-coloured crown in a sky of blue rays, in the middle a net of lozenges in rings of colour, at the bottom three tulips; all around a border of small panes. Every piece has its black lead line and the grain of blown glass. At rest the panes are almost dark. Where the pointer passes the light shines through them: they light up in full colour with a spring that overshoots a little and comes back, a glow spreads around them, beams show in the dust, and on the floor every pane throws its own patch of colour, soft and stretched by perspective. On its own the sun slowly crosses from one side to the other and the patch on the floor tilts with it. Bottom right, the name of the glass in the light (Ruby, Cobalt, Amber...) changes with a small jump. A click lights the whole window in a wave from the centre, with a brighter crest on its front.

How it works

The window is made of polygons

The 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.

Three lights for every pane

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.

The spring in the glass

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.

Three canvases: panes, glow, floor

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 wave and the name of the glass

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.

Values to change

NameFileDefaultWhat it changes
RAGGIOscript.js0.42How wide the pointer's light is, in window widths.
SOLE, GIRO_SOLEscript.js0.72, 12How much the passing sun lights up on its own, and in how many seconds it crosses the window.
RIGIDO, SMORZAscript.js0.07, 0.2Each pane's spring: stiffer lights up sooner, less damped bounces more.
ONDAscript.js1.7The seconds of the click wave, from the centre to the edges.
MACCHIE, SFOCAscript.js0.9, 12How bright the patches on the floor are and how soft.
--rubino, --cobalto, --ambra, --smeraldo, --viola, --opale, --nottestyle.css#d3233f, #2a5fd6, #f5a623, #1f9a5e, #7d48c0, #ecdfb6, #22358aThe seven glasses: the script reads them from the CSS, for panes, glow and floor.

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

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.

Pitfalls

  • The glass grain must be multiplied only inside the outline (clip with the outline's Path2D): a canvas's white in multiply over a transparent background shows, and a white rectangle appears around the arch.
  • The spring's damping must be multiplied by dt and dt must be capped (here at 2): with one long frame an uncapped spring explodes and the panes flash.
  • Every full-resolution, full-screen canvas costs something every tick: the pane canvas is only as big as the window, and glow and floor are at a quarter, enlarged by CSS, which blurs them anyway.
  • The patches on the floor must be drawn in the same order as the panes and solid, not in lighter: the rose sits on top of the rays, and adding them up would turn the floor white where they overlap.

Libraries

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.

Testing

Tested on 11 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All animations