
The cube stories
Stories, 3D, Transitions
NewFree
A menu folded into a little square of indigo washi: pressed, it lifts and unfolds in 3D face after face, first sideways and then down like an accordion, with its own light and shade on every face and the printed entries appearing as the faces lie flat. Closing, it folds back up into the square.
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 origami menu</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/shippori-mincho@5.3.0/500.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/zen-kaku-gothic-new@5.3.0/400.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/zen-kaku-gothic-new@5.3.0/700.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the menu: a little square of folded paper. Pressed, it unfolds in 3D one face after another, first sideways and
then down like an accordion, into a sheet with the menu printed on it. The box is as big as the open sheet, and
the folded square sits in its top right corner, where the paper hangs from. The script builds the paper from
the menu below, which lies over the open sheet: its links are the ones you press and reach with the Tab key -->
<div class="origami" data-origami>
<span class="origami__shadow" data-shadow aria-hidden="true"></span>
<div class="origami__stage" data-stage aria-hidden="true" inert></div>
<button class="origami__toggle" type="button" aria-expanded="false" aria-controls="menu" data-toggle data-autoclic>
<span class="sr" data-name>Open the menu</span>
<svg class="origami__glyph" viewBox="0 0 24 24" aria-hidden="true"><line x1="6" y1="9" x2="18" y2="9" data-line/><line x1="6" y1="15" x2="18" y2="15" data-line/></svg>
</button>
<nav class="sheet origami__nav" id="menu" aria-label="Main" data-nav inert>
<p class="sheet__head"><span class="seal" aria-hidden="true">紙</span>Menu</p>
<ul class="sheet__list">
<li><a class="leaf" href="#" data-leaf><svg class="leaf__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7.5 12 4l8 3.5-8 3.5z"/><path d="M4 12l8 3.5 8-3.5"/><path d="M4 16.5 12 20l8-3.5"/></svg><span class="leaf__name">Papers</span><span class="leaf__note">Washi, chiyogami and kraft</span></a></li>
<li><a class="leaf" href="#" data-leaf><svg class="leaf__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M3.5 13.5 12 4l8.5 9.5L12 20z"/><path d="M12 4v16M3.5 13.5h17"/></svg><span class="leaf__name">Workshops</span><span class="leaf__note">Fold with us on Saturdays</span></a></li>
<li><a class="leaf" href="#" data-leaf><svg class="leaf__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 6.5C10 5 7 4.5 4 5v13c3-.5 6 0 8 1.5 2-1.5 5-2 8-1.5V5c-3-.5-6 0-8 1.5z"/><path d="M12 6.5v13"/></svg><span class="leaf__name">Journal</span><span class="leaf__note">Notes on paper and patience</span></a></li>
<li><a class="leaf" href="#" data-leaf><svg class="leaf__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 9h16v11H4zM3 6h18v3H3zM12 6v14"/><path d="M12 6c-1.5-3-5-3-5-1s3.5 1 5 1c1.5 0 5 1 5-1s-3.5-2-5 1z"/></svg><span class="leaf__name">Gift sets</span><span class="leaf__note">Wrapped in furoshiki cloth</span></a></li>
<li><a class="leaf" href="#" data-leaf><svg class="leaf__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 21s-6.5-6.2-6.5-11a6.5 6.5 0 0 1 13 0c0 4.8-6.5 11-6.5 11z"/><circle cx="12" cy="10" r="2.3"/></svg><span class="leaf__name">Visit</span><span class="leaf__note">Our studio in Kyoto</span></a></li>
</ul>
</nav>
</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>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
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The origami menu” from Animorio and fit it into my siteThe sheet is a grid of 2 by ROWS faces, each an element placed with a matrix3d the script works out. A face’s matrix is the matrix of the face it hangs from, times a turn about the crease they share: a row hangs from the row above (rotateX about its top edge), the left face from the right one in the same row (rotateY about the middle crease). So a face carries along every face still folded onto it, like real paper.
Each crease between two rows has a number from 1 (folded) to 0 (open), and folds forwards and backwards in turn: shut, the rows lie stacked like an accordion. Rows lying flipped in the folded packet turn their left half the other way, so all the left halves open together as one layer. A GSAP timeline lifts the sheet, opens the middle crease and then the creases between the rows one after another, with back.out for the paper’s bounce; closing, the same timeline runs backwards.
The creases sit half a paper’s thickness (THICK, 2 pixels) off the sheet, on the side they fold to, and the middle crease sits in front of the whole stack: so the folded layers truly lie one over the other in the right order, instead of sharing a plane and flickering through each other.
Each face has two sides with backface-visibility: hidden, the printed inside and the indigo outside with waves. The face’s normal is the third column of its matrix; its dot product with the light’s direction says how much to lighten or darken each side (a light or dark veil over it), times LIGHT. A face lying flat towards the viewer has no veil: the open menu shows its true colours.
On the inside of every face there is a copy of the whole menu, moved so that the face shows its own piece of it. How open the way from a face to the corner is (the product of its creases) becomes --show, and that face’s entries rise and light up with it. Once the sheet is flat the paper gives way to the real menu, in the same place: its links are the ones you press and the Tab key reaches.
The box is as big as the open sheet and the little square sits in its top right corner: to have it in the middle of the page, folded the box is moved half a sheet left and down, and the timeline brings it back to its place while the sheet opens. There are at least ROWS faces down, and more if the menu’s last entry, measured at the sheet’s width, would not fit.
| Name | File | Default | What it changes |
|---|---|---|---|
OPEN | script.js | 1.6 | The seconds of the whole unfolding (folding back is a little quicker). |
CELL | script.js | 140 | The side of one face, in pixels: the sheet is two faces wide. |
ROWS | script.js | 3 | How many faces down the sheet has, at least: if the entries do not fit, the sheet takes more. |
TILT | script.js | [10, -14] | The degrees the sheet leans back and turns while it unfolds. |
LIGHT | script.js | 0.7 | How strong light and shade on the faces are. |
PEEK | script.js | 26 | The degrees the top layer lifts while the pointer is on the folded square. |
EASE | script.js | back.out(1.25) | How each face lands as it opens: a little bounce, like paper. |
For the site of anyone working with paper, a stationer, a design studio, a Japanese restaurant, a magazine: wherever the menu can be a little object. With five or six entries; for a long menu the sheet gets too tall.
The faces shrink so that the open sheet fits the screen minus 32 pixels, and the sheet is rebuilt at every change of width, keeping the point it had reached. A tap opens and closes; without a pointer the top layer does not lift.
No moving folds: the square and the open sheet swap in a fade, the lines become an X at once and the top layer does not lift.
GSAP 3.15.0, Shippori Mincho 5.3.0, Zen Kaku Gothic New 5.3.0.
Compressed with gzip, the three demo files weigh 9.8 KB; the libraries: GSAP 28 KB.
Tested on 4 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.