Skip to content
animorio
IT
Back to the library

The head that opens up

WebGL, 3D, TransitionsWebGL, GSAPAdvancedCompressed weight: Demo 9.3 KBGSAP + ScrollTrigger + CustomEase 49 KBThree.js 174 KBFreeDownload the zip

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.

The code

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>

Playground

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

Or ask Claude Code for it

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 site

What it does

The opening of a made-up comedian’s site, Milo Fenn, on a deep teal page with the name huge in coral. In the middle comes a paper sticker of the face, red hair and a white rim: at first it is rolled up tight and it unrolls onto the screen like a sheet being spread out, while the camera comes closer from far away and the head sinks towards the bottom. Then the top of the head, torn along a ragged line across the forehead, starts curling from one side, rolls up showing the white back of the paper and goes away. Out of it pop, one after the other with a little bounce, a cloud, a microphone, a book, an old screen with a play button and a heart, all in 3D. The eyes look around and then follow the pointer; the microphone, the book and the screen now and then do a Mexican wave. Point at a thing and it rises, with its name above it. Scroll down and the rest of the sticker peels off too, and the face, as soon as it starts, looks surprised.

How it works

The face is a drawing on a canvas

The 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 tear splits the head in two

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.

Bending a sheet with a line

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 inside the head

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.

The pointer, the eyes and the scroll

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.

Values to change

NameFileDefaultWhat it changes
UNROLLscript.js2The seconds the sticker takes to unroll (2 on the site).
ZOOMscript.js2The seconds the camera takes to come close, on expo.inOut (2 on the site).
PEELscript.js2The seconds the top of the head takes to roll away (2 on the site).
PEEL_ATscript.js3When the peel starts, in seconds (3 on the site).
CURLscript.js3How tightly the paper curls: higher, a smaller roll.
POPscript.js1.25How long each thing takes to pop up (1.25 on the site).
POP_STAGGERscript.js0.1The delay between one thing and the next (0.1 on the site).
WAVEscript.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).
LIFTscript.js0.3How far a thing rises under the pointer (0.3 on the site).
TEARscript.js0.62Where the tear crosses the head, from the chin (0) to the top (1).
NAMESscript.js['Weird thoughts', 'Live shows', 'Books', 'Videos', 'Podcast']The names of the things, in order: cloud, microphone, book, screen, heart.

Try them in the Playground

When to use it

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.

On phones

The same: the camera widens so the whole head fits on the narrow screen, and touching a thing lifts it and shows its name.

With reduced motion

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.

Pitfalls

  • The bend works on the vertices: a plane with few squares bends in corners. Here there are 96 by 106, and the curve stays smooth even close up.
  • With a ShaderMaterial sRGB textures arrive already converted, but the result must be turned back to sRGB by hand: without the colorspace_fragment include at the end of the shader the colours of the drawing come out washed out.
  • The back of the sheet only shows with side: DoubleSide, and the shader recognises it with gl_FrontFacing: there it draws the paper instead of the face.
  • A fromTo inside a timeline is applied at once: the things, which start from below, would show above the head while it is still rolled up. They are kept invisible until the peel.
  • JavaScript modules do not load when the file is opened from disk: to try it you need a small local server.

Libraries

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.

Testing

Tested on 8 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All animations