Skip to content
animorio
IT
Back to the library

The sundial that tells the time

SVG, Hover, TextGSAP, CSS onlyMediumCompressed weight: Demo 9.6 KBGSAP 28 KBFreeDownload the zip

A sundial seen from above, a fan of hairline ticks and a gnomon: the pointer is the sun, the shadow turns and stretches on two springs, the digits of the time click over one by one and underneath the time is written in words, half past four, letter by letter. Minimal style.

The code

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 sundial that tells the time</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- a sundial seen from above: a fan of hairline ticks and a gnomon. The pointer is the sun: its shadow swings
       and stretches on a spring, the time is written underneath in words and its digits click over -->
  <main class="stage" data-stage>
    <header class="top">
      <span class="top__name">Meridian</span>
      <span class="top__note">A sundial, seen from above</span>
    </header>

    <div class="dial" role="slider" tabindex="0" aria-label="Time of day" aria-valuemin="5" aria-valuemax="19" data-dial>
      <svg class="dial__svg" viewBox="-500 -490 1000 720" aria-hidden="true">
        <defs>
          <linearGradient id="shade" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="0" y2="-300" data-shade>
            <stop offset="0" stop-opacity="0.82"></stop>
            <stop offset="0.7" stop-opacity="0.42"></stop>
            <stop offset="1" stop-opacity="0.08"></stop>
          </linearGradient>
        </defs>
        <path class="rim" data-rim></path>
        <path class="path" data-sunpath></path>
        <path class="ticks" data-ticks></path>
        <path class="ticks ticks--hours" data-hours></path>
        <path class="ticks ticks--now" data-now></path>
        <g data-shadow-turn><path class="shadow" fill="url(#shade)" data-shadow></path></g>
        <path class="gnomon" data-gnomon></path>
        <path class="sun" data-sun></path>
      </svg>
      <div class="labels" aria-hidden="true" data-labels></div>
    </div>

    <div class="read" aria-hidden="true">
      <div class="read__row">
        <span class="digits" data-digits>
          <span class="slot" data-slot></span><span class="slot" data-slot></span><span class="digits__colon">:</span><span class="slot" data-slot></span><span class="slot" data-slot></span>
        </span>
        <span class="read__date" data-date>June 21</span>
      </div>
      <div class="words" data-words></div>
    </div>

    <p class="hint">Move the sun across the page</p>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

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.

23 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The sundial that tells the time” from Animorio and fit it into my site

What it does

