Skip to content
animorio
IT
Back to the library

The curling letters that stop in the house

Physics, HoverGSAP, CSS onlyMediumCompressed weight: Demo 8.0 KBGSAP 28 KBFreeDownload the zip

A minimal physics piece: on warm white ice, a row of granite curling stones with one letter each. One at a time they move up to the hack, take aim and glide up the sheet, slowed by friction and bent by their curl, until they stop in the house, the rings at the far end, where they spell the word. The stones really collide; the one at the hack can be dragged and thrown.

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>Curling letters</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage" data-stage aria-label="Curling stones with a letter each slide up the ice and stop in the house, where they spell a word.">
    <header class="top" aria-hidden="true">
      <span class="top__brand">Northrink</span>
      <span class="top__note">Curling club</span>
    </header>

    <!-- the sheet of ice: lane lines, hog line, the house with its rings; drawn by the script -->
    <svg class="sheet" data-sheet aria-hidden="true"></svg>

    <!-- the stones, one per letter, built by the script -->
    <div class="stones" data-stones aria-hidden="true"></div>

    <p class="sr" data-sr>Glide</p>
    <footer class="bottom" aria-hidden="true">
      <span class="hint" data-hint>Drag the stone and let go</span>
      <span class="status"><span class="status__n" data-count>0</span> <span data-status-text>of 5 in the house</span></span>
    </footer>
  </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.

20 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 curling letters that stop in the house” from Animorio and fit it into my site

What it does

On a warm white page a curling sheet seen from above is drawn in hairlines: the two sides, the back line, the hog line and at the top the house, two grey rings and the blue button, with the lines crossing at the centre. At the bottom a row of granite stones waits, each with one letter of the word GLIDE. The first moves up to the hack with a small lift, steps sideways to take aim and sets off: it glides up the ice slowing down with the friction, turns on itself and, as it slows, its curl bends it into a light arc until it stops in the house. As it stops it turns back upright on a spring and its letter takes on weight. The others arrive one after another, each next to the one before, and the word builds across the button; when it is complete the button lights up in a light blue, the stones give a small hop in a row and the counter at the bottom reads the word. Then the stones fade and a new end begins. The stone at the hack can be picked up with the mouse or a finger and thrown: it leaves with the speed of your hand, and a sideways flick gives it its curl. Stones that touch collide, with a small ring spreading from the point of the hit; a stone that leaves the sheet is out and fades.

How it works

Physics in stone radii

Everything is computed in stone radii, with the origin on the button of the house: the distance from the hack changes with the shape of the screen, but the rules stay the same. The step is fixed, 1/120 of a second, driven by the GSAP ticker: so the ice behaves the same on every screen and in the video.

Friction and curl

At every step the stone loses FRICTION radii per second of speed against its motion, and gets a sideways push, in the direction of its turn, that grows as it slows: CURL · 0.55 / (1 + v / 2.5). That is why the curve shows mostly at the end, as on real ice.

Aim found by simulating

For the throws it plays by itself, before letting go the script slides an invisible stone with the same rules and corrects the start and the speed until it stops on its spot in the house, next to the one before: fourteen tries at most, then the real stone sets off.

The hits

Two stones that touch are pushed apart and exchange speed along the line between them, with equal masses and a loss set by BOUNCE. A thin ring spreads from the point of the hit and both stones squash for a moment on a spring.

The stone at rest

When a stone stops, its angle goes back to the nearest whole turn with elastic.out, so the letter straightens with a small settle; if it stopped in the house it lifts a little and the letter takes on weight. If a hit sets it moving again, it loses the weight and will stop again.

Values to change

NameFileDefaultWhat it changes
WORDscript.js'GLIDE'The word the stones spell in the house, 3 to 6 letters.
FRICTIONscript.js4How much the ice slows a stone, in stone radii per second squared (1 slick, 8 sticky).
CURLscript.js1How much a spinning stone bends as it slows (0 straight, 3 a lot).
BOUNCEscript.js0.85How much speed two stones keep when they hit (0.1 dull, 1 like billiard balls).
SPINscript.js1How fast the stones turn on themselves while they slide (0 still, 4 fast).
STONEscript.js1The size of the stones (0.6 small, 1.3 large).
RESTscript.js2.4The seconds the finished word rests in the house before a new end.

Try them in the Playground

When to use it

For a curling or winter sports club, an ice rink, an event on ice, a board game or a bowls and shuffleboard app; also as the headline of a page about precision, aim or landing in the right spot.

On phones

The same animation with the sizes adapted: the stones are measured on both the width and the height of the screen, the sheet is shorter and the throws are shorter. The stone at the hack is dragged and thrown with a finger; on the stage the page does not scroll.

With reduced motion

Nothing slides: the word is already in the house, the stones at rest in a row across the button, and it fades in.

Pitfalls

  • With a variable step the same stone stopped in different places depending on the frames: the fixed step of 1/120 of a second makes it the same everywhere, and the simulated aim matches the real throw.
  • A stone already at rest, hit by another, stayed «at rest» for the script and no longer counted: now as soon as it moves again it loses that state and settles when it stops again.
  • GSAP cannot move x and y while the hand holds the stone: when it is picked up the stone’s tweens are stopped, and the throw starts from the speed of the hand’s last moves.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Testing

Tested on 24 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