
The layered button
Buttons, Hover, Physics
Free
A row of links on a pale sheet strewn with thousands of thin iron filings. Under the current link there is a hidden magnet: the filings around it line up along its field and draw the curves between its two poles around the word. Pointing at another link the field moves there and every filing turns on its own spring, a little later the further away it is.
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 iron filings nav</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the nav: a pale sheet strewn with iron filings, and a magnet hidden under the current link. The filings line up
along its field and draw the curves between its two poles around the word; pointing at another link the
field moves there, and every filing turns on its own spring -->
<nav class="ff" aria-label="Main" data-nav>
<canvas class="ff__field" aria-hidden="true" data-still></canvas>
<canvas class="ff__field" aria-hidden="true" data-field></canvas>
<ul class="ff__list" data-list>
<li><a class="ff__link" href="#" aria-current="page" data-link><span class="ff__word" data-word>Work</span></a></li>
<li><a class="ff__link" href="#" data-link data-autoclic><span class="ff__word" data-word>Studio</span></a></li>
<li><a class="ff__link" href="#" data-link data-autoclic><span class="ff__word" data-word>Process</span></a></li>
<li><a class="ff__link" href="#" data-link data-autoclic><span class="ff__word" data-word>Journal</span></a></li>
<li><a class="ff__link" href="#" data-link data-autoclic><span class="ff__word" data-word>Contact</span></a></li>
</ul>
</nav>
</main>
<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.
18 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 iron filings nav” from Animorio and fit it into my siteThe filings lie on a grid with a step of SPACING pixels, each shaken out of place by nearly a whole step, so they cover the sheet evenly without looking set in rows. Each has its own resting angle, length and stiffness, taken from a seeded random generator, the same at every load.
For every link, once, the field of two poles placed just before and just after the word is worked out: the sum of r/|r|³ towards the north pole and the opposite towards the south pole, softened a little so it never goes to infinity. The strength becomes a weight w = 1 − e^(−|E|·REACH³/pole distance): where the field is strong the filing takes its direction, where it is weak it keeps its own angle, and the two angles are mixed taken twice, since a filing has no head or tail.
Besides the angle, every field gives every filing a shift towards the nearer pole, at most GATHER pixels and never past the pole, and a shade that grows with the field. On the words the filings stay pale, and the words have a halo the colour of the sheet, so the letters are always legible.
Every frame each filing's angle is pulled towards the field's by a damped spring (SPRING and DAMPING, the shortest way round modulo 180 degrees), its position by a softer spring, its shade by an exponential approach. When the field changes, each filing starts following the new one when a wave reaches it, spreading from the word at WAVE pixels a second, so the near ones turn before the far ones. The step is at most 1/30 of a second.
All the filings with the same shade go in one path and one stroke, seven in all. At the start of every change the filings that will not move (the two fields agree and they are still) are drawn once on a still canvas; every frame only the others are worked out and drawn, on a second canvas above. When everything has been still for a quarter of a second the loop stops and the still canvas takes them all.
| Name | File | Default | What it changes |
|---|---|---|---|
SPACING | script.js | 8 | How far apart the filings lie, in pixels: less makes more of them. |
LENGTH | script.js | 7 | How long a filing is, in pixels. |
REACH | script.js | 118 | How far from the word the field still lines the filings up, in pixels. |
SPRING | script.js | 110 | How stiff the spring that turns each filing is. |
DAMPING | script.js | 8 | How quickly a filing stops swinging: less makes it overshoot more. |
WAVE | script.js | 900 | How fast the change of field spreads across the sheet, in pixels a second. |
GATHER | script.js | 9 | How far the filings slide towards the poles, in pixels. |
For the nav of a design, architecture or engineering studio, a lab, a science magazine or the portfolio of someone who works with physics and materials.
The sheet takes the width of the screen and the links shrink down to 15 pixels; the filings get denser and shorter in proportion. A finger on a link moves the field at once, lifting it chooses the link, with no wait for a double tap.
No wave and no springs: the filings are already lined up around the current link and, pointing at or choosing another link, they are drawn at once in the new pattern.
Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 7.0 KB, and no libraries are needed.
Tested on 5 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.