
The dinosaur-bitten logo
Intro, SVG, Text
NewFree
A logo’s entrance at the theatre: someone moves behind the red velvet curtain, a gloved hand drums its fingers through the gap, the curtain opens gathering its folds, a spotlight searches the dark stage and finds the logo, the footlights come on one by one and the logo takes a bow among confetti and roses. In the Playground you type your own name or upload your own logo.
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 theatre-curtain logo</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bodoni-moda@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="scena">
<!-- the theatre: the script measures it, builds the stage around the logo and draws the curtain every frame -->
<svg class="palco" data-stage role="img" aria-label="Bravessa" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- one pleat of velvet: dark in the folds, a soft sheen on the crest -->
<linearGradient id="pleat" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" class="velluto-fondo" />
<stop offset="0.3" class="velluto-pieno" />
<stop offset="0.52" class="velluto-lume" />
<stop offset="0.74" class="velluto-pieno" />
<stop offset="1" class="velluto-fondo" />
</linearGradient>
<!-- the shade over the curtain: dark under the pelmet, lighter in the middle, dark again at the hem -->
<linearGradient id="pleat-shade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="ombra" stop-opacity="0.55" />
<stop offset="0.22" class="ombra" stop-opacity="0" />
<stop offset="0.8" class="ombra" stop-opacity="0" />
<stop offset="1" class="ombra" stop-opacity="0.35" />
</linearGradient>
<!-- the swags of the pelmet -->
<linearGradient id="swag" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="velluto-fondo" />
<stop offset="0.55" class="velluto-pieno" />
<stop offset="0.85" class="velluto-lume" />
<stop offset="1" class="velluto-pieno" />
</linearGradient>
<!-- gilded wood: the frame of the stage and the trim of the apron -->
<linearGradient id="gilt" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" class="oro-lume" />
<stop offset="0.35" class="oro-pieno" />
<stop offset="0.6" class="oro-fondo" />
<stop offset="0.8" class="oro-pieno" />
<stop offset="1" class="oro-lume" />
</linearGradient>
<linearGradient id="gilt-bar" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="oro-lume" />
<stop offset="0.5" class="oro-pieno" />
<stop offset="1" class="oro-fondo" />
</linearGradient>
<!-- where something pushes the velvet from behind, it catches the light -->
<radialGradient id="bulge">
<stop offset="0" class="velluto-lume" stop-opacity="0.75" />
<stop offset="1" class="velluto-lume" stop-opacity="0" />
</radialGradient>
<!-- the hole the spotlight makes in the dark, soft at its edge -->
<radialGradient id="spot-hole">
<stop offset="0" stop-color="#000" />
<stop offset="0.72" stop-color="#000" />
<stop offset="1" stop-color="#fff" />
</radialGradient>
<!-- the warm pool of the spotlight -->
<radialGradient id="spot-pool">
<stop offset="0" class="luce" stop-opacity="0.24" />
<stop offset="0.7" class="luce" stop-opacity="0.13" />
<stop offset="1" class="luce" stop-opacity="0" />
</radialGradient>
<!-- the beam: strong at the lens, thin by the time it reaches the stage -->
<linearGradient id="beam" gradientUnits="userSpaceOnUse" data-beam-fill>
<stop offset="0" class="luce" stop-opacity="0.5" />
<stop offset="1" class="luce" stop-opacity="0.1" />
</linearGradient>
<!-- the footlights wash the stage from below -->
<linearGradient id="wash" x1="0" y1="1" x2="0" y2="0">
<stop offset="0" class="ribalta" stop-opacity="0.55" />
<stop offset="0.5" class="ribalta" stop-opacity="0.12" />
<stop offset="1" class="ribalta" stop-opacity="0" />
</linearGradient>
<linearGradient id="backdrop" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="fondale-alto" />
<stop offset="1" class="fondale" />
</linearGradient>
<!-- the logo goes a little darker while it bows, turned away from the light -->
<filter id="dim" color-interpolation-filters="sRGB">
<feComponentTransfer data-dim>
<feFuncR type="linear" slope="1" />
<feFuncG type="linear" slope="1" />
<feFuncB type="linear" slope="1" />
</feComponentTransfer>
</filter>
<!-- everything on the stage stays inside the opening -->
<clipPath id="opening" clipPathUnits="userSpaceOnUse"><rect data-opening /></clipPath>
<!-- the dark on the stage, with the hole of the spotlight in it -->
<mask id="dark-mask" maskUnits="userSpaceOnUse" data-dark-mask>
<rect fill="#fff" data-dark-full />
<ellipse fill="url(#spot-hole)" data-hole />
</mask>
<!-- the dust only shows inside the beam -->
<clipPath id="beam-clip" clipPathUnits="userSpaceOnUse"><path data-beam-clip /></clipPath>
<!-- a tassel: the point where the cord hangs is 0 0 -->
<g id="t-tassel">
<path class="nappa-cordone" d="M0 0L0 11" />
<path class="nappa" d="M-6 10C-7.5 15 -8.5 20 -7.5 24L7.5 24C8.5 20 7.5 15 6 10Z" />
<ellipse class="nappa" cx="0" cy="10" rx="6" ry="3.4" />
<path class="nappa-lucido" d="M-3.4 13.5Q-4.6 18 -3.6 21.5" />
<rect class="nappa-fascia" x="-8.8" y="23" width="17.6" height="5.4" rx="2.2" />
<path class="nappa" d="M-8 28.4L-11.5 53Q0 57.5 11.5 53L8 28.4Z" />
<path class="nappa-fili" d="M-5 31L-7.6 53.4M-1.8 31L-2.6 55.2M1.8 31L2.6 55.2M5 31L7.6 53.4" />
</g>
<!-- a footlight: a pear of glass on a brass screw, with its filament; the middle of the base is 0 0 -->
<g id="t-bulb">
<path class="vetro" d="M-5 -9C-5 -13 -10 -16 -10 -24C-10 -31 -5.5 -35 0 -35C5.5 -35 10 -31 10 -24C10 -16 5 -13 5 -9Z" />
<path class="vetro-acceso" data-glass-on d="M-5 -9C-5 -13 -10 -16 -10 -24C-10 -31 -5.5 -35 0 -35C5.5 -35 10 -31 10 -24C10 -16 5 -13 5 -9Z" />
<path class="supporto" d="M-2.4 -9L-3.6 -22M2.4 -9L3.6 -22" />
<path class="filamento" d="M-3.6 -22L-2.4 -25L-1.2 -22L0 -25L1.2 -22L2.4 -25L3.6 -22" />
<path class="filamento-acceso" data-wire-on d="M-3.6 -22L-2.4 -25L-1.2 -22L0 -25L1.2 -22L2.4 -25L3.6 -22" />
<path class="riflesso-vetro" d="M-6.4 -26Q-6.6 -30.5 -3 -32.4" />
<path class="zoccolo" d="M-6 -9.5L6 -9.5L6 -1L3.4 1.6L-3.4 1.6L-6 -1Z" />
<path class="zoccolo-righe" d="M-6 -6.8L6 -7.8M-6 -3.6L6 -4.6" />
</g>
<!-- a rose: the middle of the flower is 0 0, the stem hangs down -->
<g id="t-rose">
<path class="stelo-bordo" d="M0 8C2 30 -2 52 1 78" />
<path class="stelo" d="M0 8C2 30 -2 52 1 78" />
<path class="spina" d="M1.4 29L6 25.6L1.8 33.4ZM-0.4 53L-5 49.6L-0.9 57.4Z" />
<path class="foglia" d="M1 46C7 37 18 36 23 40C17 48 8 50 1 46Z" />
<path class="venatura" d="M2.5 45.4Q12 41.5 21 40.2" />
<path class="foglia" d="M-10 8.6L-3.4 4.4L0 9.6L3.4 4.4L10 8.6L4.6 13L0 10.6L-4.6 13Z" />
<path class="rosa" d="M-14.5 -2C-16.5 -12 -8.5 -19.5 0 -18.5C8.5 -19.5 16.5 -12 14.5 -2C12.5 6 6.5 10.5 0 10.5C-6.5 10.5 -12.5 6 -14.5 -2Z" />
<path class="rosa-cuore" d="M-8.5 -5.5C-9 -12 -3 -14.5 2 -13C7 -11.4 8 -5.4 4 -2C0.6 0.6 -4.4 -1 -3.6 -5C-3 -8 1.6 -8.4 2.4 -5.4" />
<path class="rosa-piega" d="M-14.5 -2C-10 2.6 -4.4 4.4 0 3.4M14.5 -2C10 2.6 4.4 4.4 0 3.4M-11 -12.5C-8 -9 -8.6 -5 -8.5 -5.5" />
<path class="rosa-lucido" d="M-10.5 -11Q-6.6 -15.6 -1 -15.6" />
</g>
</defs>
<rect class="sala" data-house />
<!-- the stage, seen through the opening -->
<g clip-path="url(#opening)">
<g data-set></g>
<ellipse class="ombra-logo" data-logo-shadow />
<g data-logo></g>
<rect class="buio" mask="url(#dark-mask)" data-dark />
<ellipse fill="url(#spot-pool)" class="schermo" data-pool />
<g class="pulviscolo" clip-path="url(#beam-clip)" data-motes></g>
<!-- the curtain: the left half, the gloved hand that comes out of the gap, the right half on top -->
<g data-curtain-left></g>
<g data-hand>
<g data-finger><path class="guanto" d="M4 -17L-21.75 -17A4.25 4.25 0 0 0 -21.75 -8.5L4 -8.5Z" /><path class="guanto-piega" d="M-10.6 -15Q-11.8 -12.75 -10.6 -10.5" /></g>
<g data-finger><path class="guanto" d="M4 -8.5L-24.75 -8.5A4.25 4.25 0 0 0 -24.75 0L4 0Z" /><path class="guanto-piega" d="M-12 -6.5Q-13.2 -4.25 -12 -2" /></g>
<g data-finger><path class="guanto" d="M4 0L-22.75 0A4.25 4.25 0 0 0 -22.75 8.5L4 8.5Z" /><path class="guanto-piega" d="M-11 2Q-12.2 4.25 -11 6.5" /></g>
<g data-finger><path class="guanto" d="M4 8.5L-17.75 8.5A4.25 4.25 0 0 0 -17.75 17L4 17Z" /><path class="guanto-piega" d="M-8.4 10.5Q-9.6 12.75 -8.4 15" /></g>
</g>
<g data-curtain-right></g>
<g data-floor-fx></g>
<g data-pelmet></g>
<rect class="buio" data-house-dim />
<rect fill="url(#wash)" class="schermo" data-wash />
<path fill="url(#beam)" class="schermo" data-beam />
</g>
<!-- the gilded frame, its shell, and the spotlight hanging from it -->
<g data-frame></g>
<g data-lamp>
<path class="staffa-bordo" d="M-27 6L-27 -16L27 -16L27 6" />
<path class="staffa" d="M-27 6L-27 -16L27 -16L27 6" />
<g data-barrel>
<path class="lampada" d="M-15 -20L-11 -28L11 -28L15 -20Z" />
<rect class="lampada" x="-21" y="-21" width="42" height="69" rx="6" />
<path class="alette" d="M-21 -11L21 -11M-21 -4L21 -4M-21 3L21 3" />
<path class="lampada-lucido" d="M-13.5 -15L-13.5 41" />
<rect class="ghiera" x="-24.5" y="46" width="49" height="12" rx="3" />
<ellipse class="lente" cx="0" cy="60" rx="18" ry="5" />
<ellipse class="lente-accesa" cx="0" cy="60" rx="18" ry="5" data-lens-on />
</g>
<circle class="pomello" cx="-27" cy="0" r="5" />
<circle class="pomello" cx="27" cy="0" r="5" />
</g>
<!-- the apron and the footlights -->
<g data-apron></g>
<g data-bulbs></g>
<!-- confetti and roses, over everything -->
<g data-fly></g>
</svg>
<p class="nota">Click or tap to see it again</p>
</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.
46 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 theatre-curtain logo” from Animorio and fit it into my siteThe stage is an SVG whose viewBox is as big as the window, so one unit is one pixel. The frame is worked out from the window (on a tall screen the opening becomes upright), then the letters are measured on a canvas in the same typeface (measureText, actualBoundingBoxAscent for the true height) and the logo takes the size that fits on the boards without touching the pelmet. Everything else, the circle of light, the roses, the confetti, the bulbs, comes from these two measures.
Each half of the curtain is a row of pleats: strips with a horizontal gradient (dark in the hollow, shiny on the crest) and the dark outline, plus a second strip with the vertical shade. The edges of the pleats are shared, so a gap never opens, and they are worked out again every frame from one state object: how open it is, how far the hem trails, the breathing of the velvet and the bulge of someone pushing from behind. As it opens, the place of each pleat follows a power that grows with the opening: the pleats near the side squeeze up more, like gathered cloth.
The hem is a row of arcs, one per pleat. The braid is a gold stroke along the arcs; the threads of the fringe are many vertical segments starting from the arc, worked out again with the pleats, so they stay straight even when the pleats are tight. On the swags of the pelmet, which do not move, the threads are instead a wide dashed stroke along the curve. The tassels are a single drawing in the defs, copied where needed: each one turns around the point where its cord hangs, worked out with getBBox.
The light is an object with the centre and the radii of the circle and how bright it is. The dark on the stage is a rectangle with a mask: inside it there is an ellipse with a radial gradient, black in the middle and white at the edge, the soft hole of the light. The beam starts from both sides of the lens and reaches the two points where it touches the ellipse (where the tangent is parallel to the direction of the lamp), going round the far side; the same path is the clipPath of the dust, which only shows in the light. The lamp turns on its yoke towards the circle with a rotate worked out from atan2.
Each letter bends from its foot (transformOrigin at the bottom) with a stagger that starts from the middle: a breath, down, a pause and up with elastic.out. While it is bent the logo goes under a feComponentTransfer filter whose slope is lowered, so it darkens a little without turning see-through. The confetti are rectangles that fall spinning and flutter with scaleX back and forth; the roses are a drawing in the defs, thrown from below in an arc and laid down with a little hop.
The whole story is one timeline, with timeScale for the speed; its onUpdate draws the curtain, the light, the hand and the dust again once per frame, after every tween has moved. At the end the lights go down, the curtain closes and the scene is rebuilt from the «arrive» label, with a new path for the light and new confetti. If IMAGE holds an address, the logo becomes that picture, a single piece that bows all at once. In the Playground, next to the field, there is a button to upload a file from your computer, which goes into the code as a data: address.
| Name | File | Default | What it changes |
|---|---|---|---|
NAME | script.js | 'Bravessa' | The logo as a word: every letter bows a moment after the one in the middle. |
IMAGE | script.js | '' | The logo as a picture: the address of a file, or upload it from your computer. If there is one, it takes the place of the word. |
SPOT | script.js | 1 | How wide the spotlight’s circle is around the logo, and so the beam: 0.7 tight, 1.6 generous. |
CONFETTI | script.js | 60 | How many confetti fall at the bow. |
BOW | script.js | 1 | How deep the logo bows: 0 stands still, 1.6 is a deep bow. |
ROSES | script.js | 3 | How many roses the audience throws on the stage. |
SPEED | script.js | 1 | The speed of the whole show: 2 is twice as fast, 0.5 half as fast. |
REST | script.js | 5 | How many seconds the logo stays in the light before the curtain closes. |
LOOP | script.js | true | Whether the curtain closes and the show starts again. With false the logo stays in the light for good, with the spotlight swaying. |
To present a logo with a little ceremony: a preview for a client, the opening of the site of a theatre, a festival, a company or a venue, a product launch, a presentation video, a social post. It works with a written wordmark and with a picture.
The same show, with the sizes adapted: on a tall screen the opening becomes upright, there are fewer, wider pleats, the logo stands lower on the boards and the beam is longer. A tap restarts it.
Nothing moves: the closed curtain fades away leaving the dark stage, then the light appears on the logo, then the footlights fade on and the roses and confetti appear, already lying on the boards. If the show starts again, the curtain fades back in.
GSAP 3.15.0, Bodoni Moda (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 18 KB; the libraries: GSAP 28 KB.
Tested on 10 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.