Skip to content
animorio
IT
All components

The paper notification

Notifications, 3D, TransitionsGSAP, CSS only, CanvasAdvancedCompressed weight: Demo 18 KBGSAP 28 KBFreeDownload the zip

The notification of a shared-documents app made of real paper, with its grain and a soft shadow. Dismissed, it does not vanish: it folds itself into a paper plane, fold after fold, and the plane flies away on a curve while its shadow falls behind on the page. The next notification arrives as a folded sheet and opens; under the pointer the nearest corner curls up.

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, viewport-fit=cover">
  <title>The paper notification</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/hanken-grotesk@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage>
    <!-- the notification of a shared-documents app, made of real paper. Dismissed (the cross, Esc, or a swipe
         sideways) it folds itself into a paper plane, fold after fold, and the plane flies away; the next one arrives
         as a folded sheet and opens. Open lifts the sheet towards you. The words are filled in by script.js, from
         MESSAGES; while it folds, the paper is drawn by copies of the card, cut along the creases and turned in 3D -->
    <canvas class="shadow" aria-hidden="true" data-shadow></canvas>
    <div class="note" data-note>
      <div class="note__mover" data-mover>
        <section class="card is-hidden" aria-label="Notification" data-card>
          <span class="card__face" aria-hidden="true" data-face></span>
          <span class="card__text">
            <span class="card__title" data-title></span>
            <span class="card__body" data-body></span>
          </span>
          <button class="card__open" type="button" data-open>Open</button>
          <button class="card__close" type="button" aria-label="Dismiss notification" data-close data-autoclic>
            <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 7l10 10M17 7L7 17"/></svg>
          </button>
        </section>
        <canvas class="cast" aria-hidden="true" data-cast></canvas>
        <div class="folds" aria-hidden="true" inert data-folds></div>
      </div>
      <p class="sr" role="status" aria-live="polite" aria-atomic="true" 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.

36 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 paper notification” from Animorio and fit it into my site

What it does

On a white background, alone in the middle, a notification 70 pixels tall made of ivory paper, with a fine grain, a few fibres and a soft shadow on the page: the initials MO on a sand-coloured round, Mira shared “Q4 roadmap”, You can edit · just now, the dark Open button and the cross. It arrives as a sheet folded in three, white like the back of a letter, which drops onto the page and opens: first the right third rises towards you and lies flat, then the left one, and as they turn the light changes on every face and the text shows in perspective. Two faint creases stay where it was folded. With the pointer over it, the nearest corner curls up a little towards you, with the light sliding along the curve and its shadow on the paper; coming closer to the corner lifts it more, and leaving lets it fall back with a small bounce. The cross, Esc or a sideways swipe dismiss it, and the paper folds into a plane in front of you: the left third and the right third close like a letter, the two front corners go to the middle line, then the new edges to the middle line again, the sheet closes in half lengthwise, the wings open and the plane turns to show them, lifts, pulls back a moment and sets off on a curve that climbs up and off the page, leaning into the turn, while its shadow falls behind and fades. Meanwhile the next notification arrives. Open makes another gesture: the sheet bends a little on the side of the button and lifts up towards you, bigger and bigger, while its shadow spreads, and then it is gone. When the page opens a first notification arrives by itself.

How it works

A small origami machine

The paper is a list of flat faces, each a piece of the notification cut along the creases made so far. A fold is a line on the paper as it lies at that moment, and the side to turn: every face the line crosses, on every layer, is cut in two (the cut is worked out where the face lies now, but the pieces are written in the coordinates of the flat notification), and the pieces on that side turn 180 degrees about the line. The axis lies half a paper's thickness above the stack (below it, for a fold backwards): a layer turned over lands on top of the others in the right order, as with real paper.

Every moment is a chain of turns

The folds are worked out once, all the way. Each piece remembers its folds as axes carried back onto the flat notification: the axis of a fold, as seen in the world once the folds before it are done, is carried back by the inverse of the turns the piece has already made. So any moment is just the product of that piece's turns (Rodrigues' formula), from the first to the last, at the angle GSAP has reached; folds may even overlap in time, and the plane's keel opens by 26 degrees simply by taking some angle off the fold in half.

DOM faces, sorted by hand

Each face is a copy of the notification (with no id, data- or aria- attributes, inside an inert holder), cut with the clip-path of its piece, grown by half a pixel on every side so that no seam is left between two pieces, and turned with a matrix3d. The holder has the perspective but no preserve-3d: the script decides the order. A face is in front of another when all its corners lie on the eye's side of the other's plane (or the other way round); the pairs that overlap on screen make a graph, and the faces come out from the farthest of the free ones.

Light, the back and the shadow

