
The cookie banner
Consent, Transitions, SVG, Physics
NewFree
The share dialog for an architecture studio’s drawings, drawn the way a sheet is drawn: four blue construction lines come in from the edges of the screen like the rules of a drafting machine, swing on springs and stop where the sides will be, the pen inks the outline and the paper fills in with a hatch that thickens until its lines meet. Inviting someone runs the bottom rule out again and down to the new size while the person is drafted into the list, in a square with their own hatched material; copying the link draws its dimension line underneath, marked Copied.
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 drafted share dialog</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jost@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the drafted share dialog: Share draws the dialog the way an architect draws a sheet. Blue construction lines
slide in like the rules of a drafting machine and spring into place, the outline is inked along them, the
paper fills in with a hatch, and the words come last. A new collaborator is drafted into the list the same
way, and a copied link gets its dimension line. -->
<span class="slot" data-slot data-autoclic>
<button class="opener" type="button" aria-haspopup="dialog" data-open>
<svg class="opener__icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="9.5" cy="8" r="3.6"/><path d="M3.2 19.5c.7-3.4 3.2-5.4 6.3-5.4 1.7 0 3.2.6 4.3 1.6M18.2 13.2v6.6M14.9 16.5h6.6"/></svg>
<span>Share</span>
</button>
<span class="slot__ticks" aria-hidden="true"></span>
</span>
</main>
<dialog class="share" aria-modal="true" aria-labelledby="share-title" aria-describedby="share-sub" data-dialog>
<div class="share__veil" data-veil></div>
<div class="frame" data-frame>
<div class="frame__shade" data-shade></div>
<div class="frame__paper" data-paper></div>
<div class="frame__body" tabindex="-1" data-body>
<header class="head" data-part>
<div class="head__text">
<h2 class="head__title" id="share-title">Share “Casa Albera”</h2>
<p class="head__sub" id="share-sub">Schematic design, 14 drawings</p>
</div>
<button class="close" type="button" aria-label="Close" data-close>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></svg>
</button>
</header>
<form class="invite" novalidate data-invite data-part>
<label class="label" for="invite-email">Invite people</label>
<div class="invite__row">
<input class="field invite__email" id="invite-email" type="email" inputmode="email" autocomplete="off" spellcheck="false" placeholder="Email address" aria-describedby="invite-note" data-email>
<span class="select invite__role">
<label class="sr" for="invite-role">Permission</label>
<select class="field" id="invite-role" data-role>
<option value="view">Can view</option>
<option value="edit">Can edit</option>
</select>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10l5 5 5-5"/></svg>
</span>
<button class="btn btn--ink invite__send" type="submit" disabled data-send>Invite</button>
</div>
<p class="note" id="invite-note" data-note>They get an email with a link to the drawings.</p>
</form>
<section class="people" aria-labelledby="people-title">
<h3 class="label" id="people-title" data-part>People with access</h3>
<ul class="people__list" data-list>
<li class="person" data-part data-email="marta@orsa.studio">
<span class="avatar mat-brick" aria-hidden="true"><span class="avatar__fill"></span><span class="avatar__ini">MF</span></span>
<span class="person__text"><span class="person__name">Marta Ferrante (you)</span><span class="person__mail">marta@orsa.studio</span></span>
<span class="person__owner">Owner</span>
</li>
<li class="person" data-part data-email="jonas@orsa.studio">
<span class="avatar mat-steel" aria-hidden="true"><span class="avatar__fill"></span><span class="avatar__ini">JL</span></span>
<span class="person__text"><span class="person__name">Jonas Lindqvist</span><span class="person__mail">jonas@orsa.studio</span></span>
<span class="select select--quiet">
<label class="sr" for="role-jonas">Permission for Jonas Lindqvist</label>
<select class="field" id="role-jonas" data-person-role>
<option value="view">Can view</option>
<option value="edit" selected>Can edit</option>
<option value="remove">Remove access</option>
</select>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10l5 5 5-5"/></svg>
</span>
</li>
<li class="person" data-part data-email="priya@greywater.eng">
<span class="avatar mat-timber" aria-hidden="true"><span class="avatar__fill"></span><span class="avatar__ini">PR</span></span>
<span class="person__text"><span class="person__name">Priya Raman</span><span class="person__mail">priya@greywater.eng</span></span>
<span class="select select--quiet">
<label class="sr" for="role-priya">Permission for Priya Raman</label>
<select class="field" id="role-priya" data-person-role>
<option value="view" selected>Can view</option>
<option value="edit">Can edit</option>
<option value="remove">Remove access</option>
</select>
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10l5 5 5-5"/></svg>
</span>
</li>
</ul>
</section>
<section class="link" data-part data-link-part>
<label class="label" for="share-link">Link to the drawings</label>
<div class="link__row">
<input class="field link__url" id="share-link" type="text" readonly value="orsa.studio/p/casa-albera" data-link>
<button class="btn btn--line link__copy" type="button" data-copy>
<span class="link__icons" aria-hidden="true">
<svg class="link__chain" viewBox="0 0 24 24" data-chain><path d="M10 14a4.2 4.2 0 0 0 6 0l3-3a4.2 4.2 0 0 0-6-6l-1.1 1.1M14 10a4.2 4.2 0 0 0-6 0l-3 3a4.2 4.2 0 0 0 6 6l1.1-1.1"/></svg>
<svg class="link__tick" viewBox="0 0 24 24" data-tick><path d="M5 12.6l4.4 4.4L19 7.4"/></svg>
</span>
<span data-copy-label>Copy link</span>
</button>
</div>
<div class="link__foot">
<p class="note" data-hint>Anyone with this link can view.</p>
<svg class="dim" aria-hidden="true" data-dim></svg>
</div>
</section>
<p class="sr" aria-live="polite" data-live></p>
</div>
</div>
<svg class="draft" aria-hidden="true" data-draft></svg>
</dialog>
<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.
57 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 drafted share dialog” from Animorio and fit it into my siteThe four construction lines are lines in an SVG as big as the dialog element, and each has its own distance from the side it belongs to: a damped spring, x'' = −ω²x − 2ζω·x', in steps of 1/240 of a second on GSAP’s ticker, with the step limited to 1/30. They start just off the screen on their own side, with ω = 12/DRAFT and ζ = 1 − 0.7·BOUNCE, so they go past and come back; the vertical ones leave 0.06 seconds later. While they run they are as long as the screen; then a second value, from 0 to 1, shortens them to OVERSHOOT pixels past the corners.
The four graphite sides are four more lines, each growing from its own corner, clockwise, all together with the same progress: top from the left, right from the top, bottom from the right, left from the bottom. Each side is half its width longer at both ends, so the corners close without dots. Everything is redrawn at every frame from the dialog’s real measures, and when nothing moves nothing is redrawn.
The paper is a repeating-linear-gradient at 135 degrees with a 10 pixel period, white from 0 to calc(var(--fill) · 10px) and transparent after: GSAP takes --fill from 0 to 1, the white lines thicken until they touch and the paper is solid. Once done, a class swaps it for plain white, because a repeating gradient can leave a hairline seam. The words come in afterwards, one after the other, once the paper is closed.
The dialog’s top is fixed when it opens, so an extra row makes it grow downwards only. Inviting, the height goes from the old one to the new with back.out(1.7) and the link section slides from the same distance with the same curve, so it stays with the bottom edge; the bottom rule runs out as long as the screen for a little over half a second. Meanwhile the new person’s square is drafted in its own SVG with the same function as the dialog, small: rules coming in from 12 pixels, sides inked, the material uncovered by a triangle clip-path widening diagonally, the initials last.
Copying, the link’s width is measured on a canvas with the field’s font, from the first letter to the last, in whole pixels. Underneath, an SVG draws the dimension: the word Copied in the middle, the two strokes of the line running from it to the ends by animating x2, the extension lines dropping by animating y2 and the 45-degree ticks growing from their middle with back.out. The link is copied with navigator.clipboard and, where it is missing, by selecting the field and with execCommand.
It is a native dialog opened with showModal (the page behind is out of reach) with aria-modal, aria-labelledby and aria-describedby; the focus goes to the email field for who uses the keys and to the sheet for a finger or the mouse, Tab goes round the dialog’s controls without leaving, Escape stops the cancel event and closes it with its drawing, and at the end the focus goes back to Share. Every field has its label, the confirmations go through an aria-live region, the error through aria-invalid and aria-describedby too. A click from a script on the button’s frame (the library’s preview) makes a plain round, open and close, and a full one, open, type an address and invite it, copy and close; closing puts everything back as it was, and it goes by the state, not by a fixed list.
| Name | File | Default | What it changes |
|---|---|---|---|
DRAFT | script.js | 0.8 | The seconds the dialog takes to be drafted: rules, outline, paper and words. |
BOUNCE | script.js | 0.6 | How far the rules swing past their place before they settle, from 0 to 1. |
OVERSHOOT | script.js | 28 | How far the blue construction lines run past the corners, in pixels. |
PUT_AWAY | script.js | 0.42 | The seconds the dialog takes to be rubbed out. |
DIM | script.js | 0.24 | How dark the page goes behind the dialog, from 0 to 1. |
HOLD | script.js | 2.4 | The seconds Copied stays under the link. |
For sharing a project, a folder, a sheet or a document with other people in a work tool: an architecture or design studio, a drawing program, a file archive. The drafting suits products that talk about measures and plans; without the gesture, what is left is a complete, accessible share dialog.
At 390 pixels the dialog is 358 wide, 16 pixels from the sides, and the crossings shorten so they do not touch the edge of the screen. The address has a line of its own, the permission and Invite go under it; the permission column narrows to leave room for the names, and Copy link keeps only its icon (the words stay for screen readers) so the whole link can be read. The fields are 16 pixels, so Safari does not zoom the page, and the close button is 44 tall. With many people the dialog reaches the height of the screen and scrolls inside.
No running rules, no outline being drawn, no hatch: the Share button fades and the dialog appears already drawn with a fade, and leaves the same way. The invited person appears with a fade and the dialog takes its new size at once; the link’s dimension appears already drawn; a wrong field turns red without shaking and the buttons do not squash.
GSAP 3.15.0, Jost (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 16 KB; the libraries: GSAP 28 KB.
Tested on 7 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.