Skip to content
animorio
IT
All components

The badge swipe button

Buttons, Physics, TransitionsCanvas, GSAPAdvancedCompressed weight: Demo 13 KBGSAP 28 KBFreeDownload the zip

The office Sign in with a badge: an ID card hanging on the cord of a spring reel over the pill, and the pill is the reader, with a slot along its top edge. At a click the badge is pulled down, goes into the slot behind the front of the pill, the magnetic stripe runs all the way through with a line of light under it, the reader answers Signing in… and then Signed in · Rui Costa; let go, the reel winds the cord back in and the badge goes up swinging. Sign out dips it into the reader, it comes out and hangs again. The badge can also be grabbed and swiped by hand.

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 badge swipe button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the badge swipe button: the Sign in of an office, a studio or a lab. An ID badge hangs on a spring reel over the
         pill, and the pill is the reader: a slot runs along its top edge. A click pulls the badge down, swipes it
         through the slot and lets it go: the reel winds the cord back in and the badge swings. Signing out dips the
         badge into the reader and it comes out and hangs again. The badge can also be grabbed and swiped by hand -->
    <div class="swipe" data-swipe>
      <!-- the reel, the cord and the badge, drawn by the script, between the back of the slot and the front of the pill -->
      <canvas class="swipe__rig" aria-hidden="true" data-rig></canvas>
      <span class="swipe__grip" aria-hidden="true" data-grip></span>
      <button class="swipe__btn" type="button" data-btn data-autoclic>
        <span class="swipe__back" aria-hidden="true"></span>
        <span class="swipe__front" aria-hidden="true"></span>
        <span class="swipe__faces">
          <span class="swipe__face" data-face="rest">
            <span class="swipe__word" data-wide="Sign in" data-rest-text>Sign in</span>
          </span>
          <span class="swipe__face swipe__face--busy" data-face="busy" aria-hidden="true">
            <span class="swipe__shine" data-busy-text>Signing in…</span>
          </span>
          <span class="swipe__face swipe__face--done" data-face="done" aria-hidden="true">
            <span class="swipe__who"><span data-done-text>Signed in</span> · <b data-name-text>Rui Costa</b></span>
            <span class="swipe__out" data-out-text>Sign out</span>
          </span>
          <span class="swipe__face swipe__face--busy" data-face="gone" aria-hidden="true">
            <span class="swipe__gone" data-gone-text>Signed out</span>
          </span>
        </span>
      </button>
      <p class="sr" aria-live="polite" data-live></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.

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 “The badge swipe button” from Animorio and fit it into my site

What it does

On a white page a graphite pill, 60 pixels tall, that is also a badge reader: a dark slot runs along its top edge with a thread of light on its lip. Over its left end hangs a chrome spring reel with its belt clip, and from its mouth comes down a green cord with a white landscape badge: the green band at the top with the slit for the clear strap, a small photo, the name Rui Costa, the word Studio, a few bars of a code and the dark magnetic stripe along its foot. As it comes in, the badge drops out of the reel and settles, swinging. With the mouse on the pill the badge stirs on its cord as if it felt the reader; the words widen on the wdth axis and the fill swells with a bounce. At a click an invisible hand pulls the badge down, upright, to the start of the slot: the badge goes in behind the front of the pill, so the words always stay in front, and the magnetic stripe runs to the other end, while the reel pays out cord and a green line of light runs in the slot under the badge. The reader answers in words: Signing in… with a sheen, then Signed in · Rui Costa and a small Sign out pill. The badge comes out of the slot and is let go: the reel's spring winds the cord back in, slowing on the last stretch, the badge is pulled up, the cord goes slack, the badge drops back onto the cord, turns a little on its strap and swings until the air stops it. The second click pulls the badge down and dips it into the reader, where it stays a moment with the line of light on (Signing out…), then it comes out and hangs again; Signed out, and Sign in again. The badge can also be grabbed with the mouse or a finger: the pill is solid and lets it in only through the slot; swiped through more than half the slot it signs in, dipped into the reader it signs out.

How it works

