Skip to content
animorio
IT
Back to the library

Words in the jar

Physics, TextGSAPAdvancedCompressed weight: Demo 10 KBGSAP 28 KBMatter.js 25 KBFreeDownload the zip

In the minimal style: a glass jar drawn with two hairlines and, at every click, a word that drops in, bounces and settles on the others with real rigid-body physics; it falls thin and narrow and takes its weight and width as it lands. The pointer tilts the jar and the words slide on the glass; emptying it, the jar turns over and the words slip out of its mouth.

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>Words in the jar</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>
  <!-- a glass jar drawn with two hairlines: a click drops a word in, the pointer tilts the jar and the words slide -->
  <main class="stage" data-stage>
    <button class="drop" type="button" data-drop data-autoclic aria-label="Drop a word into the jar"></button>

    <!-- the plumb line and the angle of the jar, drawn in the page -->
    <svg class="measure" data-measure aria-hidden="true">
      <path class="measure__plumb" data-plumb d="" />
      <path class="measure__axis" data-axis d="" />
      <path class="measure__arc" data-arc d="" />
      <text class="measure__label" data-angle x="0" y="0"></text>
    </svg>

    <!-- the jar and its words: one group, turned by the script around the middle of the jar -->
    <div class="jar" data-jar>
      <svg class="glass" data-glass aria-hidden="true">
        <path class="glass__outer" data-outer d="" />
        <path class="glass__inner" data-inner d="" />
        <path class="glass__lip" data-lips d="" />
      </svg>
      <div class="words" data-words aria-live="polite"></div>
    </div>

    <p class="hint" data-hint>Click to drop a word. Move to tilt the jar.</p>
    <button class="empty" type="button" data-empty data-autoclic>
      <span class="empty__text" data-empty-text>Empty the jar</span>
    </button>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/matter-js@0.20.0/build/matter.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.

25 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 “Words in the jar” from Animorio and fit it into my site

What it does

A warm white page and, in the middle, a glass jar drawn like a technical drawing: the outer wall is a thin black line, the inner one an even thinner grey line, and at the top the two close into a small round lip. The two walls draw themselves in opposite directions, from the left lip and from the right one, and over the mouth a dashed plumb line appears. Then five ingredients drop from above, one after the other: flour, salt, honey, rye, fig. While it falls a word is light (wght 300) and narrow (wdth 72), like someone running; when it touches the bottom or the other words it takes its weight and width on a spring (wght 640, wdth 100, a little past it and back), squashes a touch, the letters feel the blow from the middle outwards and the jar itself sinks a pixel and rocks a little towards the side the word fell on. The newest word is vermilion, and turns black when another one arrives. Every word is a real rigid body: it bounces, rests on the others, leans against the glass. Then the jar tilts by itself to the left and to the right and the words slide along the bottom: over the mouth, next to the plumb line, the jar's axis and a vermilion arc with the degrees appear. Every click drops a new ingredient; the pointer tilts the jar its way, up to 14 degrees. Empty the jar turns the jar over: it goes past 130 degrees, gives a few shakes, the words slip out of the mouth, lose their weight as they fall and fade at the bottom of the page; then the jar stands up again. When the jar is full, the next click empties it by itself and then drops the new word. With the mouse over Empty the jar, the label widens and the jar leans a few degrees, as if about to pour.

How it works

A jar in two lines

The jar is a group with its origin in the middle of the glass: inside are the SVG of the walls and the words, and the script moves and turns it with a single transform. The outer wall is a U path with round corners, the inner one the same path set in by the thickness of the glass and written backwards, so with pathLength 1 and stroke-dashoffset the two lines draw themselves in opposite directions. For the physics the glass is made of static bodies: two walls as thick as the glass, a floor and two triangles in the corners, so a word never gets stuck where the line curves.

Every word is a rigid body

Every word is a div holding its letters, and Matter.js keeps a rectangle as big as the word at its full weight. At every physics step (a hundred and eighty a second, inside gsap.ticker) the div takes its position and rotation from its body. The body has eight times the inertia of a plain box: a long thin word that touches the bottom at an angle rocks and lies down instead of flipping over. A small keel brings it gently back towards upright on the page, so the words stay readable; it never wins against the glass or the other words.

Tilting is turning gravity

