Skip to content
animorio
IT
All components

The airplane mode switch

Toggles, SVG, Hover, TextGSAP, CSS onlyMediumCompressed weight: Demo 5.7 KBGSAP 28 KBFreeDownload the zip

The airplane mode switch, in the minimal style: the track is a dashed runway and the knob a small plane seen from above, which takes a run-up, lifts off leaving its shadow on the ground and flies on in orange, while the Wi-Fi waves go out one by one.

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 airplane mode switch</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">
    <div class="setting" data-setting>
      <div class="setting__text">
        <label class="setting__name" id="air-name" for="air-switch">Airplane mode</label>
        <span class="setting__sub" aria-hidden="true">
          <svg class="wifi" viewBox="0 0 20 14" aria-hidden="true" focusable="false">
            <path class="wifi__arc" data-arc d="M7.6 11.2 A3.4 3.4 0 0 1 12.4 11.2"></path>
            <path class="wifi__arc" data-arc d="M5.2 8.6 A6.8 6.8 0 0 1 14.8 8.6"></path>
            <path class="wifi__arc" data-arc d="M2.7 6 A10.2 10.2 0 0 1 17.3 6"></path>
            <path class="wifi__cut" data-cut d="M3 12.6 L17 1.4"></path>
          </svg>
          <span class="setting__subwords">
            <span class="setting__s" data-sub-off>Wi-Fi and cellular on</span>
            <span class="setting__s" data-sub-on>All radios off</span>
          </span>
        </span>
      </div>
      <div class="setting__ctrl">
        <span class="setting__word" id="air-word" aria-hidden="true">
          <span class="setting__w" data-word-off>Off</span>
          <span class="setting__w" data-word-on>On</span>
        </span>
        <button class="switch" id="air-switch" type="button" role="switch" aria-checked="false" aria-labelledby="air-name air-word" data-switch data-autoclic>
          <svg class="switch__art" viewBox="0 0 104 56" aria-hidden="true" focusable="false">
            <rect class="switch__track" x="1" y="1" width="102" height="54" rx="27"></rect>
            <line class="switch__runway" data-runway x1="12" y1="28" x2="92" y2="28"></line>
            <ellipse class="switch__shadow" data-shadow cx="0" cy="0" rx="13" ry="2.8"></ellipse>
            <path class="switch__trail" data-trail d=""></path>
            <g data-knob>
              <circle class="switch__knob" cx="0" cy="0" r="17"></circle>
              <path class="switch__plane" data-plane d="M11 0 C11 1.2 9.6 1.6 8 1.6 L3.2 1.6 L-1.8 9 L-4.4 9 L-1.6 1.6 L-6.4 1.6 L-8.4 4.4 L-10.4 4.4 L-9.2 0 L-10.4 -4.4 L-8.4 -4.4 L-6.4 -1.6 L-1.6 -1.6 L-4.4 -9 L-1.8 -9 L3.2 -1.6 L8 -1.6 C9.6 -1.6 11 -1.2 11 0 Z"></path>
            </g>
          </svg>
        </button>
      </div>
    </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.

16 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 airplane mode switch” from Animorio and fit it into my site

What it does

On a white page, between two thin rules, the ‘Airplane mode’ setting with the Wi-Fi symbol and the line ‘Wi-Fi and cellular on’ under it; on the right the word ‘Off’ and the switch. The track is a runway: a hairline pill with a dashed line down the middle, and the knob is a white disc with a small black plane inside seen from above, with its shadow under it. On a click (or a tap, Space, Enter or the right arrow) the plane takes a run-up, speeding up as the runway dashes stream under it, lifts its nose and leaves the ground: the disc rises a few pixels and the shadow stays on the runway, falls behind and gets small. Two hair-thin orange trails stream from its wingtips and fade. It reaches the far end on a spring that goes a pixel past, turns orange and stays in the air, rising and sinking a touch. Meanwhile the Wi-Fi waves go out one after the other from the outermost, an orange line crosses them, the line becomes ‘All radios off’, ‘Off’ thins away and ‘On’ comes in narrow and light and takes weight. Another click (or the left arrow) brings it down: it descends, touches the runway with a small squash and rolls back braking, and the waves come back on. With the pointer over it the plane edges forward; pressed, it sinks a little.

How it works

One state

Everything is in one object of numbers: the position on the runway p, the height, the nose, the squash, the breath of the flight, the lean, the press, the colour and the word. A single render function writes them on every frame: the knob's hand-built transform (translate and scale), the plane's rotation, the shadow that stays on the runway, the streaming dashes and the word's axes.

The take-off

A GSAP timeline takes p to 0.55 with power2.in, the run-up speeding up; meanwhile the nose rises PITCH degrees and the height reaches CLIMB pixels, then p goes to 1 with back.out(SPRING), which goes past by about a pixel and comes back. The colour moves from black to orange with gsap.utils.interpolate and at the end a breath up and down of HOVER pixels starts, as a yoyo.

The streaming runway

The line down the middle of the track has stroke-dasharray 4 4: its stroke-dashoffset follows p times the run times STREAM, so the dashes stream under the plane faster than it moves, like the runway seen from the window. The shadow is an ellipse that does not rise: with the height it moves back, narrows and fades.

The landing

The nose drops a few degrees, the height goes back to zero and on touchdown the knob squashes (wider and lower) and recovers with elastic.out; then p goes back to 0 with back.out, braking with one pixel too many. The Wi-Fi waves come back on from the innermost.

Accessible

It is a button with role="switch" and aria-checked, labelled by the setting's name and the word; Space and Enter turn it like a click, the right and left arrows switch it on and off, and focus shows as an orange ring. A click halfway stops the running turn and starts the new one from where the plane is.

Values to change

NameFileDefaultWhat it changes
TAKEOFFscript.js0.95How long the take-off takes, in seconds (the landing is a little shorter).
CLIMBscript.js3How high the plane flies above the runway, in pixels.
PITCHscript.js10How far the nose lifts at take-off, in degrees.
SPRINGscript.js1.6How far the plane goes past the far end (0 not at all; 1.6 is about a pixel).
HOVERscript.js0.7How much the plane rises and sinks while it flies, in pixels (0 still).
STREAMscript.js2.2How fast the runway dashes stream under the plane, against its own speed.
PEEKscript.js3How far the plane edges forward under the mouse, in pixels.

Try them in the Playground

When to use it

For an on or off setting in the settings of an app or a dashboard: airplane mode, offline mode, sync, notifications on a trip. It also suits the profile page of a flights or travel site.

On phones

The same with a tap: the switch stays 104 by 56, the setting's row narrows to the screen's width and the line under the name wraps if it needs to.

With reduced motion

No run-up and no flight: the plane is already at the far end, in orange, with its shadow under it; the words swap in a short fade, the line and the Wi-Fi waves change at once.

Pitfalls

  • GSAP's transforms on the knob's group inside the SVG moved the centre of rotation: now the transform is written by hand in render, and the plane turns around its centre with rotate(degrees 0 0).
  • The breath of the flight carried on after landing, adding up to the zero height: now it stops and resets at the start of every turn.
  • The switches already in the library use a lamp, a moon, a lever: here the idea is another, the track as a runway and the knob leaving its shadow behind.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Testing

Tested on 23 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 components