Each face has a veil: darker the further its normal turns from the lamp compared with the flat sheet, lighter as it turns towards it. The front or the back shows depending on the eye's side; the back is paper with the print barely showing through, and the outside of the folded letter is the back of the right third, turned over and so mirrored. The shadow lies on a canvas under the paper: every face is cast onto the page along the light, in three layers from the sharpest to the softest, and the higher it rises the further the shadow moves, spreads and fades.

The curling corner

The corner near the pointer is made of six strips, each hinged on the one before, with the curl growing towards the tip (up to CURL degrees) and a spring with a little bounce; the real notification is cut away right there. Each strip has a gradient from the light of the strip before to the light of the strip after, so the strips read as one curve, and a second canvas between the paper and the faces takes the corner's shadow on the paper itself.

The flight, the gestures and the keyboard

Once folded, the plane leans to show its wings, lifts and follows a cubic Bézier curve in 3D: the nose follows the tangent, climbs a little and leans into the turn as much as the heading changes. A sideways swipe past a third of the width (or a fast one) sends it off that way, with its nose folded towards that side. The buttons are real, with a visible focus; Esc dismisses, the focus stays on the cross for the next notification, and a role="status" line reads out every new one.

Values to change

NameFileDefaultWhat it changes
FOLDscript.js1.5The seconds the notification takes to fold itself into a paper plane.
FLIGHTscript.js1.2The seconds the plane takes to fly away.
UNFOLDscript.js0.85The seconds a new notification takes to arrive folded and open.
CURLscript.js80How far the corner by the pointer curls at most, in degrees: a third far from the corner, all of it close to it.
LIGHTscript.js0.8How much the light changes on a face as it turns: 0 none, 1 strong.
GRAINscript.js0.07The grain of the paper: 0 smooth, 0.2 rough.
KEELscript.js0.3How deep the plane's keel is, against half the height of the sheet: lower means wider wings.
DEPTHscript.js900How far away the eye is, in pixels: less looks deeper.
FIRSTscript.js0.4The seconds before the first notification arrives.
MESSAGESscript.jsquattro, da Mira Okafor “Q4 roadmap” a Jonas Weber “Hiring 2027”The shared documents, in turn: who, the document, the line under it and the colour behind the initials.

Try them in the Playground

When to use it

For a notification that brings something concrete, like a shared document, an invitation, a letter, and is closed with a gesture: a documents app, a mailbox, a workspace with a handmade touch. One notification at a time, with a line of title and one of detail; the folding takes a second and a half, so it suits places where notifications do not come in bursts.

On phones

The notification takes the width of the screen minus 32 pixels (358 at 390), and below 420 pixels the gaps and the title get a little narrower so that every word fits. A sideways swipe dismisses it: the plane has its nose towards that side and flies away that way, and the sheet comes back onto the screen a little as it folds. Holding a finger on the paper lifts the nearest corner; the cross has a touch area bigger than the drawn one.

With reduced motion

No folds, no flight and no curling corners: the notification fades in and out, with the cross, with Esc, with Open or with a swipe, and the next notification fades in. The grain, the shadow and the two faint creases stay.

Pitfalls

  • With the folds going backwards (the thirds behind the sheet) the paper went under the page: the shadow of the turning third climbed above the notification. Now the letter folds towards the viewer, with the print inside like a real letter, and the sheet arrives blank and opens to show the message; a point below the page casts its shadow as if it touched it.
  • The mirrored copy on the outside of the letter turned about its middle instead of its corner: it ended up outside its piece and the largest face of the folded sheet was transparent, with the shadow showing through. The copies in the faces all turn about their top left corner.
  • The clip-path that cuts away the lifted corner also takes the pointer away from the notification there: the corner rose, lost the pointer, fell back and started again. The pointer is now followed on the holder, which is not cut.
  • Growing the pieces towards their centroid barely grows the long sides of the corner's thin strips, and light lines were left between one strip and the next. Now every side moves out by half a pixel along its normal (with the corner limited on sharp tips).
  • Fading the folded sheet in face by face, the layers underneath showed through and the message folded inside could be read through the blank back. While it fades in only the top layer shows.
  • Seen from above a corner rising towards the eye hardly changes shape: at 26 degrees and in flat strips it read as a striped shading. It needed more angle at the tip, a continuous gradient across the strips and the corner's shadow on the paper.
  • With a paper one pixel thick the tips of the layers at the plane's nose drifted apart and the nose looked frayed; at 0.4 pixels the layer order holds and the nose is clean. And the back.in ease kept the plane still for almost half a second before it left: the throw has its own curve, with a short pull back.

Libraries

GSAP 3.15.0, Hanken Grotesk (font variabile) 5.3.0.

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

Testing

Tested on 6 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 components