
The send button
Buttons, Transitions, SVG
NewFree
The whole year in twelve small months: choosing one, the view goes into it, the small month growing into the big one while the rest of the year swells past the edges and fades, like a camera moving in.
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 zooming calendar</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the calendar: the whole year in twelve small months; choosing one, the view zooms into it until it is the big
month, and the way back zooms out to the year. The months are drawn by the script -->
<div class="zoomcal" data-cal>
<div class="zoomcal__head">
<button class="zoomcal__back" type="button" data-back hidden><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14.5 6 8.5 12l6 6"/></svg><span data-back-label></span></button>
<h1 class="zoomcal__title" data-title></h1>
<div class="zoomcal__arrows">
<button class="zoomcal__arrow" type="button" data-prev><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14.5 6 8.5 12l6 6"/></svg></button>
<button class="zoomcal__arrow" type="button" data-next><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9.5 6l6 6-6 6"/></svg></button>
</div>
</div>
<div class="zoomcal__views" data-views>
<div class="year" data-year></div>
<div class="month" data-month hidden></div>
</div>
<p class="sr" role="status" aria-live="polite" data-said></p>
</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>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.
13 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 zooming calendar” from Animorio and fit it into my siteThe script draws the twelve small months and, when needed, the big one, always six weeks long: so the big month has the shape of its small one. The size of the numbers is a fraction of the cell (--num: 0.36 on a computer, 0.42 on a phone) taken from the month’s width with container units (cqi): small or big, the numbers fill the same part of their cell.
Before the zoom, the days of the small month and those of the big month are measured at rest. The ratio between the two widths says how much to enlarge: the year, with its origin at the top left, goes to that scale, moved so that the small month’s days land exactly on the big month’s days; the big month’s days start from the inverse scale, exactly over the small ones. The two moves have the same duration (ZOOM) and the same curve (EASE), so they stay one over the other on every frame.
Meanwhile the year fades over the first part of the zoom (FADE) with power2.in and the big month appears with power2.out; the names of the weekdays arrive last. Going back, the opposite happens. While the year moves, the container fades its edges over 16 pixels with a mask, instead of cutting them sharp.
Changing year, a copy of the old year stays over the new one for as long as it takes to leave: its columns move out by 20 pixels and fade, the new ones come in from 28 pixels on the other side, STAGGER seconds one after another. Changing month, the old days leave sideways and the new ones come in column by column; the names of the days stay still.
A single small month takes the Tab key: the arrows move between the months, Page Up and Page Down change year, Enter opens. In the big month a single day takes the Tab key: the arrows move between the days, Home and End go to the start and the end of the week, Page Up and Page Down change month, Enter chooses and Esc goes back to the year. The focus follows the zoom only when the keyboard is in use: after a tap, Safari on iPhone would draw the focus ring on it.
| Name | File | Default | What it changes |
|---|---|---|---|
WEEK_START | script.js | 1 | The first day of the week: 1 Monday, 0 Sunday. |
ZOOM | script.js | 0.8 | The seconds of the zoom, in and out. |
EASE | script.js | 'expo.inOut' | The curve of the zoom. |
FADE | script.js | 0.6 | The part of the zoom over which the year fades away (and comes back). |
STAGGER | script.js | 0.05 | The seconds between one column of months and the next when the year changes. |
For a planner, a diary, the events page of a season or a long-term booking: wherever you need to see the whole year and then go into a month, without losing track of where you are.
Below 720 pixels the year sits in three columns and the numbers fill a slightly larger part of their cell (--num 0.42), to stay readable. Taps work like clicks, and a sideways swipe changes year or month.
No zoom: the year and the month swap with a fade, years and months change at once, the disc of the chosen day appears without a pop and nothing arrives when the page opens.
GSAP 3.15.0, Geist (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 8.1 KB; the libraries: GSAP 28 KB.
Tested on 3 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.