Skip to content
animorio
IT
Back to the library

The title wrapped on a cylinder

Text, Scroll, 3DGSAP, CSS onlyAdvancedCompressed weight: Demo 9.6 KBGSAP + ScrollTrigger 45 KBLenis 5.3 KBFreeDownload the zip

Scroll inside the preview

The big opening title is wrapped around a 3D cylinder that turns as you scroll, with the letters darker on the sides and at the back. Then the cylinder unrolls like a carpet: the letters come off one after the other and settle in a straight line, with a small elastic bounce. Further down a second title does the opposite: it rolls up, spins and leaves.

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 title wrapped on a cylinder</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the opening of a made-up magazine about clay. The big title is wrapped on a turning cylinder, like the words
       painted around a pot on the wheel; scrolling turns it, then unrolls it letter by letter into a straight line.
       Further down a second title does the opposite: it rolls up and leaves -->
  <header class="testata">
    <a class="testata__marchio" href="#">Slip</a>
    <p class="testata__uscita">The autumn issue</p>
    <nav class="testata__nav" aria-label="Sections">
      <a class="rullo" href="#"><span data-t="Stories">Stories</span></a>
      <a class="rullo" href="#"><span data-t="Studios">Studios</span></a>
      <a class="rullo" href="#"><span data-t="Glazes">Glazes</span></a>
    </nav>
  </header>

  <main>
    <section class="giro" data-giro>
      <div class="palco">
        <p class="occhiello" data-occhiello>A quarterly on clay and the hands that shape it</p>
        <div class="cilindro" data-cilindro>
          <h1 class="nascosto" data-titolo></h1>
          <div class="anello" data-anello aria-hidden="true"></div>
        </div>
        <div class="sommario" data-sommario>
          <p class="sommario__testo" data-riga>Seven potters, one studio by the river, and the slow afternoons it takes to centre a ball of clay.</p>
          <p class="sommario__firma" data-riga>Words by Ines Moreau. Photographs by Tomas Leer.</p>
        </div>
        <p class="invito" data-invito>
          <span>Scroll to unroll</span>
          <svg viewBox="0 0 12 18" aria-hidden="true"><path d="M6 1v15M1.5 11.5 6 16l4.5-4.5" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
        </p>
      </div>
    </section>

    <article class="pezzo">
      <div class="pezzo__testo">
        <p class="pezzo__primo" data-sale>The wheel at the back of the studio is older than anyone who uses it. It hums when it starts, settles into a low note, and from then on the only sound is water and the soft slap of a palm on wet clay.</p>
        <p data-sale>Centring comes first, and it never gets quicker. You lean in with the whole body, not the arms, until the lump stops fighting you and spins without a wobble. Only then does the hole open, and the walls begin to rise.</p>
        <blockquote class="citazione" data-sale>
          <p>The clay tells you when it is ready. You just have to stop talking.</p>
        </blockquote>
        <p data-sale>Every pot here carries a line of words painted around its belly before the first firing: a name, a date, a line from a song. Turn the pot and the sentence comes round to meet you.</p>
      </div>
      <figure class="vaso" aria-hidden="true">
        <svg viewBox="0 0 240 320">
          <path data-traccia d="M88 30h64M92 30c0 22-6 34-22 56-18 25-34 52-34 92 0 62 36 112 84 112s84-50 84-112c0-40-16-67-34-92-16-22-22-34-22-56" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
          <path data-traccia d="M44 150c46 16 106 16 152 0M40 196c50 18 110 18 160 0" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
          <path data-traccia d="M70 292h100M40 304h160" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
        </svg>
        <figcaption>Drawn in the studio, before the first firing</figcaption>
      </figure>
    </article>

    <section class="forno" data-forno>
      <div class="palco palco--forno">
        <p class="occhiello occhiello--forno">Next, the firing</p>
        <div class="cilindro" data-cilindro>
          <h2 class="nascosto" data-titolo></h2>
          <div class="anello" data-anello aria-hidden="true"></div>
        </div>
        <p class="forno__nota" data-nota>Twelve hours of heat, a night of cooling, and nobody opens the door before morning.</p>
      </div>
    </section>

    <footer class="piede">
      <p class="piede__marchio">Slip</p>
      <p class="piede__testo">Four issues a year, printed on paper you can feel.</p>
      <a class="pillola" href="#"><span class="pillola__fondo" aria-hidden="true"></span><span class="pillola__scritta">Subscribe</span></a>
    </footer>
  </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/lenis@1.3.26/dist/lenis.min.js"></script>
  <script 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.

39 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 title wrapped on a cylinder” from Animorio and fit it into my site

What it does

The opening of an invented magazine about ceramics, Slip, on a paper-coloured background. The title, “On the wheel”, is painted around a cylinder like the words around a pot on the wheel: every letter sits on the curve, facing outwards, in front of clay bands, and gets darker on the sides and at the back, where you see it backwards through the clay. At the top of the page the cylinder sways gently, like a pot resting on the wheel. As you scroll it turns twice and slows down; then it unrolls: the first letter on the left comes off the side of the cylinder and settles on the line, and the cylinder rolls to the right along the line like a carpet, laying down one letter after the other. Each letter that lands squashes a little and springs back with an elastic bounce. When the title is all straight, the standfirst and the byline come in underneath. Further down, after the article text with a pot that draws itself, the page turns dark like a kiln and the second title, “Into the kiln”, does the opposite: it rolls up from the right onto its cylinder, spins faster and faster, tilts and flies away upwards.

