Skip to content
animorio
IT
All components

The iris play button

Buttons, SVG, Hover, PhysicsCanvas, GSAPAdvancedCompressed weight: Demo 12 KBGSAP 28 KBFreeDownload the zip

A "Play trailer" button made like the diaphragm of a cine lens: nine metal blades closed in a spiral, turning on their pivots. With the pointer on it the iris opens a little on a film running behind, clicked it opens wide, play becomes pause and the landscape goes from dawn to night; closing, the blades turn back into their spiral.

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 iris play button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist-mono@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the button: round, with the diaphragm of a cine lens, and its label under it. The film behind the blades is
         drawn on a canvas, the blades, the ring and the play icon are an SVG the script builds and moves -->
    <div class="trailer" data-trailer>
      <div class="iris" data-iris>
        <button class="iris__btn" type="button" aria-label="Play trailer, 48 seconds" data-btn data-autoclic>
          <canvas class="iris__scene" data-scene aria-hidden="true"></canvas>
          <svg class="iris__art" viewBox="-136 -136 272 272" aria-hidden="true" data-art></svg>
          <svg class="iris__face" viewBox="-136 -136 272 272" aria-hidden="true" data-face></svg>
        </button>
      </div>

      <p class="trailer__label" aria-hidden="true">
        <span class="trailer__word" data-word>Play trailer</span>
        <span class="trailer__time" data-time></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.

16 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 iris play button” from Animorio and fit it into my site

What it does

On a black background a large round button: the ring of a lens, knurled at the edge, with the aperture numbers from 22 to 1.4 engraved and an amber mark at the top, and inside nine dark metal blades closed in a spiral, each over its neighbour and under the other, with a thread of light on its edge. On top, the play triangle; below, Play trailer and the running time. With the pointer on it the blades turn on their pivots and the iris opens into a round aperture, with a little bounce: behind it a film shows, mountains over a lake at sunset, with the sun glittering on the water, clouds drifting and a few birds; the ring turns with the blades and under the mark there is now 5.6. The light on the blades' edges follows the pointer. Clicking, the iris opens wide, the triangle splits into the two pause bars and the trailer rises from black: a whole day in a few seconds, from blue dawn to noon, to pink sunset, to night with stars, while an amber arc on the ring marks the progress and the time counts down. At the end the film goes back to black, the iris closes and instead of the pause a round arrow draws itself, with the label Watch again. Clicking during the trailer pauses it: the blades turn back into their spiral over the still frame and the label says Resume.

How it works

Blades with true geometry

Each blade turns on a pivot set on a circle under the ring (radius 104), and its cutting edge is the arc of a large circle (radius 144) whose centre lies 150 from the pivot. Turning the blade by an angle moves that circle; the opening is the space left inside all the circles. For an opening of radius a the centre must sit 144 − a from the middle, and the law of cosines gives the blade's angle: so the movement is a lens's, not a fake rotation.

One over the other, all the way round

In a real iris each blade lies over its neighbour and under the other, all the way round: with a normal drawing order one blade would stay on top of all. Here each blade is drawn only inside the next one's cutting circle (an SVG clipPath with that circle): where the next one covers it, it is not there. The geometry was checked point by point: for every opening and with 5 to 12 blades there is never a hole.

Metal, light and ring

Each blade has its own gradient, dark at the pivot and light towards the edge; the shadow it casts on the blade below and the thread of light on its edge are the same cutting circle drawn with different strokes. Each blade is turned its own way, so the light, which comes from the pointer and turns the short way round, catches some more than others. The ring with the numbers turns with the blades, 11 degrees a number: under the mark you read the true aperture.

The film on a canvas

Behind the blades a canvas draws the film every frame: sky, stars, the sun along its arc, clouds, three mountain ridges with their reflection in the lake, the sun's glitter on the water, the shore with pines and the birds; the camera pans slowly (DRIFT) and the film weaves a little in the projector, with grain on top. A day is a table of eight moments (the colour of the sky above and at the horizon, of the sun, of the shadows) blended with smoothstep: on hover it is always golden hour, while the trailer goes from dawn to night in its TRAILER seconds.

Spring, icon and states

The opening is a number on a spring (SPRING), integrated in steps of 1/240 of a second; at zero it stops with a small knock, like blades hitting home. The play icon is eight points in two quadrilaterals that become the two pause bars. The button has four states: at rest, playing, paused on the still frame, ended with the arrow to watch again; the label and the aria-label change with it.

Values to change

NameFileDefaultWhat it changes
BLADESscript.js9How many blades (from 5 to 12).
PEEKscript.js50How far the iris opens under the pointer: the radius of the opening, out of 96.
OPENscript.js80How far it opens while the trailer plays (96 is all the way: the blades vanish).
SPRINGscript.js[150, 15]The spring of the blades: stiffness and damping (lower, more bounce).
TRAILERscript.js48The seconds the pretend trailer lasts.
DRIFTscript.js0.006How fast the camera pans over the landscape.

Try them in the Playground

When to use it

For the button that starts a video where the video is the product: the trailer of a film or a series, a studio's showreel, the launch video of a camera or a festival. Instead of the drawn film goes a frame of the real video, drawn on the canvas.

On phones

The button narrows to three quarters of the screen. Without a pointer, holding a finger on the button opens the iris like hover and letting go starts the trailer; the film is drawn at density 2 at most.

With reduced motion

The blades do not turn: they go from closed to open with a fade, without the spring and without the half opening under the pointer. The film is still, with no pan, no weave and no grain, but the trailer still plays and the light changes slowly from dawn to night; play and pause change at once.

Pitfalls

  • With a normal drawing order the last blade stays on top of all and the iris looks like a fan: each blade must be clipped by the next one's circle, so each lies over one neighbour and under the other.
  • A stylesheet giving all the blades the same fill beats the SVG's fill attribute: each blade's gradient did not show. The script sets each blade's fill, and the CSS only gives the colours of the stops.
  • The light that follows the pointer is an angle: going from −179 to 179 degrees it took the long way round. It moves on the difference reduced between −π and π.
  • Redrawing the nine blades every frame while only the film moves is wasted work for the browser: blades, icon and film live in three separate layers, and the blades are redrawn only when they move or the light shifts.
  • The frame step is capped at 1/30 of a second and the spring integrated in steps of 1/240: after a tab in the background a jump in time flung the iris open past its edge.

Libraries

GSAP 3.15.0, Geist (font variabile) 5.3.0, Geist Mono (font variabile) 5.3.0.

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

Testing

Tested on 4 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