Three layers: back, canvas, front

The pill is two layers: the back of the slot, dark, behind the canvas, and the front, cut 10 pixels under the edge with clip-path, in front of it. The button has no z-index of its own, so the canvas with the badge sits in between: when the badge goes down into the slot it disappears behind the front, and it never covers the words.

The cord in position based dynamics

The cord is a chain of twelve points: at each step gravity and the air move the points, then ten rounds of constraints put the links right, which can go slack but never stretch, and the speed comes from where the points ended up. The badge is a rigid body hanging from the last point: the clip and its middle, at a fixed distance, so it swings like a real pendulum.

The spring reel

The cord's length changes: when the hand pulls, the reel pays out all the cord it needs; let go, the spring winds it in at the speed REEL, braking on the last stretch as a real reel does. The badge is pulled up, the cord goes slack and it drops back and swings. The reel's face turns with the cord going in and out.

The hand and the swipe

During the swipe the clip and the badge's middle follow a hand moved by a GSAP timeline: straight down, into the slot, all along the slot, out. Let go, the badge keeps the speed the hand gave it and gets a small twist on its strap, a spring of its own that narrows it as if it turned.

Solid where it matters

Out of the hand the cord and the badge do not go through the pill: the badge's lowest corner rests on its edge and slides, and the badge cannot swing over the reel. Dragged by hand, the badge goes into the pill only through the slot and only as deep as it is; the reader counts how much of the slot it has run through.

Values to change

NameFileDefaultWhat it changes
LABELscript.js'Sign in'The words at rest.
BUSYscript.js'Signing in…'The words while the reader reads the badge.
DONEscript.js'Signed in'The words once in, before the name.
PERSONscript.js'Rui Costa'The name on the badge and in the words (invented: nothing is sent anywhere).
ROLEscript.js'Studio'The small word under the name, on the badge.
LOGOUTscript.js'Sign out'The little pill that signs out.
LEAVINGscript.js'Signing out…'The words while it signs out.
GONEscript.js'Signed out'The words once out, before Sign in comes back.
SWIPEscript.js0.6The seconds the swipe through the slot takes.
GRAVITYscript.js2200How hard the badge falls, in pixels a second squared.
REELscript.js420How fast the reel winds the cord back in, in pixels a second.
AIRscript.js1.1How much the air slows the swings: 0.2 it swings a long time, 4 it hardly swings.

Try them in the Playground

When to use it

For the sign in of a work app: an intranet, a studio, a coworking space, a lab, an office dashboard. It stands alone on a light background; on a real site the call that really signs in goes where the swipe is, and the name comes from the account.

On phones

The pill fits the screen (at most the screen's width less 32 pixels) and the slot with it; the badge keeps its size. A tap on the pill makes the swipe; the badge can be grabbed with a finger too, and while it is held the page does not scroll.

With reduced motion

No swings and no swiping: the badge fades out where it hangs and fades in already in the slot, still, with the line of light fading in; then it fades out and in again hanging. The words change with a fade and the pill does not swell.

Pitfalls

  • The badge swiped over the pill covered the words: the pill is split into two layers, the back of the slot behind the canvas and the front in front of it, and the button has no z-index of its own, so the canvas sits in between and the badge disappears behind the front.
  • Let go at the right end of the slot, the badge fell like a pendulum on its long cord and passed under the pill: the pill is solid for the cord and for the badge's lowest corner, and the hand lifts it and brings it towards the reel before letting go.
  • The reel wound in at full speed to the very end and threw the badge over itself, out of the canvas: it brakes on the last stretch as a real one does, the clip stops under the mouth and the badge cannot swing past level.
  • The REEL value and the object with the reel's position had the same name: inside the function the object hid the constant and the speed became NaN. The object is called HUB.
  • Dragged by hand the badge looked inside the slot but the reader did not feel it: it counted the badge in only at the bottom. Now it is enough for the magnetic stripe to pass the lip.

Libraries

GSAP 3.15.0, Mona Sans (font variabile) 5.3.0.

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

Testing

Tested on 9 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 components