Skip to content
animorio
IT
Back to the library

The ball that bounces on the syllables

Text, PhysicsGSAPMediumCompressed weight: Demo 8.2 KBGSAP 28 KBFreeDownload the zip

A sing-along headline in the minimal style: a phrase in a variable face, the syllables still to sing pale and thin, and a vermilion ball hopping from syllable to syllable on true parabolas. Every syllable it touches gives under the ball, takes on weight and turns to ink. At the end the ball drops onto the line and bounces lower and lower; you can grab the ball and throw it, and it sings whatever it lands on.

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>Bouncing ball</title>
  <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="stage" data-stage aria-label="Sing a little melody. A small ball bounces from syllable to syllable, and every syllable it touches is sung.">
    <header class="top" aria-hidden="true">
      <span class="top__brand">Little Choir</span>
      <span class="top__note">Karaoke on Fridays</span>
    </header>

    <!-- the phrase, one span per syllable, built by the script; the ball bounces on top of it -->
    <div class="song" data-song aria-hidden="true">
      <div class="lines" data-lines></div>
      <svg class="rule" data-rule-svg aria-hidden="true"><path data-rule d="" /></svg>
      <span class="shadow" data-shadow></span>
      <span class="ball" data-ball><span class="ball__body" data-ball-body></span></span>
      <span class="hit" data-hit></span>
    </div>

    <p class="sr">Sing a little melody</p>
    <p class="hint" aria-hidden="true">Grab the ball and throw it</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>

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.

18 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 ball that bounces on the syllables” from Animorio and fit it into my site

What it does

On a warm white page a phrase appears on two lines, Sing a little / melody, split into syllables: the syllables still to sing are pale, thin and narrow. Under the phrase there is a hairline. A vermilion ball with a small highlight drops from above onto the first syllable and then hops from one syllable to the next on true parabolas, like the ball of an old sing-along: it lands on the top of the letters, not on the line box, so it sits higher on an S or an l and lower on an a or an o. At every landing the ball squashes and wobbles back to round, and the syllable it touches gives a few pixels under it, widens, takes on weight and turns to ink, then springs back up; the next syllable feels the hit and dips a little. After the last syllable the ball drops onto the line, which gives a little where it lands, and bounces lower and lower until it rests, its shadow shrinking and fading as it rises. Then the phrase goes pale again from the last syllable to the first, and the ball hops back to the start. You can grab the ball with the mouse or a finger: it grows a little in your hand, and when thrown it flies with real gravity, bounces off the letters, the line and the edges and sings every syllable it lands on; when it rests it sets off by itself towards the first syllable still to sing.

How it works

True parabolas

Every hop lasts one BEAT and passes HOP times the type size above the higher syllable. From the start, the end and the height of the top of the arc the hop's gravity follows: g = (√(2·(y0 − top)) + √(2·(y1 − top)))² / BEAT², and so does the upward speed at the start. Horizontally the ball moves at a constant speed, vertically y = y0 − v·t + ½·g·t²: a true parabola that slows on the way up and speeds up on the way down, landing on the syllable exactly at the end of the beat.

The top of the letters

The spot where the ball lands is the real top of each syllable: a hidden canvas measures the text in the face at its sung weight (measureText, actualBoundingBoxAscent) and the baseline comes from the line height and the face's ascent. So on Sing the ball sits higher than on a, and on melody it goes down and up with the letters.

The syllable that takes on weight

Every syllable is a span inside another: GSAP moves the outer one (it gives 0.07 em and squashes in 7 hundredths, then springs back with elastic.out), the inner one carries the weight and width of variable Bricolage Grotesque, from IDLE to SUNG and from 92% to 100%, with back.out. Each syllable's width is measured already sung and the outer span holds it, so the change of weight does not move the phrase.

The physics of the throw

In your hand the ball follows the pointer with a small lag; let go, it leaves with the speed of the last six moves. From there it is free: gravity is the hops' gravity, the letters are ledges it can land on only on its way down, the line is the floor and the edges of the page are the walls; at every hit it keeps BOUNCE of its speed. When it has been still for almost half a second it sets off with a hop towards the first syllable still to sing.

The squash and the line

The ball's squash and the line that gives are two springs computed at every frame on the GSAP ticker (acceleration = −k·x − c·v): the hit gives the push, in proportion to the speed, and the spring settles back to zero with a small wobble. The line is an SVG path that turns into a Gaussian bell a few pixels deep under the ball.

Values to change

NameFileDefaultWhat it changes
PHRASEscript.js'Sing a lit-tle / mel-o-dy'The phrase: a slash starts a new line, hyphens split the syllables of a word.
BEATscript.js0.46The seconds of every hop from one syllable to the next.
HOPscript.js0.62How high the ball hops above the syllables, in fractions of the type size.
BOUNCEscript.js0.58How much of its speed the ball keeps at every bounce (0.2 dead, 0.85 lively).
SUNGscript.js720The weight of a sung syllable (200 to 800).
IDLEscript.js300The weight of a syllable still to sing (200 to 800).
SQUASHscript.js0.3How much the ball squashes when it lands.
RESTscript.js1.2The seconds the ball rests on the line before the phrase starts again.

Try them in the Playground

When to use it

For a site that lives on voice and rhythm: a singing school, a choir, a karaoke night, an app to learn lyrics or diction, a music festival. Also as the headline of a page for children or of a lesson about syllables.

On phones

The same animation with the sizes adapted: the phrase goes on two lines and is measured on both the width and the height of the screen, and the ball is smaller. You grab and throw the ball with a finger; elsewhere on the phrase the page scrolls as usual.

With reduced motion

Nothing hops and nothing squashes: the ball fades in above one syllable at a time, the syllable takes on weight and turns to ink with a fade, and at the end the phrase goes pale again.

Pitfalls

  • With fixed gravity and a fixed duration the top of the arc changed at every hop and from one line to the next the ball went too high or too low. Now the top is fixed above the higher syllable and the gravity is worked out for every hop: the parabola is always true and always lands on time.
  • When the ball landed on the syllable's box it looked as if it floated above the low letters. The top is measured with the real text on a canvas, at the sung weight, which is what you see when the ball arrives.
  • The inline transform the script writes on the ball also cancels the CSS scale property: the hover growth is worked into the same transform, together with the squash.

Libraries

GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 8.2 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