
The burning veil
Transitions, WebGL
NewFree
A paper sticker of a face unrolls onto the screen, then the top of the head tears off, rolls up and goes away, and out of it pop a microphone, a book, a video, a heart and a cloud. The eyes follow the pointer, the things do a Mexican wave and rise when you point at them.
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 head that opens up</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/inter-tight@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.178.0/build/three.module.min.js"
} }
</script>
</head>
<body>
<!-- the opening of a made-up comedian's site. A paper sticker of the face unrolls onto the screen and comes closer;
then the top of the head peels back like paper and what is inside pops out: a microphone, a book, a video, a
heart, a cloud. Point at them and they rise and say what they are; scroll and the rest of the sticker peels off -->
<main>
<section class="apertura" data-apertura>
<header class="testata">
<span class="testata__nome">Milo Fenn</span>
<a class="pillola" href="#date">Tickets</a>
</header>
<h1 class="titolo" data-titolo>Milo Fenn</h1>
<canvas class="tela" data-tela aria-hidden="true"></canvas>
<p class="etichetta" data-etichetta aria-hidden="true"></p>
<button class="ancora" type="button" data-ancora hidden>Play it again</button>
</section>
<section class="sotto" id="date">
<p class="sotto__frase">Comedian, podcaster and <em>terrible</em> at maps.</p>
<p class="sotto__piccolo">Scroll back up to see the opening again.</p>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/CustomEase.min.js"></script>
<script type="module" 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 head that opens up” from Animorio and fit it into my siteThe face is drawn only once on a 2D canvas, in two versions, calm and surprised: first the outline stroked with a very thick white line, which becomes the rim of the sticker, then ears, face, hair made of many circles, cheeks, eyebrows, nose and mouth. The pupils are not there: the shader draws them, so they can move. The canvas becomes the texture of two identical Three.js planes, finely divided, one on top of the other.
The two planes have the same drawing: the shader of the top piece throws away everything below a ragged line at TEAR of the height, the bottom one everything above. The line is noise in two sizes on the horizontal coordinate. Along the tear both show a band of white fibre of changing thickness, and the back of the paper is off-white: you only see it when the sheet bends.
In the vertex shader every point beyond a line, given by a point and a direction, wraps around a cylinder of radius 1/CURL towards the camera; past half a turn it carries on flat, folded back. Sliding the line is all it takes to bend the sheet: from -6 to 6 in UNROLL seconds the whole sticker unrolls, and from PEEL_AT, with the line turned the other way, the top rolls up in PEEL seconds and ends up off the screen. The bent part gets darker with the sine of the angle, so it looks curved.
The things are plain Three.js shapes with standard materials, behind the planes: you only see them where the paper is gone. Each one sits in three nested groups, one per movement, so the pop, the wave and the pointer never clash: they come up from below in POP seconds with back.inOut(2), one every POP_STAGGER. The wave is a repeating timeline set by WAVE: height, duration, delay between them and pause, on a curve that dips a little first and then rises.
A raycaster looks for the thing under the pointer: it rises by LIFT, the wave stops and starts again two seconds after you leave, and an HTML label sits above it by projecting its position onto the screen. The eyes go towards the pointer and, if it stays still for a second, look ahead again. When scrolling, a ScrollTrigger slides the fold line of the bottom piece across the whole face, and at 7.5% of the scroll the texture switches to the surprised one.
| Name | File | Default | What it changes |
|---|---|---|---|
UNROLL | script.js | 2 | The seconds the sticker takes to unroll (2 on the site). |
ZOOM | script.js | 2 | The seconds the camera takes to come close, on expo.inOut (2 on the site). |
PEEL | script.js | 2 | The seconds the top of the head takes to roll away (2 on the site). |
PEEL_AT | script.js | 3 | When the peel starts, in seconds (3 on the site). |
CURL | script.js | 3 | How tightly the paper curls: higher, a smaller roll. |
POP | script.js | 1.25 | How long each thing takes to pop up (1.25 on the site). |
POP_STAGGER | script.js | 0.1 | The delay between one thing and the next (0.1 on the site). |
WAVE | script.js | [0.25, 0.7, 0.15, 0.5] | The wave: how high, how long, the delay between them and the pause (the site’s). |
LIFT | script.js | 0.3 | How far a thing rises under the pointer (0.3 on the site). |
TEAR | script.js | 0.62 | Where the tear crosses the head, from the chin (0) to the top (1). |
NAMES | script.js | ['Weird thoughts', 'Live shows', 'Books', 'Videos', 'Podcast'] | The names of the things, in order: cloud, microphone, book, screen, heart. |
For the opening of the site of a person or a brand with a recognisable face: a comedian, an author, a podcast, an artist. It works when the things coming out of the head really are the sections of the site, and pointing at them tells you where they lead.
The same: the camera widens so the whole head fits on the narrow screen, and touching a thing lifts it and shows its name.
No unrolling, no peel and no wave: the head is already open with the things in place, the eyes look ahead, and pointing at a thing shows its name without lifting it.
Three.js 0.178.0, GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, CustomEase (GSAP) 3.15.0, Inter Tight (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 9.3 KB; the libraries: GSAP + ScrollTrigger + CustomEase 49 KB, Three.js 174 KB.
Tested on 8 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.