
Falling tools
Physics, Hover
NewFree
The header of a made-up boxing club, Ironjaw, in the rich style: in front of a brick wall, under a steel beam, a red leather heavy bag hangs from its chain and straps and swings with real physics. A tap sends a glove to hit it at the right height: the bag squashes, turns and swings, dust puffs out of the leather, the gloves on the hook jiggle and, on hard hits, the ring bell rings.
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 boxing gym heavy bag</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/big-shoulders-display@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="gym" data-gym>
<!-- the header of a made-up boxing club, Ironjaw: a brick wall under a steel beam, a red leather heavy bag hanging
from its chain and straps, a pair of gloves on a hook, the ring bell, the round clock and a corner of the ring.
The bag swings with real physics: brush it with the pointer to push it, tap anywhere to throw a punch at it -->
<canvas class="gym__back" data-back aria-hidden="true"></canvas>
<canvas class="gym__canvas" data-canvas role="img" aria-label="A boxing gym: a red leather heavy bag hangs from a chain under a steel beam in front of a brick wall, with a pair of blue gloves on a hook, a brass ring bell, a round clock and the corner of a ring. Tap to throw a punch at the bag."></canvas>
<header class="gym__bar">
<span class="gym__brand"><span class="gym__brand-mark" aria-hidden="true"></span>Ironjaw</span>
<span class="gym__hours">Boxing club · open six till ten</span>
</header>
<section class="gym__copy">
<p class="gym__kicker" data-in>Classes for every level</p>
<h1 class="gym__title" aria-label="Hit harder. Breathe easier.">
<span class="gym__line"><span data-line>Hit harder.</span></span>
<span class="gym__line"><span data-line>Breathe <em>easier.</em></span></span>
</h1>
<p class="gym__lede" data-in>Bag work, pads and skipping in a brick gym under the railway arches.</p>
<a class="gym__button" href="#trial" data-button><span class="gym__button-tape" aria-hidden="true"></span><span class="gym__button-text">Book a trial class</span></a>
</section>
<p class="gym__hint" data-hint>Tap to throw a punch</p>
<p class="sr-only" aria-live="polite" data-said></p>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="script.js"></script>
</body>
</html>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.
32 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The boxing gym header with the heavy bag” from Animorio and fit it into my siteThe wall, the beam, the floor, the ring corner, the hook, the bell plate and the clock frame change only with the size: they are drawn once on a background canvas. On top, every frame: the bag's shadow, the clock, the bell, the chain, the straps, the bag, the hanging gloves, the punching glove and the dust.
A fixed point on the bracket, a point for each chain link, the swivel ring and the bag as two heavy points, top and bottom. Every step (1/120 of a second) each point keeps the motion it had and falls a little; then sixteen rounds of constraints restore the distances. The chain and straps only pull when taut, while the bag is rigid both ways.
A hit moves back the previous position of the bag's two points: it is like giving them speed. The point nearer to where the punch lands gets more, so a low hit turns the bag as well as moving it. Meanwhile the bag widens and shortens a little and dents with a shadow where it was hit; both go back with an exponential decay.
It arrives in 0.13 seconds braking (a cubic), rests six hundredths on the bag and goes back in 0.24. It starts from the side of the bag you touched and hits at the height of your finger, between 16 and 82 per cent of the bag. The real hit happens when the glove touches, not on the click.
The dust is specks with their own gravity and drag that fade out; the impact marks are five lines moving apart. The hanging gloves are two short pendulums that get a push at every hit and from the passing pointer; the bell shakes and its striker beats when the hit is stronger than a jab.
| Name | File | Default | What it changes |
|---|---|---|---|
PUNCH | script.js | 1 | How hard the glove hits. |
PUSH | script.js | 1 | How much a mouse brushing past the bag pushes it (0 none). |
GRAVITY | script.js | 1 | Gravity: higher, the bag swings faster. |
DAMPING | script.js | 0.5 | How much the air brakes: higher, the bag stops swinging sooner. |
AUTO_EVERY | script.js | 2.6 | Seconds between combinations when nobody touches. |
DUST | script.js | 18 | The dust specks at every hit. |
LINKS | script.js | 7 | The links of the chain. |
--bag, --tape, --wall… | style.css | rosso, giallo, blu notte | The colours in :root: the canvas reads them again by itself when they change. |
For the header of a boxing, kickboxing or martial arts gym, a neighbourhood gym, a personal trainer, a sports equipment shop or a workout app. It is a toy: the real hours and prices also need to be in plain text.
Same physics and same drawing, adapted sizes: the words top left, the bag on the right, the hanging gloves lower down; bell and clock only where there is room. A finger taps and the glove goes; the page scrolls as usual.
The bag hangs still and straight on the chain and no glove flies: a tap only makes the hit's shadow appear and fade. The words fade in.
GSAP 3.15.0, Big Shoulders Display (font variabile) 5.3.0, Bricolage Grotesque (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 13 KB; the libraries: GSAP 28 KB.
Tested on 23 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.