Skip to content
animorio
IT
All components

The napkin menu

Menus, Physics, 3D, TransitionsCanvas, GSAPAdvancedCompressed weight: Demo 13 KBGSAP 28 KBFreeDownload the zip

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.

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 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>

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.

24 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 napkin menu” from Animorio and fit it into my site

What it does

On a white page there is a walnut button with «Menu» and a little zigzag pleat. Pressed, the button rises to the top, stretches into a polished rail and the pleat straightens into a line; «Menu» makes way for «Close». From behind the rail comes a cream linen napkin, folded like an accordion with the two red stripes of its hem zigzagging: the folds open under their own weight, the hem reaches the bottom with a whip and springs back, the cloth sways and settles with a few soft folds towards the bottom. On it are the links, Lunch, Dinner (the page you are on, in red italics), Wine list, Private dining and Book a table, in a serif typeface: they move, turn and are squeezed with the fold they sit on. Passing over it the cloth moves as under a hand, and the link pointed at grows bolder, turns red and sinks a little into the linen. Choosing one, the napkin gives a tug and is gathered up from the bottom like a Roman blind, fold after fold, disappears behind the rail and the button goes back to the middle. It also closes with Esc, with the button or by pressing outside.

How it works

A cloth of points

The 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).

Folded like an accordion

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

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.

Drawn in triangles

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.

The links on the cloth

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.

Gathered from the bottom

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.

Values to change

NameFileDefaultWhat it changes
DROPscript.js1500Gravity: how hard the napkin falls, in pixels per second squared.
STIFFscript.js0.9How firmly the linen holds its shape: 0.4 soft as silk, 1 stiff as canvas.
AIRscript.js1.5How much the air holds the cloth back: more and it settles sooner.
PLEATSscript.js6How many folds the napkin falls out of.
BREEZEscript.js1How strongly the pointer stirs the linen as it passes over it.
RISEscript.js0.55The seconds the button takes to rise and stretch into the rail.
LIFTscript.js0.8The seconds the napkin takes to be gathered back up.

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

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.

Pitfalls

  • The constraints that make the cloth stiff (a point with the one after its neighbour) are a tenth of their length while the napkin is folded: switched on at once, they blew the folds up over the rail. Now they switch on slowly as it falls, and they only push.
  • Without a spring towards the flat shape the folds got stuck on each other and the napkin stopped crumpled and askew, with the links unreadable: a simulated cloth does not know it was ironed.
  • Closing with the physics (the hem pulled up and the rest left to it) crumpled the cloth into a faceted ball: now the closing places every point, like a Roman blind.
  • The shadow on the page uses the trick of the shape drawn far away with its shadow sent back: the canvas blur filter does not exist in Safari. The offset is given in device pixels, and the shape must be built after the translate, not before.
  • The links wait at (0, 0) with no transform: until the napkin is there they must be kept transparent, or for an instant a word shows up in the corner.

Libraries

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.

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 components