On warm white paper, at the top left the name of a made-up brand, Meridian, and on the right A sundial, seen from above. In the middle a horizontal sundial seen from above: a fan of hairline ticks, one every five minutes from five in the morning to seven in the evening, longer for the hours and the quarters, with the hour numbers outside the rim. The ticks are not evenly spaced: as on a real sundial they are tight round noon and wide towards morning and evening. In the middle the gnomon, a slim triangle pointing north, and under it the sun's path, a dotted arc. The pointer is the sun: moving from right to left goes from dawn to sunset (the sun rises in the east, on the right of the page), moving up and down changes the season, the high June sun at the top and the low December one at the bottom. On the dotted arc the sun is a short vermilion stroke, and on the other side of the gnomon the shadow, a dark wedge that fades towards its tip: it turns on one spring and stretches on another, very short at noon in summer, very long at a winter dawn, always a hair too far and back. The ticks next to the shadow reach in towards the middle while it runs and the tick it reads turns black, with the number of its hour. Underneath, the digits of the time (16:30) click over one at a time, each in its own little window, from below when time goes on and from above when it goes back, and they narrow while they count fast (Instrument Sans's width axis); next to them the day of the season. Below that, large, the time in words: half past four, twenty to five, noon. While the shadow runs the words turn thin and pale; when it settles the new phrase arrives letter by letter from below, goes a hair too far and takes on weight (Fraunces's weight axis). When the page opens the rim and the ticks are drawn from noon outwards, the gnomon rises on an elastic, the sun comes up on the right and crosses the sky to half past four. When nobody moves the pointer, after a moment the sun walks on by itself half an hour at a time, and after sunset it starts again from the morning. The arrow keys move a quarter of an hour, Page Up and Page Down an hour, Home and End go to dawn and sunset.

How it works

The hour lines of a real sundial

On a horizontal sundial the style's shadow at time t makes an angle with the noon line given by tan(angle) = sin(latitude) × tan(H), where H is the sun's hour angle, 15 degrees for each hour from noon. With atan2(sin(lat)·sin H, cos H) the angle stays continuous past six o'clock, so the ticks run from 5 to 19 and close up round noon by themselves. The SVG has a viewBox of 1000 by 720 with the gnomon at the origin; each tick is a segment to the rim (radius 420), in two paths: the hours darker, the rest lighter.

The sun from the pointer

The pointer's horizontal position becomes the hour (right is dawn, left is sunset), the vertical one the season, that is the sun's declination between +23.44 and −23.44 degrees. From hour and season comes the sun's height, sin(h) = sin(lat)·sin(dec) + cos(lat)·cos(dec)·cos(H), and the shadow of a gnomon NODUS tall is NODUS / tan(h) long, with the sun never below 5 degrees so the shadow stays on the dial. The day next to the digits comes from the same declination, read on the way from December to June.

Two springs: one to turn, one to stretch

The time the shadow shows goes towards the one the sun asks for on TIME_SPRING, integrated by hand on GSAP's ticker with the step capped at 1/30 of a second; the length goes towards the one of that moment on LENGTH_SPRING, softer, so when the shadow turns fast it stretches and shrinks a little late and with a hair of bounce. The shadow is a wedge drawn pointing up inside a rotated group: the userSpaceOnUse gradient turns with it and always fades towards the tip. The ticks nearby have a spring each, which pulls them in towards the middle in proportion to the speed (LEAN).

Digits that click and words that settle

Each digit sits in a little window with hidden overflow: the new digit comes in from below (from above if time goes back) on back.out and the old one leaves the other way, fading. If a digit changes again within 0.24 seconds it simply switches without rolling, so they do not pile up when time runs fast. The words are rounded to five minutes; they are rewritten when the phrase stays the same for 0.22 seconds, or at most once every 0.85 seconds while the shadow runs. Each letter is a span with font-weight: calc(var(--wt) + var(--lw)): the container gives the weight of the speed (WEIGHT), the landing letter takes --lw from −300 to 0.

The opening, the sun on its own and the hands

A GSAP timeline draws the rim and the sun's path opening them from the middle, grows each tick with a back.out when the drawing reaches it, raises the gnomon with elastic.out, then takes the sun from 5 to START: the springs do the rest. The mouse drives the sun anywhere on the page, a finger while it drags; the dial is a role=slider with the arrow keys. After 2.4 seconds with nobody there, a gsap.delayedCall moves the sun on half an hour every 1.5 seconds.

Values to change

NameFileDefaultWhat it changes
TIME_SPRINGscript.js[150, 17]The spring the shadow turns on: how stiff, and how much it is held back (less hold, more bounce).
LENGTH_SPRINGscript.js[210, 11]The spring the shadow stretches and shrinks on: how stiff, and how much it is held back.
NODUSscript.js140How tall the gnomon is (the dial is 1000 wide): taller, longer shadows.
LEANscript.js18How far the ticks next to the shadow reach in towards the middle while it runs.
WEIGHTscript.js[540, 220]The weight of the words at rest and while the shadow runs (100 to 900).
WIDTHscript.js[100, 76]The width of the digits at rest and while they count fast (75 to 100).
STARTscript.js16.5The hour the opening lands on, from 5 to 19 (16.5 is half past four).
WANDERscript.jstrueThe sun walks on by itself, half an hour at a time, when nobody moves the pointer.

Try them in the Playground

When to use it

To tell a time in a warm, readable way: a restaurant's or a bar's opening hours (when lunch is served, when it closes), a hotel's or a holiday home's check-in time, the time of a concert or an event, sunset from a terrace. It works where the time is the message and there is room for a single scene; for one time among lots of data plain text is enough.

On phones

The same animations with the sizes adapted: the dial is as wide as the screen, the hour numbers and the digits a little smaller, the words scale with the width. The sun follows the finger while it drags anywhere on the page (the page does not scroll there, it is a single scene) and stops when it lifts; then it walks on by itself.

With reduced motion

No springs, no ticks reaching in, no rolling digits and no sun walking by itself: the shadow goes straight to the hour and its length, the digits change and the words swap with a short fade. When the page opens everything fades in already in place, at half past four.

Pitfalls

  • With tan(angle) = sin(lat) × tan(H) written with atan the angle jumps 180 degrees at six in the morning and six in the evening, where tan(H) goes to infinity: with atan2(sin(lat)·sin H, cos H) it stays continuous and the dial can run from 5 to 19.
  • A sun below the horizon casts no shadow: with real seasons, at five on a winter morning the height is negative and the shadow would vanish halfway. The height never goes below 5 degrees and the length stops a little past the rim.
  • While time runs fast the digits change every frame and the rolls piled up, with three digits halfway in the same little window. A digit that changes again within 0.24 seconds switches without rolling, and only the last one ever leaves.
  • Words that waited for the shadow to stop never changed while the pointer kept moving (the preview video showed half past four for seven seconds): now they are rewritten on the run too, at most once every 0.85 seconds.
  • With fr grid rows the 500 pixel tall dial made the empty row under the words grow too, in proportion, and the page got taller than the screen: the fr rows only hold the title and the empty space, the dial and the words sit in auto rows.
  • A filled gnomon hid the short summer noon shadow: it is drawn as an outline only, and the shadow shows underneath.

Libraries

GSAP 3.15.0, Fraunces (font variabile) 5.3.0, Instrument Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 9.6 KB; the libraries: GSAP 28 KB.

Testing

Tested on 15 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All animations