Skip to content
animorio
IT
Back to the library

The eclipse that dims the page

Scroll, SVGGSAPMediumCompressed weight: Demo 7.5 KBGSAP + ScrollTrigger 45 KBFreeDownload the zip

Scroll inside the preview

An observatory’s eclipse day, in the minimal style: as you scroll, the Moon, only a thin outline, slides across a vermilion Sun and bites it into a thinner and thinner crescent, and the whole page darkens with the light that is left. At totality the Moon settles in the middle, two thin rings draw themselves around it and the page is night; then it moves on and the day comes back.

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 eclipse that dims the page</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/full.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <!-- the eclipse day of a made-up observatory, Halo. Scrolling, the Moon, only a thin outline, slides across the Sun
       and bites it into a crescent; the more Sun it covers, the darker the whole page gets. At totality the Moon settles
       in the middle, a thin vermilion ring draws itself around it and the page is night; then the Moon moves on and
       the day comes back. The word of the phase loses weight with the light -->
  <main>
    <section class="apertura">
      <p class="piccolo">Halo Observatory</p>
      <h1 class="titolo">For six minutes,<br>the day goes out.</h1>
      <p class="piccolo piccolo--tenue">Scroll to bring the Moon across.</p>
    </section>

    <section class="racconto" data-racconto>
      <div class="palco" data-palco>
        <header class="testa">
          <p class="marchio">Halo</p>
          <p class="piccolo piccolo--tenue">Total eclipse, viewing day</p>
        </header>

        <svg class="cielo" data-cielo aria-hidden="true">
          <defs>
            <mask id="morso" maskUnits="userSpaceOnUse">
              <rect class="morso__tutto" data-morso-tutto fill="#fff"></rect>
              <circle data-morso-luna fill="#000"></circle>
            </mask>
          </defs>
          <circle class="sole" data-sole mask="url(#morso)"></circle>
          <circle class="corona corona--larga" data-corona-larga></circle>
          <circle class="corona" data-corona></circle>
          <circle class="luna" data-luna></circle>
          <g class="righello" data-righello></g>
        </svg>

        <div class="fase" aria-live="polite">
          <p class="fase__finestra">
            <span class="fase__parola" data-fase>Daylight</span>
            <span class="fase__parola" data-fase>Partial</span>
            <span class="fase__parola" data-fase>Totality</span>
            <span class="fase__parola" data-fase>Partial</span>
            <span class="fase__parola" data-fase>Daylight</span>
          </p>
          <p class="lettura">Sun covered <span class="lettura__cifra" data-coperto>0%</span></p>
        </div>
      </div>
    </section>

    <section class="apertura apertura--fine">
      <h2 class="titolo titolo--medio">Bring a chair.<br>We bring the glasses.</h2>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.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.

29 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 eclipse that dims the page” from Animorio and fit it into my site

What it does

The eclipse day of a made-up observatory, Halo, on a warm white with black ink and a single vermilion. After the opening the screen stops: on the right a solid vermilion Sun, at the top left the Moon, which is only a thin grey outline. As you scroll the Moon slides diagonally towards the Sun and, where it covers it, the Sun disappears: a thinner and thinner crescent is left. The whole page follows the light that remains: it stays light for a long time, then near totality it turns grey and almost black, and the text turns from black to warm white. On the left the word of the phase, large in a variable serif, changes in a window (Daylight, Partial, Totality, Partial, Daylight): the old one leaves upwards, the new one rises from below, and it loses weight and softens as the light drops; below it the share of the Sun covered counts. At totality the Moon reaches the middle, goes a hair too far and settles with a small elastic, and two thin vermilion rings draw themselves around it from the top, the second wider and fainter a moment later. Before the Moon moves on the rings run off the same way, then the crescent comes back on the other side and the page turns light again. At the bottom a thin timeline has first contact, totality (a short vermilion stretch, because it lasts six minutes) and last contact at their true distance: a vermilion mark walks the hours with the time above it. Everything follows the scroll, forwards and backwards.

