
The slide-to-confirm button
Buttons, Physics, Transitions
NewFree
The egg timer of a cooking app, with the egg cut in half really cooking as the time runs down: the heat of the water moves in through the shell as in real physics, the white turns white from the edge inwards and the yolk sets from its own edge. Soft, jammy or hard come out by themselves. When the time is up the egg is lifted out of the water with a little jump and the yolk wobbles as much as it is still runny.
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 egg timer</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/rubik@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the egg timer: the egg is drawn cut in half, and while the time runs down it cooks from the shell inwards,
worked out as heat that really moves through the white and into the yolk. When the time is up the egg is
lifted out of the water and its yolk wobbles as much as it is still runny -->
<section class="egg" aria-label="Egg timer" data-timer>
<div class="egg__pan" data-pan>
<canvas class="egg__canvas" aria-hidden="true" data-canvas></canvas>
</div>
<div class="egg__readout" data-readout>
<span class="egg__time" role="timer" aria-live="off" aria-atomic="true">
<span class="egg__digits" aria-hidden="true" data-time></span>
<span class="sr" data-time-words></span>
</span>
<p class="egg__state"><span class="egg__word" data-word></span><span class="egg__detail" data-detail></span></p>
</div>
<fieldset class="kinds" data-kinds>
<legend class="sr">How you like your egg</legend>
<span class="kinds__pill" aria-hidden="true" data-pill><span class="kinds__copy" data-pill-copy></span></span>
</fieldset>
<div class="egg__controls" data-controls>
<button class="egg__reset" type="button" aria-label="Start over" aria-disabled="true" data-reset>
<span class="egg__turn">
<svg viewBox="0 0 24 24" aria-hidden="true" data-reset-icon><path d="M5.6 9.2A7.2 7.2 0 1 1 4.9 14.2"/><path d="M5.2 4.6v4.8H10"/></svg>
</span>
</button>
<button class="egg__go" type="button" data-go data-autoclic>
<span class="egg__go-words" data-go-words>Start</span>
</button>
<span class="egg__balance" aria-hidden="true"></span>
</div>
<p class="sr" aria-live="polite" data-live></p>
</section>
</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.
31 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 egg timer” from Animorio and fit it into my siteThe cut is a half plane round the long axis of the egg: z along the egg, r out from the axis, in cells of 0.75 mm (76 by 30). Each cell is really a ring, and heat flows through its four faces in proportion to their area: outwards (i+1)/(i+½), towards the axis i/(i+½), above and below 1. It is the heat equation in cylindrical coordinates, with finite volumes, with the conductivity and the heat capacity of the white and of the yolk (a harmonic mean on the faces between the two) and the water at WATER degrees outside the shell. The time step is the longest that stays steady, and every cell remembers the highest temperature it has reached: proteins do not go back.
Two tables of 481 colours, a quarter of a degree at a time, say what the temperature does: the white is clear up to 58 degrees, milky up to 66 and firm white towards 80; the yolk stays runny up to 60, turns to jam up to 65, sets up to 70 and turns pale yellow above. Two layers, the white and the yolk, are painted pixel by pixel on two hidden canvases: for each pixel the cell and the weights of the bilinear interpolation are worked out once, so painting means four reads and a table. The yolk has a wet sheen and a spot of light only where it is still runny, and a grain where it is set.
The outline is the egg curve, y = (B/2)·√((L²−4x²)/(L²+8wx+4w²)), with w moving the widest part towards the blunt end; the skin under the shell is the same outline moved in along its normals. The white is drawn inside the outline over a black silhouette, so the bubbles passing behind do not show through the raw white; the yolk inside its circle, which can wobble on its own. The white under the yolk reads the temperature just outside the yolk, so no hole shows when the yolk squashes.
The bubbles are born on the shell, mostly underneath and at the sides, grow stuck to it and then let go and rise faster and faster, wobbling. The egg rocks with two sines out of step while it boils. At zero a GSAP timeline makes it crouch, jump, land squashed (the squash keeps the bottom of the egg in place) and come back up with an elastic.out; on landing the yolk swings like a damped spring, scaling (1+j, 1−j) round its centre, with its size, frequency and damping taken from how much of the yolk is still runny, so a soft egg wobbles for a while and a hard one hardly at all, and it is all over within a second and a half.
The time left comes from the clock (performance.now), and the egg is worked out up to where the clock says: a tab left in the background ends on time and cooked right. With DEMO the real time is squeezed (seven minutes in twenty seconds) but the egg cooks by the time on the display; the figures then change without rolling. role="timer" with aria-live off, and an aria-live region that speaks only when the state changes and at the end. The preview’s click (detail 0) only begins and resumes, and after the end it waits a little before taking a new egg.
| Name | File | Default | What it changes |
|---|---|---|---|
EGGS | script.js | [['Soft', 330], ['Jammy', 420], ['Hard', 600]] | The ways to have the egg: the name and the seconds in the water. |
CHOSEN | script.js | 1 | The way chosen when the page opens: 0 is the first. |
DEMO | script.js | 20 | To try it out, a whole egg cooks in this many seconds (the figures still show the real minutes); 0 = in the real time. |
START | script.js | 4 | The egg’s temperature as it goes into the water, in degrees: 4 from the fridge, 20 from the counter (it cooks sooner). |
WATER | script.js | 100 | The water, in degrees: 100 at a rolling boil; below 65 the yolk never sets. |
BUBBLES | script.js | 1 | How hard the water boils round the egg: 0 = no bubbles. |
WOBBLE | script.js | 1 | How much a runny yolk wobbles when the egg is lifted out: 0 = not at all. |
For the timer of a recipe or cooking app, a smart oven or pot, a breakfast app: wherever the one waiting wants to know not only how long is left but how it is coming along. The same working out suits anything that cooks from the edge inwards (a roast, a loaf, a cake) with another shape and other temperatures.
The component is 360 pixels wide and at 390 it narrows to 358 without spilling over. The three ways are 52 pixels tall, the buttons 48 and 56. Working out the heat costs very little (about 1700 cells); the two layers are painted at most thirty times a second while the egg cooks, and never while it is still.
The egg still cooks, because it is the time: the white and the yolk change colour without anything moving. No bubbles, no rocking or dip, no jump and no wobble at the end: Done and the verdict fade in. The new egg fades in, the pill of the three ways moves without sliding and the figures change without rolling.
GSAP 3.15.0, Rubik (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 15 KB; the libraries: GSAP 28 KB.
Tested on 7 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.