
Tiles that rise
SVG, Hover, Physics
NewFree
A billiard table seen from above: the cue aims with the pointer, draws back and breaks the rack with real physics. The balls really roll, the potted ones spin down a small whirl into the ball return, then the triangle puts everything back.
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 billiard break</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/standard.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mona-sans@5.3.0/standard.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="sala">
<header class="testa">
<p class="sopra">The Baize Room Billiard Club</p>
<h1 class="titolo">Break the rack</h1>
<p class="riga">Aim with the pointer: the farther away it is, the harder the cue hits. Click the table to shoot.</p>
</header>
<!-- the table is drawn by the script: felt, rails, pockets, fifteen numbered balls and the cue -->
<div class="tavolo" data-tavolo>
<svg class="tavolo__svg" data-svg role="img" aria-label="A billiard table seen from above, with fifteen balls racked in a triangle"></svg>
</div>
<div class="piede">
<div class="conti">
<p class="conto"><span class="conto__nome">Potted</span> <span class="conto__num" data-imbucate>0</span><span class="conto__su">/15</span></p>
<p class="conto"><span class="conto__nome">Breaks</span> <span class="conto__num" data-colpi>0</span></p>
<p class="stato" aria-live="polite"><span class="stato__testo" data-stato>Table is set</span></p>
</div>
<!-- the ball return: potted balls roll in here -->
<div class="vassoio" data-vassoio aria-label="Ball return"></div>
<button type="button" class="tiro" data-tiro data-autoclic>
<span class="tiro__fondo" aria-hidden="true"></span>
<span class="tiro__testo">Break</span>
</button>
</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>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.
41 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 billiard break” from Animorio and fit it into my siteNo libraries: for identical balls a few lines are enough. At every step the cloth takes away speed (a constant friction plus one that grows with speed), then every pair of touching balls is checked: they are separated and exchange the impulse along the line of centres, with a coefficient of restitution. There are as many steps as needed so that no ball moves more than a third of its radius: this way no ball passes through the others on the break.
Each cushion is a segment, and at the pockets it continues with two slanted segments, the jaws. For each ball the closest point of each segment is found: if it is closer than the radius the ball is pushed out and its velocity bounces along the normal. The same rule makes the bounces off the cushions and the balls that rattle on the pocket edge and stay out.
Each ball keeps two 3D vectors: the pole of the number and the axis of the stripe. When it moves by d, they rotate by d over the radius around the horizontal axis perpendicular to the motion. Number and stripes are caps of the sphere seen from above: their rim is sampled and the points behind the ball are pushed onto the outline, so every frame becomes an SVG path.
The cue is drawn once with its tip at zero and moves with a single transform: cue ball position, aim angle and distance. The angle chases the pointer with an exponential ease, and the distance tells the power. The shot is a GSAP timeline: wind-up, pause, sharp strike, and only at the end of the strike does the cue ball get its speed.
A potted ball leaves the physics and a GSAP timeline spirals it towards the centre of the pocket, the way it was running, while it shrinks and rolls. When everything has stopped, a delayedCall waits for the pause and then the triangle racks the balls again: there too every ball rolls as it goes back to its place.
| Name | File | Default | What it changes |
|---|---|---|---|
POTENZA | script.js | 3400 | The cue ball’s speed on the hardest shot, in table units per second (the table is 1000 long). |
ATTRITO | script.js | 270 | How much the cloth slows the balls: higher, the break ends sooner. |
SPONDA | script.js | 0.78 | How much the balls bounce off the cushions (1 = losing nothing). |
URTO | script.js | 0.95 | How elastic the collisions between balls are. |
EFFETTO | script.js | 0.3 | Spin on the cue ball: positive follows on after the hit, negative draws it back. |
PAUSA | script.js | 0.9 | Seconds to wait, with the balls still, before the triangle racks them again. |
GUIDA | script.js | true | The aiming line with the ghost ball. |
For the page of a bar, a club or a game, a playable 404 page or a moment of fun inside a site: it is a toy, and belongs where visitors have time.
The table turns upright so it stays large. With no hover, a tap does it all at once: it aims at the finger and shoots, with the power given by the distance. The button shoots along the starting aim.
No motion: the whole break is computed at once, the balls fade out and reappear where they stopped; the triangle racks them again with a fade too.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Mona Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 15 KB; the libraries: GSAP 28 KB.
Tested on 11 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.