
The menu under the page
Menus, 3D, Physics, Transitions
NewFree
The menu of a trattoria as a linen napkin: pressing Menu, the button rises and stretches into a rail, and a napkin folded like an accordion drops from behind it, opens under its own weight, whips its hem, sways and settles. It is a real simulated cloth, and the links lie on it and bend with it.
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 napkin menu</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full-italic.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the menu of a trattoria as a linen napkin. At rest a dark Menu button with a folded pleat in it. Pressed, the
button rises and stretches into a rail, and a napkin folded like an accordion drops out from behind it: the
pleats fall open under their own weight, the cloth swings and settles, and the links ride on the linen -->
<div class="table" data-frame>
<canvas class="cloth" aria-hidden="true" data-cloth></canvas>
<nav class="napkin" id="napkin-menu" aria-label="Main" data-menu inert>
<ul class="napkin__list">
<li><a class="dish" href="#lunch" data-link>Lunch</a></li>
<li><a class="dish" href="#dinner" aria-current="page" data-link>Dinner</a></li>
<li><a class="dish" href="#wine" data-link>Wine list</a></li>
<li><a class="dish" href="#private" data-link>Private dining</a></li>
<li><a class="dish" href="#book" data-link>Book a table</a></li>
</ul>
</nav>
<button class="rail" type="button" aria-expanded="false" aria-controls="napkin-menu" data-toggle data-autoclic>
<span class="rail__words" aria-hidden="true">
<span class="rail__word" data-word-open>Menu</span>
<span class="rail__word" data-word-close>Close</span>
</span>
<svg class="rail__pleat" viewBox="0 0 26 14" aria-hidden="true">
<polyline data-pleat points="2,7 6,2.5 10,11.5 14,2.5 18,11.5 22,2.5 24,7"/>
</svg>
<span class="sr" data-toggle-name>Open the menu</span>
</button>
</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.
24 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 napkin menu” from Animorio and fit it into my siteThe napkin is a grid of 17 by 25 points in three dimensions, moved with Verlet integration (the velocity is the difference between the position now and the one before) in fixed steps of 1/120 of a second, with the gravity DROP and the air AIR holding it back. The top row is pinned to the rail. Eight times each step the constraints are put right: the distances along the threads, those across the diagonals and those from a point to the one after its neighbour, which give the linen its stiffness (STIFF).
When it opens the points start already folded: each row sits a little below the one before and forwards or backwards by just what keeps the thread the same length, so the folds (PLEATS) lie squashed on each other without pulling. The long constraints switch on slowly while the cloth falls, and they only push: they open a fold, they never pull it tight.
Ironed linen remembers being flat: after the drop a light spring brings every point back towards an almost flat shape, with a few soft folds that grow towards the hem. The passing pointer pushes the nearby points back in proportion to its speed (BREEZE), and the spring brings them home: the cloth moves under the hand and comes back by itself.
Every little square is two triangles: their normal says how much of the light from the top left they catch, and the colour goes from linen in shadow to linen in full light (or the back of it, when the triangle shows its back). They are painted from the farthest to the nearest, each one a hair bigger to leave no seams; on top the weave of the linen in multiply, the two red stripes of the hem drawn on the bent grid, and below a soft shadow on the page.
Every link is a real link. Each frame the matrix of the cloth under its middle is worked out, where the point goes and how the two threads stretch (the derivative of the projected grid), and written into its transform: the word moves, turns and is squeezed with the fold it sits on, darkens where the cloth is in shadow and disappears where the cloth shows its back.
When it closes the physics stops and every point is placed: a fold line climbs from the hem to the rail in LIFT seconds, the cloth below it lies in its pleats, the cloth above it still hangs; at the end the bundle slides behind the rail, which hides it because the drawing is cut at its height.
| Name | File | Default | What it changes |
|---|---|---|---|
DROP | script.js | 1500 | Gravity: how hard the napkin falls, in pixels per second squared. |
STIFF | script.js | 0.9 | How firmly the linen holds its shape: 0.4 soft as silk, 1 stiff as canvas. |
AIR | script.js | 1.5 | How much the air holds the cloth back: more and it settles sooner. |
PLEATS | script.js | 6 | How many folds the napkin falls out of. |
BREEZE | script.js | 1 | How strongly the pointer stirs the linen as it passes over it. |
RISE | script.js | 0.55 | The seconds the button takes to rise and stretch into the rail. |
LIFT | script.js | 0.8 | The seconds the napkin takes to be gathered back up. |
For the site of a restaurant, a trattoria, a bistro or a hotel restaurant, with a few links: the napkin tells at once where you are. It works at the top of the page, with room below to let it drop; with more than six links the cloth gets long.
The napkin narrows to the width of the screen and drops the same way; a tap opens, closes and chooses, and a finger moving over the cloth stirs it like the mouse.
No drop and no swaying cloth: the button goes to the top at once, the napkin fades in already hanging and fades out the same way when it closes. The links change colour and weight under the pointer as always.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 13 KB; the libraries: GSAP 28 KB.
Tested on 19 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.