The physics works inside the jar, which for it never moves: when the jar tilts by an angle, gravity in the physics turns by the same angle the other way (the sine and cosine of the angle). So the walls stay still and the words slide as if the glass were turning under them. The angle follows the pointer on a spring that goes just past and back; the plumb line, the jar's axis and the arc with the degrees are drawn in the page, outside the group that turns.

The landing

At a word's first knock (Matter's collisionStart event) a GSAP tween takes the weight of the type from LIGHT to HEAVY and the width from 72 to 100 with elastic.out, written in font-variation-settings. Meanwhile the ink squashes and comes back, the letters dip a pixel and a half one after the other from the middle, and the jar gets a small push down and a turn towards the side of the knock, damped by two springs. How hard the knock is, measured on the relative speed of the two bodies, decides how much.

Emptying the jar

Empty the jar is a GSAP timeline on the angle: the jar goes to 138 degrees, gives four shakes and waits. The glass turns slippery (the words' friction drops almost to nothing) and the keel switches off, so the words slip out of the mouth instead of jamming. A word that has left the glass loses weight and width as it falls, fades and its body leaves the physics; as soon as the jar is empty the wait is cut short and the jar stands up again. With reduced motion nothing moves: the physics runs all at once out of sight and the words fade in where they would come to rest.

Values to change

NameFileDefaultWhat it changes
WORDSscript.js['flour', 'salt', 'honey', 'rye', 'fig', 'thyme', 'butter', 'lemon', 'oats', 'basil', 'sugar', 'yeast']The words that drop into the jar, in this order (up to 12 letters each). The entrance drops the first five.
TILTscript.js14How many degrees the pointer can tilt the jar each way.
GRAVITYscript.js1.3How hard the words fall: the higher, the sharper the knock.
BOUNCEscript.js0.16How much a word bounces when it lands: 0 stops where it touches, 0.5 jumps.
FRICTIONscript.js0.06How well the words hold on the glass and on each other: the lower, the sooner they slide when the jar tilts.
LIGHTscript.js300The weight of the type while a word falls, from 100 to 900.
HEAVYscript.js640The weight the word takes as it lands.

Try them in the Playground

When to use it

To gather choices with a gesture: the ingredients of a recipe, the tags of an article, the flavours of an ice cream, the filters of a catalogue, the skills on a freelancer's page. It also works on its own, as a playful moment at the top of a food site, a pantry or a grocery shop.

On phones

The same jar with the sizes adapted: wider relative to the page, words a little bigger relative to the glass and the same physics, in proportion. A tap drops a word; dragging a finger left or right tilts the jar, and letting go stands it up again (a drag drops no word).

With reduced motion

Nothing falls and nothing tilts: the physics runs all at once out of sight and the words fade in already resting where they would land. Empty the jar fades them out; the jar stays upright.

Pitfalls

  • A word is a long thin box: dropping from the full height of the page and touching the bottom at the smallest angle, with plain inertia it rose onto its corner and flipped over, and after a few clicks half the words were upside down. With eight times the inertia, a little air drag while falling and a light keel, they rock and lie down.
  • The keel (the push that turns words back upright) kept the words crosswise against each other while the jar poured, and the pile no longer came out of the mouth: while the jar pours the keel switches off and the glass turns slippery.
  • Two words touching in mid-air, over the mouth, counted as landed and outside the jar, and vanished: a word leaves the jar only when it passes beyond the walls, not when it is higher than the mouth.
  • Jumping to the end of the entrance with progress(1) set off at once every word the entrance still had to drop, one inside the other, and the physics blew them apart: now the entrance jumps to its end without its callbacks, and two words dropped in the same moment start one above the other.
  • Tilting the jar by 10 degrees did not move the words: in Matter.js standing friction (frictionStatic) held them far more than the friction number says. With frictionStatic at 0 only FRICTION counts, and the slope that sets them off is the one you would expect.
  • The card's video stops when the picture stays the same for a second with no GSAP animation scheduled: while the physics is awake a gsap.delayedCall is always pending, and it only falls asleep when every word is still and the jar is at its angle.

Libraries

GSAP 3.15.0, Matter.js 0.20.0, Archivo (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 10 KB; the libraries: GSAP 28 KB, Matter.js 25 KB.

Testing

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