How it works

The letters and the line

The script splits TITLE into letters, each in two spans: the scroll moves the outer one, the bounce the inner one. It measures the letters at 100 pixels, picks the size that fits the line in 84% of the window (90% on a phone, at most 26% of the height) and gives every letter its place s on the line, measured from the middle.

The cylinder

The radius is RADIUS times the length of the line divided by 2π: with 1 the title goes exactly once around. Wrapped, a letter sits at the angle s / R: x = R · sin a, z = R · cos a − R, and rotateY(a) turns it outwards. Behind the letters, 24 to 72 narrow clay bands make the surface. The wrapped cylinder sits a little closer to you (a share of the perspective), so it looks bigger, and TILT leans it with rotateX around its own axis.

The shade

The colour of every letter and band is mixed between the lit colour and the shaded one by the angle: (1 − cos a) / 2, a little more on the right side because the light comes from the left, and more again at the back. SHADE says how dark it gets. The letters at the back show backwards (backface-visibility visible) and faint, as if through the clay. The bands live in a layer of their own, under the letters, so a letter is never cut or covered by a band; when the unrolling starts the cylinder already stands upright, and each band vanishes as soon as it comes off.

The unrolling

The stage is a 100lvh sticky box in a 380lvh section; a tween with ScrollTrigger and scrub carries the progress from 0 to 1, and Lenis smooths the scroll. In the first half the cylinder turns TURNS times, slowing down; from 30% to 82% it unrolls. Every letter has its own stretch (one every 1 / 3.4 of the unrolling, from the left) in which position and angle go from the cylinder to the line with power3.inOut. Meanwhile the cylinder rolls to the right like a carpet and turns as much as it rolls, so the letter coming off always leaves from its left side.

The bounce and the opposite

When a letter lands on the line, the inner span starts squashed (scaleY 0.72, scaleX 1.16) and springs back with EASE in 1.1 seconds. The second title uses the same cylinder backwards: the unrolling goes from 1 to 0, so it rolls up from the right; then it spins faster and faster with power2.in, tilts, rises, shrinks and disappears.

Values to change

NameFileDefaultWhat it changes
TITLEscript.js'On the wheel'The opening title, wrapped on the cylinder.
OUTRO_TITLEscript.js'Into the kiln'The second title, the one that rolls up and leaves.
RADIUSscript.js1.15The size of the cylinder: with 1 the title goes exactly once around it, more leaves a gap at the back.
TURNSscript.js2How many times the cylinder turns before it unrolls (whole numbers start with the title in front).
SHADEscript.js0.8How dark the letters get on the sides and at the back, from 0 to 1.
TILTscript.js16How much you look down on the cylinder, in degrees.
EASEscript.js'elastic.out(1.1, 0.35)'The bounce of each letter when it lands in the straight line.
SCRUBscript.js0.6The seconds the cylinder takes to catch up with the scroll.

Try them in the Playground

When to use it

For the opening of a magazine, a long read, a project page or a brand that has to do with something that turns: ceramics, textiles, printing, records, cans, labels. It works with short titles, 6 to 16 letters: with a long sentence the line gets small and the cylinder huge.

On phones

The same animations with the sizes adapted: the line takes 90% of the width, the wrapped cylinder sits closer to you so it stays big on the narrow screen, and a finger unrolls the title like the wheel (Lenis leaves native scrolling to touch).

With reduced motion

Nothing turns and nothing moves: the title is already straight in its place, the standfirst and byline fade in as soon as you scroll, and the second title fades away. Lenis does not start.

Pitfalls

  • Interpolating the angle of a letter that has been turning for many turns makes the letter do all those turns on its own. That is why the cylinder (almost) stops turning before the letters come off, and the angle is never wrapped back between −180 and 180: the jump would show halfway.
  • If the cylinder stays in the middle while it unrolls, the line runs through it. It has to roll along the line and turn as much as it rolls (angle = distance / radius), so the letter coming off leaves from its side.
  • Tilting with rotateX turns around the middle of the screen: if the cylinder sits closer to you, it drops. It has to turn around its own axis, with a translateZ before and an equal and opposite one after.
  • The letters must be measured in their own font: wait for document.fonts.load of the weight in use, or you measure the fallback font and the letters overlap.
  • Letters and bands in the same 3D context cut each other where they cross, and a closer band covers letters that have already landed. The bands go in a sibling layer before the letters’ one: each sorts its own pieces in 3D, but the letters always stay on top.

Libraries

GSAP 3.15.0, Lenis 1.3.26, Fraunces (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 9.6 KB; the libraries: GSAP + ScrollTrigger 45 KB, Lenis 5.3 KB.

Testing

Tested on 10 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