How it works

One SVG and one mask

The Sun, the Moon, the rings and the timeline sit in one SVG whose viewBox matches the pixels of the pinned stage (position: sticky, 100lvh tall). The Sun is a solid circle with a mask: a white rectangle as big as the stage and, on top, a black circle that moves with the Moon. Where the black is the Sun does not show, so the crescent comes by itself, right at every position, without drawing it. The visible Moon is only a thin, semi-transparent outline.

One number for the whole story

The timeline, tied to the scroll with scrub SCRUB, carries a number u from 0 to 1: for four steps the Moon arrives, for TOTALITY steps it stays still in the middle, for four more it leaves. From u come the Moon’s place on its line (tilted by ANGLE degrees), the time and the word of the phase. The change between two words falls where geometry says: first contact is when the distance between the centres equals the sum of the radii.

The page follows the light

Every frame the script works out the covered area of the Sun with the formula for the lens between two circles and writes it in the percentage. The darkness is that coverage cubed, like the real sky that barely changes while a sliver of Sun is left: with gsap.utils.interpolate it mixes the warm white and the near black into the --fondo variable, and the text colour turns from black to white between 40 and 62 per cent of darkness. The same number takes weight away from the word of the phase (wght axis) and softens it (Fraunces’ SOFT axis).

The settle and the rings

Once in the middle, the Moon goes a little over two pixels too far and comes back with elastic.out: a second value of the timeline added to its place. The rings are circles with a stroke-dasharray as long as their circumference, turned by 90 degrees to start from the top: stroke-dashoffset goes from the circumference to zero and draws them, then from zero to minus the circumference and the tail chases the head until they are gone. The second one starts a moment later.

The timeline and the measures

The four times in TIMES sit on the line at their true distance, which is why totality is a short stretch; the vermilion mark walks the hours and the names under the line fade when the time passes over them. All the measures (the Sun’s centre and radius, the line) are worked out again on every ScrollTrigger refresh and on every resize, even halfway through the eclipse.

Values to change

NameFileDefaultWhat it changes
SUNscript.js0.25The radius of the Sun, as a share of the stage height.
MOONscript.js1.035How much bigger the Moon looks than the Sun: the bigger it is, the wider the dark edge inside the rings.
ANGLEscript.js20The slope of the Moon’s path, in degrees (0 is horizontal).
TOTALITYscript.js2.2How long totality lasts, in steps of the story (the Moon takes 4 to arrive).
TIMESscript.js['09:58', '11:24', '11:30', '12:56']The four times: first contact, start and end of totality, last contact.
SCRUBscript.js0.6How many seconds the drawing takes to catch up with the scroll.

Try them in the Playground

When to use it

For the page of an observatory, a planetarium or an outdoor event, for a science article or for any story where the page should go from day to night and back: an opening, a held moment in the middle, a return.

On phones

The same, with adapted measures: the Sun sits centred near the top and smaller, the word of the phase below it, the timeline at the bottom with smaller labels. The Moon comes in from off screen.

With reduced motion

The Moon does not travel: five still pictures (day, crescent, totality, crescent, day) that take turns with a cross-fade, with the rings already drawn at totality; the page darkens and lightens slowly, the words of the phase cross-fade and the mark on the timeline jumps from one picture to the next.

Pitfalls

  • Drawing the crescent as a computed shape (two arcs) breaks when the Moon is almost entirely over the Sun; with the SVG mask there is nothing to compute and the crescent is always right.
  • Darkness proportional to the coverage would darken the page too early and leave the text grey on grey for a long time: with the coverage cubed the page stays light almost to the end, and the text colour changes over a short stretch.
  • The window of the phase word cut off the tail of the y in Totality: it has more room below, balanced by a negative margin.
  • The percentage before the sentence pushed the words around when the number of digits changed: put at the end (Sun covered 64%) it moves nothing.

Libraries

GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Fraunces (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 7.5 KB; the libraries: GSAP + ScrollTrigger 45 KB.

Testing

Tested on 19 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