Skip to content
animorio
IT
Back to the library

Torn characters

WebGL, HoverWebGLAdvancedCompressed weight: Demo 7.8 KBGSAP 28 KBFreeDownload the zip

A WebGL field of characters, gathered into islands like a map, that the pointer tears away: it leaves a trail of ragged holes that close up by themselves.

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="it">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>I caratteri strappati</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="palco" data-palco>
    <!-- il campo di caratteri, in WebGL, sotto a tutto: il puntatore ci strappa dei buchi -->
    <canvas class="campo" data-campo aria-hidden="true"></canvas>

    <header class="testa">
      <p class="testa__riga"><span class="maschera"><span data-entra>Mostra di foto venute male</span></span></p>
      <p class="testa__riga testa__riga--destra"><span class="maschera"><span data-entra>Dal 3 al 26 ottobre</span></span><span class="maschera"><span data-entra>Ingresso libero</span></span></p>
    </header>

    <div class="piede">
      <h1 class="titolo" aria-label="Scarti"><span class="maschera" aria-hidden="true"><span data-titolo>Scarti</span></span></h1>
      <div class="piede__lato">
        <p class="sottotitolo"><span class="maschera"><span data-entra>Mosse, storte, sfocate, col pollice davanti: le foto che nessuno ha voluto, appese come quadri.</span></span></p>
        <p class="nota" data-nota>Muovi il puntatore: dove passa, i caratteri si strappano via e poi ricrescono.</p>
      </div>
    </div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.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.

27 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 “Torn characters” from Animorio and fit it into my site

What it does

A paper-coloured page with the exhibition’s title, Scarti, and underneath a field of blue characters: dots, dashes, crosses, hashes and at signs gathering into islands like the contour lines of a map, crawling slowly. Where the pointer passes the characters are torn away: a trail of holes with ragged edges is left behind, closing up again in just over half a second. Around the small text the field thins out, so it stays readable. Until someone moves the pointer, a ghost draws the trail by itself.

How it works

Two passes

The field is drawn in two WebGL passes. In the first, every screen cell, 9 px wide, is a single pixel of a small texture, and the shader writes its density there. In the second, at full resolution, every pixel finds its cell, reads the density and takes the glyph from an atlas: a canvas strip with the ramp’s characters, each in its own square of real pixels.

The density

It is a level of 0.57, denser at the bottom by 0.22, plus a three-dimensional value noise (the third dimension is time) over four octaves, which moves it by 0.62. A contrast of 2.3 gathers it into full islands with emptiness around them. Ten times a second every cell trembles a little, only where there is already something: the islands’ edges stay alive.

The trail

The hole under the pointer is 0.085 screen heights wide and chases it with a 0.06 second lag. Every 0.3 radii of travel, and no more often than every 30 ms, a mark is laid that lives 0.7 seconds: it stays almost full, then shrinks quickly. Hole and marks, 24 at most, reach the shader as an array of vec4: position, radius and a seed for the lumpy outline.

The tear

For every cell the shader takes the distance to the nearest mark and, before the threshold, adds a noise whose high octaves weigh more than usual: the edge does not wave, it breaks into shards. Where the distance drops below zero the density goes to zero and the cell falls onto the blank character.

Values to change

NameFileDefaultWhat it changes
CELLAscript.js9The size of one character, in px.
RAMPAscript.js' .:-=+xo%#@'The characters from empty to full: the first is the space.
CONTRASTOscript.js2.3How much the density gathers into islands.
LIVELLO, PENDENZAscript.js0.57, 0.22How dense the field is, and how much denser at the bottom.
RUMORE, SCALAscript.js0.62, 2.4How much the noise moves the density and how small the islands are.
RAGGIOscript.js0.085The hole under the pointer, in screen heights.
VITA, PASSOscript.js0.7, 0.3How long a trail mark lives and how much travel lays the next one.
STRAPPO, TRAMAscript.js0.13, 7How far the noise tears the edge and how fine the shards are.

Try them in the Playground

When to use it

For the background of a page that wants a strong character: a portfolio, an exhibition, a festival, an error page. It works best where the page is short and there is empty space to fill.

On phones

The finger draws while it touches: the page is one screen tall and dragging does not scroll it. When the finger lifts, the ghost comes back after two and a half seconds.

With reduced motion

The field stands still, with no ghost and no trail: only the hole under the pointer remains, and it moves when you move it.

Pitfalls

  • Do not compute the noise for every pixel: a 9 px cell is 81 pixels, 324 on a retina screen, all giving the same number. A texture with one pixel per cell does the same work hundreds of times faster.
  • The atlas must be drawn in real pixels, with the cell size times devicePixelRatio rounded, and read with NEAREST: with LINEAR or a fractional size the glyphs smudge.
  • When control passes from the ghost to the real pointer the hole must not rush from one to the other: it switches off, is reborn under the pointer and switches back on, otherwise the trail draws a straight line across the screen.
  • Noise added after the threshold dirties the edge; added before, to the distance, it tears it.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 7.8 KB; the libraries: GSAP 28 KB.

Testing

Tested on 28 September 2026

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

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