
The cookie banner
Consent, Transitions, SVG, Physics
NewFree
A one-of-a-kind gift wrap pattern being generated, shown as a harmonograph seen from above: a walnut table, a sheet on a plate that swings with its pendulum and a pen at the end of a long arm resting on a second pendulum, which you see hanging down a hole in the table. Press Generate pattern and the pendulums are pulled back and let go: the two damped swings draw a figure that turns and closes in towards the middle, the ink thinner where the pen flies and fuller where it slows. The drawing is the progress. At the end the pen lifts and slides back, and a wave of colour runs along the line: Pattern ready. A different figure every time.
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, viewport-fit=cover">
<title>The harmonograph loader</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">
<!-- the harmonograph loader: a one-of-a-kind gift wrap pattern being generated, shown as a harmonograph seen from
above. A walnut table with a sheet of paper on a swinging plate and a pen at the end of a long arm; the arm is
hinged on a brass post and rests on the top of a pendulum that hangs through a hole in the table. Pressed, both
pendulums are pulled back and let go, the pen comes down and the two damped swings together draw a figure that
closes in towards the middle. The drawing is the progress. At the end the pen lifts and the figure takes its
colours. The table, the pendulums and the ink are drawn by script.js -->
<section class="harmo" aria-label="Pattern generator" data-harmo>
<!-- three layers: the table, the hole and the pendulum in it; the plate and the paper, with the ink; the arm,
the post and the pen -->
<div class="harmo__scene" role="progressbar" aria-label="Pattern generation" aria-valuemin="0" aria-valuemax="100"
aria-valuenow="0" aria-valuetext="Ready to generate" data-scene>
<svg class="harmo__art" viewBox="0 0 380 270" aria-hidden="true" data-art="back"></svg>
<div class="harmo__plate" aria-hidden="true" data-plate>
<canvas class="harmo__paper" data-paper></canvas>
</div>
<svg class="harmo__art" viewBox="0 0 380 270" aria-hidden="true" data-art="front"></svg>
</div>
<p class="harmo__status" aria-hidden="true">
<svg class="harmo__tick" viewBox="0 0 24 24" data-tick><path d="M5.5 12.6l4.2 4.2 8.8-9.4" pathLength="1"/></svg>
<span class="harmo__swap" data-status>Ready to generate</span>
<span class="harmo__pct" data-pct></span>
</p>
<div class="harmo__buttons">
<button class="pill" type="button" data-go data-autoclic><span class="pill__label" data-label>Generate pattern</span></button>
<button class="pill is-quiet" type="button" hidden data-again><span class="pill__label">New pattern</span></button>
</div>
<p class="sr" role="status" 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.
62 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 harmonograph loader” from Animorio and fit it into my siteA pendulum free to swing any way, for small swings, moves its top on the table like a damped two dimensional spring: x'' = −ω²x − 2γx', and the same for y. There are two: A carries the arm (its displacement is the pen’s), B carries the plate and the sheet. The mark left on the paper is the difference A − B. They are integrated with semi-implicit Euler (velocity first, then position), which over thousands of steps neither gives nor takes energy: every frame the pendulums’ time is split into steps of 1/260 of the faster swing.
The ratio between the frequencies is picked at random from RATIOS (2:3, 1:2, 3:4…) and put slightly out of tune (DETUNE), so the figure turns slowly as it closes; which of the two pendulums is the slow one changes too. Each starts on an ellipse with a random width, flatness, tilt, phase and direction: the starting position and velocity come from the ellipse’s formula. The damping is −ln(FADE)/CYCLES, so FADE of the swing is left when the drawing ends; the pen takes 58 to 70% of the figure, the sheet the rest, and together they never go past SIZE.
The pendulums’ time chases the progress: the target is p × CYCLES, and every frame closes part of the gap with 1 − e^(−7·dt), so the pen speeds up and slows down without a jolt when the work moves in fits and starts. The percentage is the time drawn over the whole. The arm is a lever: hinged on the post and resting on the pendulum at 0.3 of its length, it carries the pen 3.3 times further than the pendulum’s top; the bob, far below the pivot, goes the other way.
At every step a point is skipped if it is less than 0.3 units from the last one; for the others the position on the sheet, the normal and a width that drops with the pen’s speed, e^(−4.2·v), smoothed from one point to the next, are kept. Every frame the new points become a band: its two edges, one forward and one back, filled at once on a canvas that already holds the paper, in multiply mode at 74%: where the line crosses itself the ink darkens, as on real paper.
At the end the pen lifts (its shadow widens and moves off), slides back along the arm with an elastic ease and the brake multiplies the damping by seven. Then the sheet is painted again in pieces of 40 points: each turns from the ink to its colour when the front of a wave, going from 0 to 1 in a second and a half, reaches its place along the line. The colour comes from three of the five --tone of :root, blended one into the next from the outside in, and where the run starts changes every time.
The scene is a role=progressbar with aria-valuenow and aria-valuetext updated at most every 0.6 seconds, aria-busy while it works and an aria-live line for the start, the end and the download. The button stays the same element in every state and New pattern, as it goes, hands focus back to it. Clicks from a script (detail 0, the library preview’s) never download: after 2.5 seconds of Pattern ready they lay a fresh sheet. When nothing moves the loop paints nothing.
| Name | File | Default | What it changes |
|---|---|---|---|
SECONDS | script.js | 5.5 | How long the demo’s drawing takes, in seconds, without the pendulums pulled back at the start and the colour at the end (a real one follows the server’s work). |
STEPS | script.js | [[0.15, 1], [0.24, 0.8], [0.55, 1.1], …] | The progress in stretches: for each step how far it gets (from 0 to 1) and how much of the time it takes. The short stretches are where the pen slows down; a step that goes no further than the last one is a pause. |
JITTER | script.js | 0.25 | How much the steps’ weights change from one run to the next: 0 always the same. The length stays SECONDS. |
CYCLES | script.js | 20 | How many swings the slow pendulum makes during the drawing: the more there are, the more turns the figure has and the denser it is. |
FADE | script.js | 0.24 | How much of the swing is left at the end of the drawing: the lower, the more the spiral closes in towards the middle. |
RATIOS | script.js | [[2, 3], [1, 2], [3, 4], [1, 3], [3, 5], [2, 5]] | The ratios between the two pendulums’ frequencies: one is picked at random for every figure. They give the shape: 1:2 a figure eight or a heart, 2:3 a three-petal flower, 2:5 a star. |
DETUNE | script.js | 0.012 | How far the pendulums are from the exact ratio: at 0 the figure closes on itself, with a little it turns as it tightens. |
SIZE | script.js | 78 | The figure’s largest radius, in drawing units (the sheet is 172 wide, the table 380). |
INK | script.js | [0.5, 1.9] | The ink’s width when the pen flies and when it stops, in drawing units. |
LABELS | script.js | { busy: 'Generating…', done: 'Download', saved: 'Downloaded' } | The button’s words while it works, at the end and once downloaded; the one at rest, Generate pattern, is changed in index.html. |
WORDS | script.js | { busy: 'Drawing your pattern…', done: 'Pattern ready' } | The line under the table while it works (followed by the percentage) and at the end; the one at rest, Ready to generate, is changed in index.html. |
For a wait of a few seconds that ends with something one of a kind, made for whoever is waiting: a generative pattern for gift wrap or fabric, an avatar, a cover, a greeting card, an art print on demand. The figure closing in says how far along things are even without reading the number, and the final figure is different every time, like the result. It suits a product with a crafted, workshop or stationery shop tone; for a very short wait, or work with no result to look at, it is too much.
The component is 380 pixels wide and on a phone takes the width of the screen less 16 pixels a side (358 at 390): the whole table scales together, the drawing is vector and the sheet is a canvas painted at the screen’s real density (up to twice, with a quarter more to spare), and at every change of size it is painted again from the saved points, so the figure stays sharp. The buttons are pills 44 tall: under a finger they squash and spring back; the pill that swells, the words that widen and the push to the pendulum on the way past are there only with the mouse (or the keyboard, for the push).
The pendulums, the plate, the arm and the pen stay still (the pen at the edge of the sheet) and there is no push on the way past. The figure is still drawn, with the percentage, because it is what says how far along things are: the line appears along its path with nothing moving. At the end the colour fades in over the whole figure instead of the wave, the fresh sheet fades in, the words change with a fade and the tick appears without drawing itself.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 16 KB; the libraries: GSAP 28 KB.
Tested on 8 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.