
The origami-unfolding logo
Intro, SVG, Transitions
NewFree
The opening of a portfolio: a drawn little figure walks onto the black screen pushing a white panel in three pushes and uncovers the name in red; then the white slides down and the name stays still while it is wiped away.
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 panel pushed by hand</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- the opening of a made-up designer's portfolio. On a black screen a little figure walks in from the left pushing
a white panel in front of it, in three pushes, and the panel uncovers the name in red; then the white panel
slides down off the screen, the name drifts up, and the home page is underneath -->
<main class="pagina">
<header class="testata">
<p class="firma">KAI VERO<sup>®</sup></p>
<nav class="voci" aria-label="Main">
<a href="#">Work</a>
<a href="#">About</a>
<a href="#">Playground</a>
<a href="#">Contact</a>
</nav>
<a class="scrivi" href="#">hello@kaivero.studio</a>
</header>
<section class="eroe">
<p class="eroe__sopra">Independent designer & art director</p>
<h1 class="eroe__titolo">Interfaces with<br>a sense of humour.</h1>
<p class="eroe__sotto">Selected work, 2019 to now</p>
</section>
<ul class="lavori" aria-label="Selected work">
<li class="lavoro" style="--tinta: #ff4b3e">Paper Moons</li>
<li class="lavoro" style="--tinta: #1d1d1d">Low Tide Records</li>
<li class="lavoro" style="--tinta: #3b5bdb">Field Notes Co.</li>
<li class="lavoro" style="--tinta: #f2b705">Sunday Ferry</li>
</ul>
</main>
<div class="sipario" data-sipario aria-hidden="true">
<div class="sipario__bianco"></div>
<p class="sipario__nome" data-nome>Kai<br>Vero</p>
<div class="sipario__nero" data-nero></div>
<div class="spinta" data-spinta>
<svg class="omino" data-omino viewBox="0 0 240 262" aria-hidden="true">
<defs>
<!-- the dots of the cap and the socks, and the flowers of the shirt -->
<pattern id="puntini" width="3.6" height="3.6" patternUnits="userSpaceOnUse">
<circle cx="1.2" cy="1.2" r=".75" fill="currentColor"/>
</pattern>
<pattern id="fiori" width="24" height="24" patternUnits="userSpaceOnUse" patternTransform="rotate(-18)">
<g fill="#ffffff" stroke="currentColor" stroke-width=".9">
<circle cx="6" cy="3.4" r="2.6"/><circle cx="8.6" cy="5.4" r="2.6"/><circle cx="7.6" cy="8.4" r="2.6"/>
<circle cx="4.4" cy="8.4" r="2.6"/><circle cx="3.4" cy="5.4" r="2.6"/>
</g>
<circle cx="6" cy="6.2" r="1.3" fill="currentColor"/>
<g fill="#ffffff" stroke="currentColor" stroke-width=".8">
<circle cx="18" cy="15.6" r="1.8"/><circle cx="19.8" cy="17" r="1.8"/><circle cx="19.1" cy="19" r="1.8"/>
<circle cx="16.9" cy="19" r="1.8"/><circle cx="16.2" cy="17" r="1.8"/>
</g>
<circle cx="18" cy="17.4" r=".9" fill="currentColor"/>
</pattern>
<clipPath id="taglio-maglia">
<path d="M86 178 C82 150 102 112 132 96 C140 92 148 90 154 90 L168 94 C172 104 170 128 154 156 C146 170 136 178 126 182 C112 188 94 186 86 178 Z"/>
</clipPath>
</defs>
<g fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round">
<!-- the far leg: the thigh in the shorts turns at the hip, the shin with sock and shoe turns at the knee -->
<g class="gamba gamba--dietro">
<g data-coscia="dietro">
<path class="arto" d="M0 22 L0 40"/><path class="arto-dentro" d="M0 22 L0 40"/>
<path class="calzoni" d="M-14 -8 C-6 -12 8 -12 14 -6 C15 4 14 14 12 23 C6 27 -6 27 -11 23 C-14 14 -15 4 -14 -8 Z"/>
<path class="dettaglio" d="M-11 19 C-5 22 5 22 11 19"/>
<path class="dettaglio" d="M6 -2 L4 12"/>
</g>
<g data-stinco="dietro">
<path class="arto" d="M0 0 L0 26"/><path class="arto-dentro" d="M0 0 L0 26"/>
<path class="dettaglio" d="M-3 3 C0 6 3 5 4 2"/>
<rect class="calzino" x="-8.5" y="22" width="17" height="16" rx="4"/>
<rect class="puntinato" x="-8.5" y="22" width="17" height="16" rx="4"/>
<path class="dettaglio" d="M-8.5 27 L8.5 27 M-8.5 30 L8.5 30"/>
<g data-scarpa="dietro" transform="translate(0 40)">
<path class="scarpa" d="M-9 -7 C-9 -12 3 -13 7 -9 L17 -3 C24 0 24 6 18 7 L-11 7 C-15 7 -15 -3 -9 -7 Z"/>
<path class="suola" d="M-13 5 L22 5 C23 8 21 10 19 10 L-11 10 C-14 10 -15 7 -13 5 Z"/>
<path class="dettaglio" d="M-1 -10 L5 -6 M2 -11 L8 -7 M5 -11 L10 -7"/>
<path class="dettaglio" d="M-8 -1 C0 -4 8 -1 13 3"/>
<path class="dettaglio" d="M15 -2 C18 -1 20 1 21 4"/>
</g>
</g>
</g>
<!-- the far arm, behind the body -->
<g class="braccio--dietro">
<path class="arto" d="M146 108 L182 114 L218 108"/><path class="arto-dentro" d="M146 108 L182 114 L218 108"/>
<path class="mano" d="M216 98 C220 94 228 94 230 100 L231 116 C231 121 224 122 219 117 L214 110 C211 106 212 101 216 98 Z"/>
<path class="dettaglio" d="M224 101 L231 101 M224 106 L231 106 M224 111 L231 111"/>
</g>
<!-- the near leg: the thigh in the shorts turns at the hip, the shin with sock and shoe turns at the knee -->
<g class="gamba gamba--avanti">
<g data-coscia="avanti">
<path class="arto" d="M0 22 L0 40"/><path class="arto-dentro" d="M0 22 L0 40"/>
<path class="calzoni" d="M-14 -8 C-6 -12 8 -12 14 -6 C15 4 14 14 12 23 C6 27 -6 27 -11 23 C-14 14 -15 4 -14 -8 Z"/>
<path class="dettaglio" d="M-11 19 C-5 22 5 22 11 19"/>
<path class="dettaglio" d="M6 -2 L4 12"/>
</g>
<g data-stinco="avanti">
<path class="arto" d="M0 0 L0 26"/><path class="arto-dentro" d="M0 0 L0 26"/>
<path class="dettaglio" d="M-3 3 C0 6 3 5 4 2"/>
<rect class="calzino" x="-8.5" y="22" width="17" height="16" rx="4"/>
<rect class="puntinato" x="-8.5" y="22" width="17" height="16" rx="4"/>
<path class="dettaglio" d="M-8.5 27 L8.5 27 M-8.5 30 L8.5 30"/>
<g data-scarpa="avanti" transform="translate(0 40)">
<path class="scarpa" d="M-9 -7 C-9 -12 3 -13 7 -9 L17 -3 C24 0 24 6 18 7 L-11 7 C-15 7 -15 -3 -9 -7 Z"/>
<path class="suola" d="M-13 5 L22 5 C23 8 21 10 19 10 L-11 10 C-14 10 -15 7 -13 5 Z"/>
<path class="dettaglio" d="M-1 -10 L5 -6 M2 -11 L8 -7 M5 -11 L10 -7"/>
<path class="dettaglio" d="M-8 -1 C0 -4 8 -1 13 3"/>
<path class="dettaglio" d="M15 -2 C18 -1 20 1 21 4"/>
</g>
</g>
</g>
<!-- the seat of the shorts, where both legs start -->
<path class="calzoni" d="M84 170 C88 160 118 158 126 168 L128 186 C118 194 96 194 86 186 Z"/>
<path class="dettaglio" d="M106 166 L104 186"/>
<!-- the shirt, with flowers, folds and a collar -->
<path class="maglia" d="M86 178 C82 150 102 112 132 96 C140 92 148 90 154 90 L168 94 C172 104 170 128 154 156 C146 170 136 178 126 182 C112 188 94 186 86 178 Z"/>
<path d="M86 178 C82 150 102 112 132 96 C140 92 148 90 154 90 L168 94 C172 104 170 128 154 156 C146 170 136 178 126 182 C112 188 94 186 86 178 Z" fill="url(#fiori)" stroke="none" clip-path="url(#taglio-maglia)"/>
<path class="dettaglio" d="M110 132 C114 140 116 146 122 150 M100 156 C106 162 112 166 120 168 M138 118 C140 126 140 132 136 140"/>
<path class="dettaglio" d="M90 176 C104 182 118 182 128 178"/>
<path class="colletto" d="M152 90 L160 102 L168 94 L164 88 Z"/>
<!-- the neck and the head -->
<path class="arto" d="M159 92 L164 82"/><path class="arto-dentro" d="M159 92 L164 82"/>
<g data-testa>
<path class="pelle" d="M152 60 C150 42 166 34 180 38 C190 41 194 50 193 57 L200 64 C201 66 199 67 196 67 L194 68 C195 74 192 80 186 82 C178 86 166 86 158 80 C152 74 152 66 152 60 Z"/>
<path class="capelli" d="M150 54 L146 62 L152 60 L150 70 L156 64 L156 54 Z"/>
<path class="pelle" d="M156 58 C150 56 148 64 151 69 C153 72 157 72 159 70"/>
<path class="dettaglio" d="M154 62 C152 64 153 67 156 67"/>
<path class="berretto" d="M148 54 C148 30 186 22 195 46 C182 46 162 49 148 54 Z"/>
<path d="M148 54 C148 30 186 22 195 46 C182 46 162 49 148 54 Z" fill="url(#puntini)" stroke="none" opacity=".55"/>
<path class="visiera" d="M186 44 C200 41 214 45 219 52 C208 55 194 53 187 50 Z"/>
<path class="dettaglio" d="M171 30 C166 36 160 44 156 52 M171 30 C176 36 180 42 182 47"/>
<circle cx="171" cy="30" r="2.6" class="bottone"/>
<path d="M178 51 L189 55" stroke-width="2.2"/>
<path d="M181 60 C184 57 188 57 190 60" stroke-width="2.2"/>
<path class="dettaglio" d="M175 68 L178 70 M178 66 L181 68"/>
<ellipse cx="190" cy="74" rx="3.2" ry="2.6" class="bocca"/>
<path class="dettaglio" d="M204 70 L210 68 M205 76 L212 77 M203 82 L208 85"/>
<path class="goccia" data-goccia d="M146 34 C148 39 151 41 148 44 C145 46 142 43 143 40 Z"/>
</g>
<!-- the near arm, in front, with the sleeve -->
<g class="braccio--avanti">
<path class="arto" d="M170 116 L198 124 L222 122"/><path class="arto-dentro" d="M170 116 L198 124 L222 122"/>
<path class="maglia" d="M146 98 C156 96 170 102 178 110 C176 118 172 124 168 126 C158 120 150 116 144 112 Z"/>
<path d="M146 98 C156 96 170 102 178 110 C176 118 172 124 168 126 C158 120 150 116 144 112 Z" fill="url(#fiori)" stroke="none"/>
<path class="dettaglio" d="M172 120 L176 112"/>
<path class="mano" d="M220 112 C224 108 232 108 233 114 L234 130 C234 135 227 136 222 131 L217 124 C214 120 215 115 220 112 Z"/>
<path class="dettaglio" d="M227 115 L234 115 M227 120 L234 120 M227 125 L234 125"/>
<path class="dettaglio" d="M219 123 C214 120 214 128 220 129"/>
</g>
</g>
</svg>
</div>
<p class="sipario__conto" data-conto>0</p>
</div>
<button class="ancora" type="button" data-ancora>Play it again</button>
<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.
50 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 panel pushed by hand” from Animorio and fit it into my siteEverything depends on one number, how far the push has gone, as a share of the screen width. A GSAP timeline takes it to the three stops in STOPS in the times in MOVES, with power2.inOut, putting the RESTS between them; the last stop has the LAST_EASE curve, power3.in, which starts slowly and ends in a rush past the edge.
The white panel and the name stay still underneath; on top there is a black sheet that GSAP moves to the right by the push times the width, but never past BLACK_MAX. So the white with the name is uncovered from the left without anything really moving.
The figure is a hand-drawn SVG, in two line weights: the head in profile with its nose, ear and a cap with seams, the flowered shirt made with an SVG pattern clipped to the outline, the hands with their fingers against the edge. Each leg is two groups: the thigh in the shorts turns at the hip, the shin with the striped sock and the shoe turns at the knee, and the shoe turns back by as much as the shin did, so it stays flat and only points down when the foot is lifted. The script works out the angles every frame: the phase of the step is the push times STEPS turns, the thigh swings with a sine and the knee bends more while the foot is lifted. The far leg and arm are a little greyer.
The number on the right goes from 0 to 30 on the first push, 30 to 60 on the second and 60 to 100 on the last, as on the site. When the black edge reaches it, the script moves it right by as much as the black has passed it, so it looks shoved away. SHOW_COUNT hides it.
Once the push is over and FINAL_HOLD seconds have passed, after EXIT_DELAY the panel goes down by one screen height in EXIT_TIME seconds with power2.inOut, and the name, which sits inside the panel, goes up by the same amount: on the screen the name does not move, and the edge of the panel wipes it away from the top. On a phone the first and the last push take three tenths longer and the last one goes further.
| Name | File | Default | What it changes |
|---|---|---|---|
STOPS | script.js | [0.3, 0.6, 1.28] | Where the three pushes end, in screen widths (0.3, 0.6 and 1.28 on the site). |
MOVES | script.js | [0.65, 0.72, 1.46] | How long each push takes, in seconds (0.65, 0.72 and 1.46 on the site). |
RESTS | script.js | [0.16, 0.2] | The rests after the first and the second push (0.16 and 0.2 on the site). |
BLACK_MAX | script.js | 1.12 | Where the black stops (1.12 on the site). |
EXIT_TIME | script.js | 1.33 | How long the white takes to slide down (1.33 on the site). |
STEPS | script.js | 3.2 | How many steps the figure takes to cross the screen. |
HOLD | script.js | 2.4 | The seconds before it starts again; 0 for once only. |
For the opening of the portfolio of an illustrator, a designer or a studio with a playful character, on the first visit. The character should be drawn in the site’s style.
The same, with a smaller figure and the site’s phone timings: the first and the last push slower, the last one longer.
No push: the panel is not there and the home page fades in.
GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0, Geist (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.6 KB; the libraries: GSAP 28 KB.
Tested on 14 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.