Skip to content
animorio
IT
All components

The prism button

Buttons, WebGL, Physics, HoverWebGL, GSAPAdvancedCompressed weight: Demo 11 KBGSAP 28 KBFreeDownload the zip

The Upgrade to Pro button of a pricing page, on a black background: inside the pill a small glass prism opens a ray of white light into its spectrum, which runs across the pill and colours the words. It is real optics, worked out for sixteen wavelengths with Snell’s law, Cauchy’s index and Fresnel’s reflections, and drawn by a WebGL shader that adds the bands of colour together. The pointer turns the prism on a spring and the spectrum moves, opens and narrows; pressed, the prism spins, the spectrum sweeps the pill like a lighthouse and the words become Welcome to Pro.

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 prism button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/inter-tight@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the prism button: the Upgrade to Pro button of a pricing page. Inside the pill a small glass prism splits a ray
         of white light into its spectrum, worked out with Snell's law for sixteen wavelengths, and the colours light the
         words. The pointer turns the prism; pressed, it spins and the spectrum sweeps the whole pill -->
    <div class="pro" data-pro>
      <span class="pro__halo" aria-hidden="true" data-halo></span>
      <div class="pro__pill" data-pill>
        <canvas class="pro__canvas" aria-hidden="true" data-canvas></canvas>
        <button class="pro__btn" type="button" data-btn data-autoclic>
          <span class="pro__face" data-face="rest">Upgrade to Pro</span>
          <span class="pro__face" data-face="busy" aria-hidden="true">Upgrading</span>
          <span class="pro__face" data-face="done" aria-hidden="true">Welcome to Pro</span>
        </button>
      </div>
      <p class="pro__note" data-rise><span data-note>$12 a month, billed yearly · cancel anytime</span></p>
      <p class="sr" 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>

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.

20 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 prism button” from Animorio and fit it into my site

What it does

On a black background there is a dark pill with a thin edge. On its left, inside, a triangular glass prism with edges that catch the light; a white ray climbs from the bottom corner, goes into the prism (a small part is reflected off the first face and goes back up) and comes out opened into a fan of colours: red at the top, then orange, yellow, green, cyan, blue and violet. Near the prism the bands still overlap and the light is almost white; further right they separate. The fan crosses the words Upgrade to Pro, and the letters light up in the colours that hit them, far more than the dark floor round them; below, the line $12 a month, billed yearly · cancel anytime. Moving the mouse over the pill the prism turns towards the pointer on a spring, with a small wobble: on the left the spectrum rises and opens, on the right it drops and narrows, and the light grows a little stronger. Pressed, the pill sinks a touch, the prism starts spinning and the spectrum sweeps the whole pill like a lighthouse beam while the words say Upgrading and the line below Setting up your workspace. After a moment the prism slows and stops with a wobble on its next face, the words become Welcome to Pro, the spectrum opens wider and brighter and a halo of every colour lights up under the pill; the line says Pro is on · every feature unlocked. After a few seconds Upgrade to Pro comes back.

How it works

Sixteen rays with Snell’s law

Every frame in which the prism moves, the script follows sixteen rays, from violet at 409 nanometres to red at 691. For each one it finds the first face the ray meets, takes its normal and bends the ray with Snell’s law in vector form; inside the glass it finds the face it leaves by and bends it again. The index changes with the colour by Cauchy’s formula, n = INDEX + SPREAD / λ², higher for blue: that is why blue bends more and the colours separate. If a ray meets a face at a flatter angle than the critical one, the face acts as a mirror (total internal reflection) and the ray leaves by another.

Fresnel: how much light gets through

At each face part of the light is reflected, by Fresnel’s equations for unpolarised light (the mean of the two polarisations): what gets through is the light left in the ray, and what the first face reflects becomes a white ray going back, stronger when the light comes in at a grazing angle. For each colour the shader gets the entry point, the point of any bounce, the exit point and the direction, with the light left written into the length of the direction (two vec4 per ray: few uniforms, enough for phones too).

