Skip to content
animorio
IT
All components

The ticket to tear

Tickets, Physics, SVGGSAPAdvancedCompressed weight: Demo 7.2 KBGSAP 28 KBFreeDownload the zip

A concert ticket with its stub: pulling the stub the perforation gives way from the top, the harder the pull the faster it tears, and the torn flap opens round the point where the paper still holds, with ragged edges. Let go halfway it stays open; torn to the end it flies out of the hand and falls turning, and the ticket gets its stamp.

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 ticket to tear</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/league-gothic@5.3.0/index.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/azeret-mono@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the ticket to tear: pulling the stub, the perforation gives way from the top and the stub opens round the
         tear; torn off, it flies out of the hand and falls, and the ticket is stamped -->
    <section class="entry" aria-label="Concert ticket" data-entry data-autoclic>
      <div class="ticket" data-ticket>
        <div class="ticket__body" data-body>
          <svg class="paper" aria-hidden="true" data-paper-body></svg>
          <div class="ticket__main">
            <p class="ticket__kind">Open-air concert</p>
            <h2 class="ticket__title">Stars over the vineyard</h2>
            <dl class="ticket__facts">
              <div><dt>Date</dt><dd>Sat 12 July</dd></div>
              <div><dt>Doors</dt><dd>21:30</dd></div>
              <div><dt>Gate</dt><dd>B</dd></div>
              <div><dt>Seat</dt><dd>F 14</dd></div>
            </dl>
          </div>
          <p class="stamp" aria-hidden="true" data-stamp>Admitted</p>
        </div>
        <!-- the stub in two layers: what still holds, and the flap already torn, which opens round the tear -->
        <div class="ticket__stub" data-stub>
          <div class="stub__layer" data-rest>
            <svg class="paper" aria-hidden="true" data-paper-rest></svg>
            <div class="ticket__side">
              <p class="ticket__admit">Admit one</p>
              <p class="ticket__seat">F14</p>
              <svg class="ticket__code" viewBox="0 0 60 22" preserveAspectRatio="none" aria-hidden="true" data-code></svg>
            </div>
          </div>
          <div class="stub__layer" aria-hidden="true" data-flap></div>
        </div>
      </div>
      <div class="entry__row">
        <p class="entry__hint" data-hint>Pull the stub to tear it off</p>
        <button class="entry__act" type="button" data-act>Tear the stub</button>
      </div>
      <p class="sr" aria-live="polite" data-live></p>
    </section>
  </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.

24 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 ticket to tear” from Animorio and fit it into my site

What it does

On a white background a cream paper ticket: on the left a wine-red band, Open-air concert, STARS OVER THE VINEYARD, date, doors, gate and seat, and a vineyard faintly printed; on the right, past a dashed perforation with a half-moon at each end, the stub with Admit one, F14 and a barcode. Below, a line and the Tear the stub button. Grabbing the stub and pulling it outwards or downwards, the paper at the top starts to give: the point of the tear moves down the perforation, the faster the harder the pull, the torn edges of the ticket and the stub are ragged and the part already torn opens like a wedge round that point, while the part that holds stays in its place. Let go halfway, the flap swings back with a bounce and stays a little open (paper does not mend) and the line says Keep pulling to tear it off. Torn to the end, the stub flies off with the speed of the hand, falls turning and vanishes; the ADMITTED stamp comes down on the ticket and the ticket gives a little under the blow. New ticket sends the ticket out to the left and brings a new one in from the right.

How it works

The drawn paper

Each piece has its paper in an SVG behind the words: a path with rounded corners, the half-moons of the perforation and the edge of the tear, rebuilt every frame, with a feDropShadow shadow that follows the real shape. The torn edge has a tooth every 5 pixels, the same teeth for the ticket and for the stub, so the two edges fit.

The stub in two layers

The stub is there twice: the layer below shows only what still holds (clip-path inset cut below the tear) and stays still, the layer above shows only the torn flap and turns round the point of the tear (transform-origin on that point). So only the torn part opens, like paper that bends.

The pull and the tear

The pull is how far the hand has turned round the point of the tear, in degrees, plus how far it has moved away to the right. Past HOLD degrees the paper gives: the point of the tear moves down RATE pixels a second for every degree more, worked out on GSAP's ticker while the hand holds. The flap opens up to OPEN degrees; beyond, it barely gives. Let go halfway, a tween with elastic.out brings it back to hang open.

The flight and the stamp

Torn to the end, the rotation round the point of the tear becomes a shift plus a rotation round the middle, so the stub can fly free: it leaves with the speed of the hand, falls with the gravity FALL, turns and fades. The stamp arrives big and crooked and lands in a flash (power4.in), and the ticket gives by 3 pixels and comes back with a bounce.

The button, the keys and the preview

Tear the stub makes a pretend pull: the same tearing, driven by a number instead of the hand; then it becomes New ticket. A click from a script (the library's preview) is a pretend hand that tears halfway and lets go, then tears it off, then takes a new ticket.

Values to change

NameFileDefaultWhat it changes
HOLDscript.js8The degrees the stub must be pulled open before the paper starts to give.
RATEscript.js9How fast the paper tears: pixels a second for each degree pulled beyond HOLD.
OPENscript.js30The degrees the torn flap can open.
FALLscript.js1600The gravity on the torn stub, in pixels a second each second.

Try them in the Playground

When to use it

For a booking or purchase confirmation, an event page, a voucher to use, an invitation, a museum or winery tour ticket: anywhere a gesture should say «used».

On phones

The finger pulls the stub without scrolling the page (touch-action none on the stub); under 520 pixels the details go into two columns and the stamp gets smaller, and the button stays for those who prefer to tap.

With reduced motion

The hand still tears the paper, but the flap let go hangs without swinging; torn off, the stub fades where it is instead of falling, the stamp is there without a blow, the new ticket comes at once and the button tears in an instant.

Pitfalls

  • A rigid stub turned round the point of the tear slides the part still attached into the ticket: two layers are needed, cut above and below the tear, and only the flap turns.
  • clip-path cuts shadows too: with negative insets (inset(t -30px -40px -30px)) the shadow can spill past the sides and the bottom.
  • box-shadow and drop-shadow do not follow a drawn torn edge: the paper is an SVG path with feDropShadow, redrawn every frame.
  • Changing transform-origin on a rotated element moves it: at the tear the rotation round the point of the tear must be turned into a shift plus a rotation round the middle, before letting it fly.
  • The pretend pull ends with a delayedCall: if the stub comes off before, it must be cancelled, or the button stays blocked until it runs out.

Libraries

GSAP 3.15.0, League Gothic (font variabile) 5.3.0, Azeret Mono (font variabile) 5.3.0.

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

Testing

Tested on 3 October 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 components