
The menu under the page
Menus, 3D, Physics, Transitions
NewFree
The menu of a shop of handmade umbrellas as a real umbrella, in 3D: closed it is furled, its strap done up and a Menu tag hanging from the handle. Pressed, the strap lets go, the runner snaps up the shaft, the ribs spread and the canopy pulls taut panel by panel with a bounce; each panel carries a section printed on the fabric. Hovered, a panel puffs up and catches the light; chosen, it dips as if pressed and the umbrella closes, the cloth going slack between the ribs and the strap wrapping round it again.
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 umbrella menu</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/standard-italic.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the umbrella menu: a furled umbrella with its strap done up is the Menu button. Pressed, the strap lets go,
the runner snaps up the shaft, the ribs spread and the canopy pulls taut panel by panel; every panel is a
section of the shop. The whole umbrella is drawn in 3D on a canvas: ribs, stretchers, folds and light -->
<div class="brolly" data-brolly>
<canvas class="brolly__canvas" aria-hidden="true" data-canvas></canvas>
<button class="brolly__btn" type="button" aria-expanded="false" aria-controls="brolly-menu" data-btn data-autoclic>
<span class="sr" data-name>Open the menu</span>
</button>
<!-- the sections: real links, one for each panel of the canopy (the canvas draws them on the fabric) -->
<nav class="brolly__nav" id="brolly-menu" aria-label="Main" data-nav inert>
<ul>
<li><a href="#umbrellas" data-item>Umbrellas</a></li>
<li><a href="#parasols" data-item>Parasols</a></li>
<li><a href="#canes" data-item>Canes</a></li>
<li><a href="#repairs" data-item>Repairs</a></li>
<li><a href="#journal" data-item>Journal</a></li>
<li><a href="#gifts" data-item>Gifts</a></li>
<li><a href="#stores" data-item>Stores</a></li>
<li><a href="#about" data-item>About</a></li>
</ul>
</nav>
<p class="sr" aria-live="polite" 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>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.
30 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 umbrella menu” from Animorio and fit it into my siteThe umbrella is a real model: a shaft, eight ribs starting at the crown, the stretchers, the runner, the hooked handle. Every frame the script works out its points in three dimensions, turns them with Rodrigues’ formula from the furled pose (across the box) to the open one (towards you, tilted by TILT) and projects them in perspective. The facets of the cloth, the rods and the ribs go into one list sorted by depth and are painted from the back forwards.
The crown, the runner and the stretcher make a triangle: from the runner’s place on the shaft, by the law of cosines, comes the angle of the ribs. So moving the runner is enough: opening, it is pushed up (PUSH) to its catch, bounces off it (SNAP) and gives the ribs a knock; they have a bend on a spring and swing for a moment. Closing, a damped spring pulls it down.
Between two ribs the cloth is a surface of rows and columns. Each row has the fabric it gets in the open umbrella: if the gap between the ribs is shorter, the spare cloth makes a fold outwards, as deep as the triangle between cloth and gap says, with a ceiling (real folds are many and small); if the cloth is pulled past taut, it dips in a little. Each panel has a spring on its spare cloth (TAUT): opening, it goes to nothing one panel after another (STAGGER), its bounce making the canopy snap taut; closing, it goes slack again.
Every facet has its normal: in front it takes a diffuse light and a soft sheen, from inside it is darker with the light coming through the cloth. The shadow on the page is the umbrella’s silhouette drawn on a second canvas and pasted with shadowBlur and an offset. The sections are printed on the panels with an affine transform made from the panel’s directions at that spot, so they bend and shorten with the cloth, and a long word is narrowed to fit between the ribs.
Furled, the folds turn a little round the shaft and close into a spindle; the strap is a ring round the folds that, opening, unwinds and drops, and closing wraps round them again with a GSAP back.out. The tag is a pendulum hung from the handle: the handle’s acceleration swings it. When nothing moves the canvas is not redrawn.
The umbrella is a button with aria-expanded and aria-controls, laid over the furled umbrella and, open, over the brass tip. The sections are real links in a nav, inert while the umbrella is closed, that the canvas draws on the panels: the arrows, Home and End go from one to the next with an outline on the panel, Enter chooses, Escape closes and the focus goes back to the umbrella; an aria-live area reads out the section chosen. A tap on a panel puffs it up and, let go there, chooses it.
| Name | File | Default | What it changes |
|---|---|---|---|
OPEN_ANGLE | script.js | 76 | How far the ribs open at the crown, in degrees from the shaft. |
PUSH | script.js | 26 | How hard the runner is pushed up the shaft: more, a quicker snap. |
SNAP | script.js | 0.32 | How much of its speed the runner keeps bouncing off its catch. |
TAUT | script.js | [300, 0.3] | The spring of each panel pulling taut: stiffness, and damping (1 = no bounce). |
STAGGER | script.js | 0.045 | The seconds between one panel pulling taut and the next. |
LIFT | script.js | 16 | How far a panel puffs up under the pointer, in units of the drawing. |
TILT | script.js | 26 | How far the open umbrella leans back from facing you, in degrees. |
SPIN | script.js | 50 | How far the canopy turns round the shaft as it opens, in degrees. |
For the menu of a site with a crafted, playful character: a shop of umbrellas, accessories or clothing, a weather app, a seaside hotel, a design brand. Eight short sections, one per panel; long words get narrowed.
The whole drawing scales to the width of the screen (at 390 pixels the box is 358) and the open umbrella fits without spilling over. A tap on a panel puffs it up like the mouse over it, and letting go there chooses it; the brass tip and a tap outside close it.
No snaps, turns or bounces: the umbrella fades out and back in already open, or already furled with its strap, and the panel under the pointer brightens without puffing up.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Bricolage Grotesque (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 14 KB; the libraries: GSAP 28 KB.
Tested on 9 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.