Skip to content
animorio
IT
Back to the library

The crew that glitches

Transitions, ImagesCanvas, GSAPMediumCompressed weight: Demo 7.5 KBGSAP 28 KBFreeDownload the zip

A portrait cut into five frames that draw themselves out from their centre. Pick another name in the crew and every frame breaks into strips sliding sideways, with two bright copies shaking, and at the worst of the noise the face underneath changes.

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 crew that glitches</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/chakra-petch@5.3.0/500.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/chakra-petch@5.3.0/700.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the crew page of a night radio: one portrait cut into five frames that draw themselves out from their centre;
       pick another name and every frame tears into sliding strips, and under the noise the face changes -->
  <main class="pagina" data-pagina>
    <header class="testa">
      <p class="testa__marchio">Night Shift Radio</p>
      <h1 class="testa__titolo">Six voices,<br>one night shift.</h1>
    </header>

    <div class="nomi" role="radiogroup" aria-label="Crew" data-nomi>
      <button type="button" role="radio" aria-checked="false" data-nome="0" data-autoclic>ines<span>host</span></button>
      <button type="button" role="radio" aria-checked="true" data-nome="1" data-autoclic>otto<span>producer</span></button>
      <button type="button" role="radio" aria-checked="false" data-nome="2" data-autoclic>remi<span>sound</span></button>
      <button type="button" role="radio" aria-checked="false" data-nome="3" data-autoclic>sol<span>music</span></button>
      <button type="button" role="radio" aria-checked="false" data-nome="4" data-autoclic>juno<span>news</span></button>
      <button type="button" role="radio" aria-checked="false" data-nome="5" data-autoclic>tavi<span>late nights</span></button>
    </div>

    <!-- the five frames: the whole portrait and four close-ups of it -->
    <div class="palco" data-palco aria-live="polite">
      <div class="cornice cornice--grande" data-cornice data-taglio="0.5,0.5,1"></div>
      <div class="cornice cornice--alto" data-cornice data-taglio="0.6,0.33,2.6"></div>
      <div class="cornice cornice--sinistra" data-cornice data-taglio="0.4,0.46,2.4"></div>
      <div class="cornice cornice--basso" data-cornice data-taglio="0.2,0.86,2"></div>
      <div class="cornice cornice--destra" data-cornice data-taglio="0.72,0.8,1.7"></div>
      <p class="sr" data-chi></p>
    </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.

31 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 crew that glitches” from Animorio and fit it into my site

What it does

The crew page of a made-up night radio, Night Shift Radio, in lime green on an almost black page: on the left the title and six names, each with its role, on the right five frames over the same portrait, a big one with the whole person and four smaller ones around it with close-ups. When the page opens every outline starts from a point in its centre and grows to its size, while the four little corner squares fly to their places, and the pictures inside pop up growing. Pick a name and it lands on a lime pill, and all five frames glitch together for less than a second: strips of the picture slide right and left, more and more and then less and less, and two bright copies move a few pixels; half way, when the noise covers everything, the new person is already underneath. Moving the mouse, the frames follow it a little, each by a different amount, as if they stood at different distances.

How it works

The portraits

The script paints the six portraits in grey on an offscreen canvas: shoulders, neck, a head lit from one side, eyes, mouth and a different hairstyle for each. Then it blurs them and turns them into two colours, the dark and the light from the style sheet, with every third row darker as on an old screen.

The five frames

Each frame says in data-taglio which part of the portrait it shows: the centre of the close-up and how many times it is enlarged. The script cuts that part out to the shape of the frame and draws it on the frame’s canvas.

The outline that draws itself

The outline is an SVG rectangle that GSAP takes from zero width and height, in the centre, to full size, in FRAME seconds on power2.out; the four little squares start from the centre and reach the corners. The picture inside goes from scale 0 to 1 in 0.6 seconds on the curve 0.33, 1, 0.32, 1.

The glitch

Over each frame there is a second canvas. For GLITCH milliseconds the strength rises from 0 to 1 and back to 0; on every frame the canvas copies the picture, then copies from itself as many strips as SLICES times the strength, each a random height and moved randomly up to SHIFT times the strength. Last it adds itself twice, moved right and left by GHOST[0] plus GHOST[1] times the strength. Above COVER the canvas is fully opaque, and half way the person underneath changes.

The mouse

The frames move after the mouse, each by the hundredths of the width written in DEPTH, in turn, with a 0.3-second CSS transition: moving the mouse they seem to stand at different distances. Only where there is a real mouse.

Values to change

NameFileDefaultWhat it changes
GLITCHscript.js780The milliseconds of the glitch when the name changes (as on the site).
SLICESscript.js70How many strips slide at the worst of it (70 on the site).
SHIFTscript.js200How far a strip can slide at the worst of it, in pixels (200 on the site).
GHOSTscript.js[2, 10]The two bright copies: how far they always move and how much more at the worst (as on the site).
COVERscript.js0.88Above this strength the noise covers the picture completely (0.88 on the site).
FRAMEscript.js0.6The seconds the outlines take to draw themselves out of their centre (as on the site).
DEPTHscript.js[0.5, 1.2, 0.8, 1.5]How far the frames follow the mouse, in turn, in hundredths of the width (the site’s).

Try them in the Playground

When to use it

For the team page of a studio, a band, a newsroom: you pick a person and the change has the character of a channel jumping, instead of an ordinary fade.

On phones

The same: the frames take most of the screen and the names line up underneath, to tap; the frames do not follow the finger.

With reduced motion

No glitch and no movement: the frames fade in and the old face fades out over the new one.

Pitfalls

  • The SVG rectangles made by the script must be born with x, y, width and height written: if they are missing, GSAP’s first tween on their attributes starts from an empty value and the browser throws an error.
  • The glitch copies strips from the canvas onto itself: the whole picture of that frame has to be drawn first, otherwise the strips carry the noise of the frame before and the picture gets dirtier and dirtier.
  • The face must change when the noise is strongest and the canvas is opaque: earlier or later, the jump shows.

Libraries

GSAP 3.15.0, Chakra Petch 5.3.0.

Compressed with gzip, the three demo files weigh 7.5 KB; the libraries: GSAP 28 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