Skip to content
animorio
IT
Back to the library

The glass word

WebGL, 3D, Scroll, TextWebGL, GSAPAdvancedCompressed weight: Demo 9.0 KBGSAP + ScrollTrigger 45 KBThree.js + SVGLoader 190 KBFreeDownload the zip

Scroll inside the preview

A word in thick glass floats over a wall of brush strokes: through its curves the wall shows bent three times, once per colour, and as you scroll the glass melts back into the wall.

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 glass word</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
  <script type="importmap">
    { "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.178.0/build/three.module.min.js",
      "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.178.0/examples/jsm/"
    } }
  </script>
</head>
<body>
  <main>
    <!-- the opening: 220% of the screen tall, with a sticky stage; the word melts into the wall as you scroll -->
    <section class="opening" data-opening>
      <div class="stage" data-stage>
        <canvas class="canvas" data-canvas aria-hidden="true"></canvas>
        <p class="wait" data-wait>The glass is cooling</p>

        <header class="top">
          <p class="brand">Mirage</p>
          <p class="top__line">Digital studio</p>
        </header>
        <h1 class="sr">Mirage, a digital studio</h1>

        <p class="corner" data-corner>Interfaces, apps and brands built to hold up in the heat.</p>
        <p class="invite" data-invite>Scroll to discover</p>
      </div>
    </section>

    <section class="after">
      <h2 class="after__title">Solid on arrival. Invisible in use.</h2>
      <p class="after__text">We design and build interfaces that catch the eye in the first second and then step aside, so the work shows through.</p>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
  <script type="module" 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.

29 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 glass word” from Animorio and fit it into my site

What it does

A paper-coloured wall covered in light brush strokes and, in the middle, the word mirage in script, made of thick glass. It flies in from the right along a curve, turning as it comes, and settles. Then it floats, breathes a little and leans towards the pointer, and the light catching its edges turns with it. Through the glass you see the wall, bent by the curves and split into a faint rainbow at the edges; two photo-studio panels are reflected on the curves. As you scroll the word rises, tips back and melts into the wall, until only the paper is left.

How it works

The wall

The wall is painted once on a canvas a third of the screen’s size: 90 diagonal strokes from a seeded generator, light and dark, each a linear gradient. Stretched back over the screen, the third softens it by itself. It becomes a texture, and a quad covering the screen shows it by reading it at the pixel’s own position, gl_FragCoord divided by the resolution: so wall and glass line up to the pixel.

The word

The outline of mirage comes from Pacifico (SIL OFL licence), written as an SVG path in font units. SVGLoader turns it into shapes and ExtrudeGeometry extrudes them: depth 110, a 26 by 64 bevel in 8 steps. The bevel grows inwards, with bevelOffset equal to minus its width, so the script’s small counters stay open.

The glass

No physical material: a ShaderMaterial. For every pixel the refraction is computed three times, with indices 1.42, 1.45 and 1.48, one per channel: red bends least, blue most, and at the edges the colours part. The offset is 0.04 of the screen. Where the glass is thick the colour leans towards #bccbd2, the rim, (1 − N·V)^2.2, darkens towards ink, a raking light brightens the edges facing it and a narrow glint, (N·H)^90, makes the highlight.

Studio reflections

The view reflected on the normal reads two vertical panels and a light from above, drawn by a function rather than a photo; their edges are filtered with fwidth, so they stay soft even on the bevels. Each channel reads them 0.006 apart, a hint of prism. They weigh 0.5 times a fresnel that grows towards the edges, and a slow glint crawls over the curves.

Flight, float and scroll

The word sits in three nested groups: the first moved by scrolling, the second by the entrance, the third by the float. The entrance lasts 2.6 seconds of power3.out through three points, with sine.inOut between them, and turns from a crooked angle to straight. The pointer tilts it up to 0.16 radians and moves the light, with a lag that does not depend on the screen’s refresh rate. Scrolling arrives through an object scrubbed with a 0.6 second lag: from 35% to the end of the opening the glass mixes into the wall and disappears.

Values to change

NameFileDefaultWhat it changes
WORDscript.jsmirageThe word’s outline as an SVG path: to change it, export another word’s outline from the typeface you like.
DEPTH, BEVELscript.js110, 26 × 64How thick the glass is and how wide and deep the bevel, in font units (1000 = the type size).
IORscript.js1.42, 1.45, 1.48The refraction indices of red, green and blue: the further apart, the more rainbow on the edges.
BENDscript.js0.04How far the refraction moves the wall behind.
TINT, RIMscript.js#bccbd2The colour of thick glass and of the rim.
STUDIO, PRISMscript.js0.5, 0.006The strength of the reflected panels and how far apart their colours are.
FILLscript.js0.74How much of the screen width the word takes (0.92 on a phone).
MELTscript.js0.35, 1Between which points of the opening the glass melts into the wall.
STROKES, FLIGHTscript.js90, 2.6The brush strokes on the wall and the seconds of the entrance.

Try them in the Playground

When to use it

For the opening of a site that has to be remembered in its first second: a studio, a brand, a product with a short name. It works with a word or a symbol, not a sentence: glass wants thick, curved shapes.

On phones

The word takes 92% of the width instead of 74%, the line at the bottom spans the full width above the invitation to scroll, and the canvas lets the finger scroll through. The stage is as tall as the screen with the browser’s bars tucked away, and the lines at the bottom rise by the bars’ height.

With reduced motion

No flight, no float and no tilt: the word appears in 0.6 seconds already in place. The light still follows the pointer, and scrolling still lifts and melts the word, because the person scrolling drives it.

Pitfalls

  • A geometry’s translate() and scale() recompute its boundingBox in place: read it afterwards to measure and the word comes out tiny or huge. Copy the box first.
  • ExtrudeGeometry’s bevel grows outwards and closes a script’s small counters: with bevelOffset equal to minus bevelSize it grows inwards.
  • Wall and glass must read the same texture the same way, in screen coordinates: if the wall were a plane with its own uvs, you would see a step through the glass.
  • With a high curveSegments the script goes past 270,000 vertices; 8 are enough to keep the curves smooth.
  • A module with an importmap only starts once everything it imports has arrived: the waiting line lives in the HTML and disappears on the first drawn frame.

Libraries

Three.js 0.178.0, GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Mona Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 9.0 KB; the libraries: GSAP + ScrollTrigger 45 KB, Three.js + SVGLoader 190 KB.

Testing

Tested on 28 September 2026

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

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