Skip to content
animorio
IT
All components

The call button

Buttons, Transitions, SVGGSAPMediumCompressed weight: Demo 6.4 KBGSAP 28 KBFreeDownload the zip

A whole phone call in one button: clicked, the handset rocks and rings and the pill swells at every ring; when Nora answers the pill opens into the dark call bar, with the avatar, the running time and the voice level, and the handset crosses the bar to become the red key that hangs up. Once the call is over, the bar turns back into a grey pill that says how long it lasted.

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 call button</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/funnel-sans@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the call button: clicked, the handset rings; when Nora answers, the button opens into the call bar and the
         handset travels to the red key that ends the call -->
    <div class="call" data-call data-autoclic>
      <div class="call__shell" data-shell>
        <button class="call__start" type="button" data-start>
          <span class="call__label"><span class="call__word" data-word>Call Nora</span></span>
        </button>
        <span class="call__avatar" aria-hidden="true" data-avatar>NL</span>
        <span class="call__who" data-who>
          <span class="call__name">Nora Lind</span>
          <span class="call__line"><span class="call__time" data-time>0:00</span><span class="call__level"><span class="call__bars" aria-hidden="true" data-bars><i></i><i></i><i></i><i></i></span><span class="call__muted" aria-hidden="true" data-muted>Muted</span></span></span>
        </span>
        <button class="call__mute" type="button" aria-pressed="false" aria-label="Mute" data-mute>
          <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21"/><path class="call__slash" d="M4 4l16 16" pathLength="1" data-slash/></svg>
        </button>
        <span class="call__phone" aria-hidden="true" data-phone>
          <span class="call__ripple" data-ripple></span>
          <svg viewBox="0 0 24 24"><path d="M6.6 3.5l2.2 2.9c.5.7.4 1.6-.2 2.2L7.3 9.9a12.2 12.2 0 0 0 6.8 6.8l1.3-1.3c.6-.6 1.5-.7 2.2-.2l2.9 2.2c.8.6.9 1.7.2 2.4l-1.3 1.3c-1 1-2.6 1.4-4 .9A18.3 18.3 0 0 1 2.7 9.3c-.5-1.4-.1-3 .9-4L4.9 4c.5-.6 1.2-.8 1.7-.5z"/></svg>
        </span>
        <button class="call__end" type="button" aria-label="End the call" data-end></button>
      </div>
      <p class="call__hint"><span data-hint>Nora is on her mobile</span></p>
      <p class="sr" aria-live="polite" data-say></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.

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

What it does

On a white background a green pill with a handset in a white circle and the words Call Nora, and below the line Nora is on her mobile. Clicking, the words become Calling Nora and the pill widens as much as it needs; the handset rocks in bursts, a white ring moves away from it and the pill swells a little at every ring, with a pause between one ring and the next. When Nora answers, the words leave and the pill opens into the dark call bar: the avatar with NL arrives with a bounce, Nora Lind and the time running from 0:00 come in, with four green bars moving like a voice, and a key with a microphone; meanwhile the handset crosses the bar turning and going red, and becomes the key that hangs up. With the microphone off, a slash draws itself across the microphone and the word Muted takes the place of the green bars. Hanging up, the bar shrinks into a grey pill that says Call ended after and the length, the handset goes back to the left, grey and upright, and soon after the button is green again with Call Nora. Clicking while it rings stops it and says Call cancelled.

How it works

A pill that takes the size of its words

The pill's width is measured with an invisible copy of the words, plus the handset's room on the left and a margin: each time the words change they roll up and the pill widens or narrows with power3.out.

The ring

The ringing is a repeating timeline: the handset rocks between −SHAKE and SHAKE degrees in half a second (keyframes), a ring leaves the circle and widens up to 1.8 times as it fades, the pill passes through a scale of 1.03; then 0.32 seconds of silence. After RING seconds Nora answers.

The pill becomes the bar

When Nora answers GSAP takes the pill to WIDE pixels (or the screen minus 48) and to 72 high, from green to the bar's colour, with expo.out; at the same time and with the same curve the handset goes from its place to the red key's (a shift, a scale from 44 to 48 pixels, a 135 degree turn and the colour), so it gets there together with the edge of the bar. Avatar, name and microphone come in after, one behind the other.

The time and the voice

On GSAP's ticker the time is counted from the moment of the answer and rewritten only when the second changes; the four bars have heights made of sines at different frequencies, never under 6 pixels, so they stay bars and never turn into dots. The microphone off lowers them and fades them, and writes Muted.

Keys, focus and the preview

The red key is a transparent button over the handset that has arrived there; with the keyboard, when Nora answers the focus moves onto it, and once the call is over it goes back to the green button. Escape hangs up or stops calling. A click from a script (the library's preview) makes the call, and the next click ends it.

Values to change

NameFileDefaultWhat it changes
RINGscript.js1.4The seconds it rings before Nora answers.
WIDEscript.js320How wide the call bar opens, in pixels.
SHAKEscript.js14How far the handset rocks while it rings, in degrees.
BACKscript.js1.6The seconds the button says how long the call was, before it is ready again.

Try them in the Playground

When to use it

For the site of a restaurant, a hotel or a practice people call from their phone, for customer service, for an app that puts people in touch: anywhere a call should feel alive from the button on.

On phones

The bar opens at most as wide as the screen minus 48 pixels; the red key and the microphone measure 48 and 44 pixels, easy for a finger, and at a touch the pill gives a little.

With reduced motion

The call goes through the same steps without motion: while it rings no rocking, ring or breathing (the words Calling Nora say it), the bar and the handset are in their places at once, the voice bars stand still at different heights and the words change without rolling.

Pitfalls

  • A ring left halfway by an interrupted timeline stays where it is: when Nora answers it has to be switched off by hand, or it stays round the red key.
  • Voice bars that are too short look like little squares: never under 6 pixels, and with the microphone off they go and the word Muted appears.
  • Hiding the green button while it has the focus makes the page lose the focus: with the keyboard the focus must be moved to the red key, and brought back once the call is over.
  • The right width of the pill depends on the typeface: it must be measured again once the typeface has loaded (document.fonts.ready), or it keeps the fallback's width.
  • The red key drawn and the one to press are two different things: the travelling handset is only a drawing (pointer-events none), the transparent button over it is the real one, labelled End the call.

Libraries

GSAP 3.15.0, Funnel Sans (font variabile) 5.3.0.

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

Testing

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