
The water button
Buttons, SVG, Physics, Hover
NewFree
A stage light hanging above the links lights the current one, with a warm beam and a pool of light behind the word. Pointing at another link the light swings over to it like a hanging lamp, going a little past and coming back, and each word lights up as the light passes over it; a click closes the beam in on the word and makes it flare.
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 spotlight nav</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/mozilla-headline@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the nav: a stage light hangs above the links and lights the current one; pointed at, another link draws the
light, which swings over to it, and a press makes it the current one with the beam closing in on it -->
<nav class="sl" aria-label="Main" data-nav>
<svg class="sl__light" aria-hidden="true" data-light>
<defs>
<linearGradient id="sl-beam" gradientUnits="userSpaceOnUse" data-beam-paint>
<stop offset="0" class="sl__beam-near"/>
<stop offset="0.72" class="sl__beam-mid"/>
<stop offset="1" class="sl__beam-far"/>
</linearGradient>
<radialGradient id="sl-pool">
<stop offset="0" class="sl__pool-mid"/>
<stop offset="0.6" class="sl__pool-half"/>
<stop offset="1" class="sl__pool-edge"/>
</radialGradient>
</defs>
<path fill="url(#sl-beam)" data-beam/>
<ellipse fill="url(#sl-pool)" data-pool/>
</svg>
<ul class="sl__list" data-list>
<li><a class="sl__link" href="#" aria-current="page" data-link>Shows</a></li>
<li><a class="sl__link" href="#" data-link data-autoclic>Tickets</a></li>
<li><a class="sl__link" href="#" data-link data-autoclic>Cast</a></li>
<li><a class="sl__link" href="#" data-link data-autoclic>Visit</a></li>
</ul>
<!-- an invisible frame round the light and the links, for the library's picture of the nav -->
<span class="sl__frame" aria-hidden="true" data-frame></span>
<!-- the light itself: the bar it hangs from, the yoke, the can and its lens -->
<svg class="sl__lamp" aria-hidden="true" data-lamp-art>
<g data-lamp>
<path class="lamp__yoke" d="M-17 14V0H17V14"/>
<rect class="lamp__can" x="-13" y="5" width="26" height="34" rx="5"/>
<rect class="lamp__band" x="-14.5" y="27" width="29" height="6" rx="2"/>
<path class="lamp__sheen" d="M-8 10V29"/>
<ellipse class="lamp__lens" cx="0" cy="39" rx="11" ry="3.4" data-lens/>
<path class="lamp__bolt" d="M3 0L1.5 2.6H-1.5L-3 0L-1.5 -2.6H1.5Z"/>
</g>
<rect class="lamp__bar" data-bar height="5" rx="2.5"/>
<path class="lamp__stem" data-stem/>
</svg>
</nav>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="script.js"></script>
</body>
</html>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.
12 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The spotlight nav” from Animorio and fit it into my siteThe light's angle is a spring towards the link's angle, taken with atan2 from the hinge to the middle of the word: every frame, in four small steps, the acceleration is SWING times the distance from the target minus DAMP times the speed, and with these values the light goes a little past and comes back. Two slow waves, of 0.35 and 0.25 degrees, are added to the target: the sway at rest.
From the lens, 39 pixels from the hinge along the light's direction, two edges leave at plus and minus SPREAD degrees from the direction, cut where they meet a line 16 pixels below the middle of the words: a quadrilateral filled with a gradient along the beam, from 30% near the lens to zero on the line.
The pool is an ellipse centred where the middle ray of the beam meets the words, as wide as the beam there (with its radius between 44 and 110 pixels) and flattened. Each word's light is a bell of its distance from that point: its colour goes from dark to light (gsap.utils.interpolate) with a text-shadow glow, and the current word never drops below 0.42.
A timeline takes the opening to 55% and the light's strength to 1.45 in 0.18 seconds, then back with elastic.out(1, 0.45) in 0.9 seconds; the light's strength sets the opacity of the beam, the pool and the lens.
Tab onto a link (focus-visible) brings the light there and Enter chooses it; leaving the row with the pointer (after 0.3 seconds) or the focus brings the light back to the current link. The light hangs HANG pixels up, but never more than 36% of the row's width (at least 90), so on a phone the angles stay readable; a ResizeObserver and the window's resize measure again. The library's preview clicks the other links in turn.
| Name | File | Default | What it changes |
|---|---|---|---|
SWING | script.js | 90 | How hard the light is pulled towards its link: more is quicker. |
DAMP | script.js | 8.5 | How quickly the swing dies down: less swings more. |
SPREAD | script.js | 8 | Half the opening of the beam, in degrees. |
HANG | script.js | 150 | How high above the links the light hangs, in pixels. |
For the nav of a theatre, a live music venue, a cinema, a festival, a show, a dance company or a museum with dark rooms.
The text goes from 19 to 30 pixels with the width and the light hangs lower over a narrow row (36% of its width, at least 90 pixels); each link is 51 pixels tall and a tap brings the light there and closes it in on the word.
The light points at the link at once, without swinging or swaying, is on from the start with no stutter and the click neither closes in nor flares the beam; the words light up and go dark at once, following the light.
GSAP 3.15.0, Mozilla Headline (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 5.0 KB; the libraries: GSAP 28 KB.
Tested on 4 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.