Skip to content
animorio
IT
All components

The tip button

Buttons, SVG, PhysicsGSAPMediumCompressed weight: Demo 5.3 KBGSAP 28 KBFreeDownload the zip

Every press throws a coin from the button into the glass jar: the coin flies in an arc turning over and over, drops in through the mouth, lands on the pile with a little bounce, the jar rocks and the total goes up. Pressed many times, many coins fly at once.

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>The tip button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/afacad@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the tip button: every press throws a coin from the button into the glass jar, turning over in the air; it
         lands on the pile and the total under the button goes up. Above the jar there is nothing: the coins fly there -->
    <div class="tip" data-tip data-autoclic>
      <div class="tip__jar">
        <svg class="tip__art" aria-hidden="true" data-art></svg>
      </div>
      <button class="tip__btn" type="button" data-btn>
        <span class="tip__coin" aria-hidden="true" data-coin></span>
        <span>Tip $1</span>
      </button>
      <p class="tip__total"><span class="tip__roll"><span data-total>$0</span></span> <span class="tip__said">tipped this week</span></p>
      <p class="sr" aria-live="polite" data-live></p>
    </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>

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.

15 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 tip button” from Animorio and fit it into my site

What it does

On a white background a glass jar with the word TIPS and six gold coins at the bottom, below it a dark green button with a coin and Tip $1, and below that the line $6 tipped this week; above the jar there is only empty space, where the coins fly. On arrival the coins drop into the jar one after the other, bouncing, and the button comes up from below. Pressed, the button's coin pulses, the button gives and comes back, and from the button's coin a coin just like it flies in an arc over the jar's mouth turning over and over, like a coin tossed; beside the mouth a +$1 rises and fades. The coin goes in, now behind the glass, drops onto the pile in its place and bounces a little, the jar rocks on its base and the total rolls to the new number. The coins settle in layers, four and then three in the gaps between those below; once the jar is full, new ones land on top and vanish into the pile.

How it works

One drawing over the whole component

A single SVG covers the whole component, with a 60 pixel margin, and has four groups in this order: the glass behind, the pile, the front of the glass (rim, gleam and label) and the air. The jar is drawn where its box is in the page (offsetLeft and offsetTop), so the coin flies from the button to the jar within the same drawing.

The arc and the spin

The flight is a quadratic Bézier curve from the button's coin, measured at every toss, to above the place waiting for it, at the height of the mouth, with the control point TOSS pixels above the higher of the two ends. The face is a circle squashed vertically by |cos(t · SPINS · π)|, never under 0.1: it is seen more and more edge-on and then full again, while it turns slowly.

Inside the glass

At the mouth the coin moves into the pile's group, which is under the front of the glass: from there it is seen through the glass. It drops with power2.in in the time a real fall from that height takes (the square root of 2h over 2600), then it gives way to a coin lying down, edge and ellipse, which bounces 5 pixels, and the jar rocks 1.6 degrees round the middle of its base with elastic.out.

The pile

The places are in alternate layers of four and three coins, 6 pixels higher each layer and each shifted a little, so they do not look like a grid; past 26 coins new ones land on top and fade away. GSAP moves only the inner group of a coin lying down: the outer one holds its place in the transform attribute, which a GSAP transform would replace.

The total and the preview

The total goes up when the coin touches the pile: it leaves upwards and the new number comes in from below with back.out(2), and an aria-live region says how much has been given. Every press is independent, so several coins fly at once. A click from a script (the library's preview) throws two coins, 0.32 seconds apart.

Values to change

NameFileDefaultWhat it changes
TOSSscript.js110How high the coin flies over the jar's mouth, in pixels.
SPINSscript.js2How many times the coin turns over in the air.
FLIGHTscript.js0.7The seconds from the button to the jar's mouth.
STARTscript.js6The coins already in the jar.

Try them in the Playground

When to use it

For tips and small repeated donations: the tip jar of a café or a creator, support for a podcast, a fundraiser, the points of a loyalty card, a piggy bank in a savings app.

On phones

The jar is 168 pixels wide and the button at least 56 tall, so it all fits a narrow screen; every tap throws a coin without waiting for a double tap (touch-action manipulation), and tapping in a row sends several coins flying at once.

With reduced motion

No flight: the coin appears on the pile fading in over 0.2 seconds, with no +$1, the total changes without rolling, the button and its coin do not pulse and the jar does not rock; on arrival nothing moves.

Pitfalls

  • A GSAP transform on an SVG element that already has a transform attribute replaces it: that is why every coin lying down has two groups, the outer one with its place and the inner one GSAP moves.
  • The coin must go behind the glass only when it enters the mouth: it changes group (appendChild into the pile) halfway through the animation, instead of being drawn twice.
  • The starting point is measured at every toss with getBoundingClientRect, because the button and its coin pulse: measured once, the coins would set off from the wrong place.
  • The drawing is made again at a new window size and once the font has arrived, because the jar takes its place from the page; the coins already on the pile are drawn again in their places.
  • The rolling total must be stopped if another coin arrives (killing its timeline), or two rolls one over the other would leave the number half way.

Libraries

GSAP 3.15.0, Afacad (font variabile) 5.3.0.

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

Testing

Tested on 4 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: Done

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 components