Skip to content
animorio
IT
Back to the library

The photo in three passes

Images, TransitionsGSAP, CanvasMediumCompressed weight: Demo 7.8 KBGSAP 28 KBFreeDownload the zip

In the minimal style: a photo print comes into colour in three passes, like in a dye-sublimation printer. A thin head runs down the white card three times and leaves the yellow, then the magenta, then the cyan, each ink a few pixels out of register until it snaps into place; a last clear pass makes it shine.

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 photo in three passes</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-flex@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <header class="top">
      <p class="mark">Dyeline</p>
      <p class="note">Proof</p>
    </header>

    <!-- a print card: a head runs down it three times, laying yellow, then magenta, then cyan, each ink a beat out
         of register until it settles; a last clear pass makes it shine. Click for the next print -->
    <section class="press" data-press>
      <figure class="card" data-card role="img">
        <div class="print" data-print>
          <canvas class="ink" data-ink="y" aria-hidden="true"></canvas>
          <canvas class="ink" data-ink="m" aria-hidden="true"></canvas>
          <canvas class="ink" data-ink="c" aria-hidden="true"></canvas>
          <div class="sheen" aria-hidden="true"><i class="sheen__band" data-band></i><i class="sheen__satin" data-satin></i></div>
          <i class="head" data-head aria-hidden="true"></i>
        </div>
      </figure>

      <ol class="passes" data-passes aria-hidden="true">
        <li class="pass">Yellow</li>
        <li class="pass">Magenta</li>
        <li class="pass">Cyan</li>
        <li class="pass">Coat</li>
      </ol>

      <p class="cap" data-cap aria-live="polite"><span class="cap__title" data-title></span><span class="cap__meta" data-meta></span></p>
    </section>
  </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.

23 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 photo in three passes” from Animorio and fit it into my site

What it does

A paper-coloured page with the name of a made-up photo printing lab, Dyeline, at the top left. A white card, blank, with a wide border, rises from below and settles one pixel past its place before it stops. Beside it there are four words one under the other, Yellow, Magenta, Cyan, Coat, thin and grey. Yellow takes its weight and a yellow line, a little wider than the print, runs down the card: where it has passed, the photo made only of yellow stays, very pale. Then the line turns magenta and runs down again, and the photo turns pink and orange; then cyan, and the photo reaches its true colours: three lemons on a blue cloth with a leaf. Every ink arrives out of register by two or three pixels, and at the edges of the photo a thread of the new colour shows for a moment; once the pass is over it slides into place on a spring. Last, Coat takes its weight: a grey line runs down with a band of light following it, and a soft satin sheen stays on the print. Under the print the title rises, Lemons on blue, with the size on the right. A moment later the print slides away upwards and a new card arrives: a pink ring floating in a pool, then a red door in a sunlit terracotta wall. A click on the print moves straight on to the next.

How it works

The photo split into three inks

The script draws the photo on a canvas and makes three separations of it: yellow keeps only the blue channel (the other two at 255), magenta only the green, cyan only the red. They are three canvases stacked with mix-blend-mode: multiply over white: multiplied, they give back the exact photo.

The head and the cut

Every ink has a number, r, from 0 to 1, saying how far it is printed: its canvas is cut with clip-path: inset(0 0 (1 − r) × 100% 0). The head is a two-pixel element that runs down on the same curve (sine.inOut) in the same time, so the edge of the ink is always exactly under it. The head is the colour it is printing.

Out of register, then in place

Every ink starts a few pixels off (OFF_REGISTER, in different directions for magenta and cyan), and near the end of the pass goes back to zero with elastic.out: at the edges a thread of colour shows and snaps into place, like in progressive print proofs.

The clear pass

The last pass has a grey head and a band of white light in screen mode riding just above it; meanwhile a very light diagonal sheen grows and stays on the finished print, like the gloss of dye-sublimation prints.

The words of the passes

Yellow, Magenta, Cyan and Coat are in Roboto Flex, a variable typeface with the wght and wdth axes. The word of the pass under way goes to weight 760 with elastic.out and narrows to width 92; the others go back to 300 and 118, grey. The whole sequence is one GSAP timeline per print.

Values to change

NameFileDefaultWhat it changes
PRINTSscript.js3 stampeThe prints, one after the other: the title and the small line under the card (the script draws the photos).
PASSscript.js1.25The seconds the head takes to run down the print.
GAP_BETWEENscript.js0.35The seconds between one pass and the next.
OFF_REGISTERscript.js3How many pixels each ink lands out of register before it snaps into place (0 = always in register).
HOLDscript.js2.2The seconds the finished print stays before the next one.

Try them in the Playground

When to use it

For those who print or sell prints: an online photo lab, the page of a printing service for photos or postcards, the page of a limited-edition print, the moment an order 'goes to print'. Also as the loading of a photo in a portfolio.

On phones

The same animation with the sizes adapted: the card is almost as wide as the screen and the four words sit in a row underneath, smaller. A tap on the print moves on to the next.

With reduced motion

Nothing runs down and nothing slides: the prints are already finished and one gives way to the next with a fade.

Pitfalls

  • Without isolation, the multiply of the three separations would also multiply the colour of the page's paper and the photo would come out warmer and darker: the print box has isolation: isolate and its own white background.
  • The band of light of the clear pass, full and wide, looked like fog on the photo: it is at 26% and rides just above the head, in screen mode.

Libraries

GSAP 3.15.0, Roboto Flex (font variabile) 5.3.0.

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

Testing

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