The colour of a wavelength

The colour of each ray comes from the CIE 1931 colour matching functions written as sums of skewed gaussians (Wyman, Sloan and Shirley), then from XYZ to linear sRGB, clipping the negative parts the screen cannot show. The sixteen colours are scaled so that all of them together make white: where the bands overlap, near the prism, the light is white again, and further on the rainbow opens, as in a real prism.

The shader adds the bands together

For each pixel the shader adds up the light of every ray: a band with a sharp core and a wide glow, which widens along its path and grows fainter in proportion, so the energy stays the same. The letters are a texture painted once (the three labels in the red, green and blue channels) and they take the light more than the floor does, like print under a beam. The prism has a faint tint and polished edges, lighter on the faces turned upwards; at the end a soft curve that never reaches flat white, and the gamma correction.

Rest, the spring and the lighthouse

At the start the script looks for the turn of minimum deviation, the classic position where the spectrum is tidiest, and the entry angle of the white ray that sends green through the middle of the words. The pointer adds up to TURN radians on a spring (STIFF and DAMP); pressed, the prism spins at SPIN turns a second for WAIT seconds and then the spring stops it on the next third of a turn, where a triangle looks just as before. The shader draws again only when something changes.

Values to change

NameFileDefaultWhat it changes
INDEXscript.js1.48The glass’s refractive index (Cauchy’s A): more, the light bends more.
SPREADscript.js0.032How strongly the index changes with the colour (Cauchy’s B, in square micrometres): more, a wider rainbow. Real glass stays under 0.01: here it is exaggerated so it shows.
TURNscript.js0.3How far the pointer can turn the prism, in radians each way.
STIFFscript.js70How hard the spring turns the prism to where the pointer wants it.
DAMPscript.js9How quickly the prism stops wobbling.
SPINscript.js1.4The turns per second of the prism while the upgrade goes through.
WAITscript.js1.6The seconds of the pretend upgrade.
DONEscript.js3.4The seconds the button says Welcome to Pro before it comes back by itself.
GAINscript.js1How bright the light is.

Try them in the Playground

When to use it

For the button that matters on a dark pricing page: Upgrade, Go Pro, Start free trial, Get early access. It works on its own, in the column of the recommended plan, or in the header of an app for creatives and developers; the prism says light and quality without any icon. Use it once a page: it is an effect that draws the eye.

On phones

The pill narrows to the width of the screen (at most 360 pixels) and the prism, the words and the spectrum are worked out again for its size. With no mouse a finger turns the prism while it touches and the spectrum follows; a tap presses the button. The canvas works at most at twice the screen’s density.

With reduced motion

The prism keeps still in its rest position: no spring, no turning towards the pointer and no spin on the press. The spectrum stays where it is; pressed, the words change with a fade, the light grows stronger, the spectrum opens without moving and the halo appears.

Pitfalls

  • With any entry angle the spectrum always came out low: a prism turns the light by at least its minimum deviation, about 47 degrees. The white ray has to climb, and the script finds by itself the angle that brings the spectrum onto the words.
  • Looking only for the turn that sends green onto the words, the script found a grazing exit: blue ended in total internal reflection and the colours arrived out of order. Rest is the minimum deviation, where the path through the glass is symmetrical.
  • The ray aimed at the centre of the prism went in near a corner and violet left by the wrong face: now it is aimed at the middle of the entry face.
  • The colour matching functions give colours outside the screen, with negative parts: clipped to zero and scaled so the sum is white, the overlapping bands are white again as they should be.
  • One uniform for each colour, point and intensity went over the 64 uniforms of phones: entry and bounce in one vec4, exit and direction in the other, and the intensity in the length of the direction.
  • The two labels, one going out and the other coming in at the same moment, showed one on top of the other: the old one goes out completely before the new one comes in.

Libraries

GSAP 3.15.0, Inter Tight (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 11 KB; the libraries: GSAP 28 KB.

Testing

Tested on 5 October 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 components