Skip to content
animorio
IT
Back to the library

The golden rectangle that draws itself

Scroll, SVGGSAPAdvancedCompressed weight: Demo 12 KBGSAP + ScrollTrigger 45 KBLenis 5.3 KBFreeDownload the zip

Scroll inside the preview

As you scroll, a golden rectangle divides itself square after square: every thin line draws itself, lands with a small slash and leaves its measure beside it. Then the spiral runs through the squares and the camera follows it into the eye, where the studio’s name was waiting. 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 golden rectangle that draws itself</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>
  <!-- a made-up architecture studio, Aurel. The stage sticks while you scroll: a golden rectangle 233 by 144 is divided
       square after square, every thin line draws itself with its measure beside it; then the spiral runs through the
       squares and the camera dives into its eye, where the studio's name was waiting. The drawing is made by the
       script -->
  <main>
    <section class="corsa" data-corsa>
      <div class="palco" data-palco>
        <svg class="tela" data-tela aria-hidden="true">
          <defs>
            <linearGradient id="bordi" data-bordi x1="0" y1="0" x2="0" y2="1">
              <stop offset="0" stop-color="#000"/>
              <stop data-bordo-alto offset="0.08" stop-color="#fff"/>
              <stop data-bordo-basso offset="0.92" stop-color="#fff"/>
              <stop offset="1" stop-color="#000"/>
            </linearGradient>
            <mask id="buco" data-maschera maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
              <rect data-maschera-fondo x="0" y="0" width="100" height="100" fill="url(#bordi)"/>
              <rect data-buco x="0" y="0" width="0" height="0" fill="#000" fill-opacity="0"/>
              <rect data-buco-sotto x="0" y="0" width="0" height="0" fill="#000" fill-opacity="0"/>
            </mask>
          </defs>
          <g data-veli></g>
          <g mask="url(#buco)">
            <path class="quote" data-quote d="M0 0"/>
            <path class="linee" data-linee d="M0 0"/>
            <path class="spirale" data-spirale d="M0 0"/>
          </g>
        </svg>

        <div class="misure" data-misure aria-hidden="true"></div>

        <header class="testa">
          <a class="marchio" href="#" data-marchio data-entra-testa>
            <svg class="marchio__segno" viewBox="0 0 26 16.83" aria-hidden="true">
              <path class="marchio__bordo" d="M1 1h24v14.83H1zM15.83 1v14.83M15.83 10.17H25M19.33 10.17v5.66"/>
              <path class="marchio__arco" data-marchio-arco d="M1 15.83A14.83 14.83 0 0 1 15.83 1A9.17 9.17 0 0 1 25 10.17A5.67 5.67 0 0 1 19.33 15.83"/>
            </svg>
            <span class="marchio__nome">Aurel</span>
          </a>
          <p class="voce" data-entra-testa>Studio for architecture</p>
        </header>

        <h1 class="nome" data-nome aria-label="Aurel">Aurel</h1>
        <p class="sotto" data-sotto><span class="sotto__dentro" data-sotto-dentro>We build in proportion.</span></p>

        <p class="nota" data-entra-testa><span class="nota__etichetta">Proportion</span><span class="nota__valore">1 : 1.618</span></p>
        <p class="cenno" data-entra-testa><span class="cenno__dentro" data-cenno><span>Scroll</span><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M10 3v13M4.5 10.5 10 16l5.5-5.5"/></svg></span></p>
      </div>
    </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="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.

18 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 golden rectangle that draws itself” from Animorio and fit it into my site

What it does

The page of a made-up architecture studio, Aurel: ivory paper, the name at the top left with its small golden rectangle, the proportion 1 : 1.618 at the bottom and, in the middle, a rectangle drawn in thin lines. It arrives tracing itself from the top left corner, both ways at once, and the dimensions appear around it as on a technical drawing: the dimension line growing from the middle, the slashes at its ends and the figures 233 and 144 breaking the line. As you scroll the stage stays still and the rectangle divides itself: a line starts from the line before, runs down or across, and when it reaches the other side it leaves a small slash that settles with a bounce; the square it has just closed is shaded for a moment and beside the line its measure appears, narrow and a little low, then widens and rises into place. The squares are 144, 89, 55, 34, 21, 13, 8, 5, 3, 2, 1 and 1, the Fibonacci numbers, so the division comes out exact; each one takes a little less scroll than the one before and the measures of the smallest stay hidden until they are big enough to read. Then the spiral, in the accent colour, enters from the bottom left corner and runs through the squares, a quarter of a circle in each one: the measure of the square it is crossing lights up in the accent and goes back to grey when the spiral moves on. When the spiral gets to the small squares the camera follows it and dives towards the eye with an exponential zoom, so every square grows at the same pace, the outer dimensions leave the screen and the measures of the tiny squares appear one after the other. The lines always stay one pixel thin. In the eye the studio’s name was waiting: the lines open around it, as on a drawing where there is a label, and the letters arrive narrow and light, one after the other, and widen into their full weight with a small bounce; below, the studio’s sentence appears. With the mouse the square under the pointer is shaded and its measure lights up, the letters of the name widen and spring back, and the mark draws its spiral again. Scrolling back up, everything goes in reverse.

How it works

The drawing in units

The rectangle is 233 by 144 and the squares are the Fibonacci numbers, so every cut is exact. A loop goes round clockwise, left, top, right, bottom, and each time cuts from what is left a square as wide as the short side: for each one the script keeps the line that closes it, the quarter circle of the spiral (centre and two ends) and its measure. Every line is turned round so it starts from the line before. The eye of the spiral is where the diagonal of the rectangle crosses the diagonal of what is left after the first square.

Drawing on the screen, not zooming

Nothing is enlarged with transform: on every frame the script takes every point from units to the screen through the camera (a zoom and the position of the eye) and rewrites the SVG paths. So the lines stay one pixel thin even at eleven times, the slashes and the measures stay the same size, and every measure only shows once its square is at least 48 pixels big. On a phone the drawing turns a quarter and the rectangle stands up.

The spiral and the camera

Each quarter circle is sampled once; the tip of the spiral moves forward quarter by quarter, and each one takes a share of scroll proportional to its side to the power of 0.42, so the small squares do not flash by. The zoom is exponential (ZOOM to the power of the position), so every square grows at the same pace, and it starts when the tip is halfway through the fourth square; meanwhile the eye slides to the middle of the screen. The measure of the square the tip is crossing blends towards the accent colour.

The name in the eye

The name is anchored to the eye and grows with the camera. An SVG mask holds a black rectangle as big as the name (measured on an invisible copy already at its final weight) and one for the sentence below: as their opacity grows they open the lines and the spiral around the words, as on a technical drawing, and the measures that would end up underneath step aside. The letters rise with font-variation-settings from wght 260 and wdth 62 to 600 and 112, with back.out and a stagger.

Direction

Everything is one timeline with ScrollTrigger and scrub, on a sticky stage 100lvh tall with Lenis: the lines one after the other (each with a little less scroll), each with its slash, its shade and its measure in back.out, then the spiral, the zoom, the name and the sentence. The state is a handful of numbers; the drawing is redone in GSAP’s ticker only when something has changed. The entrance (the rectangle and the dimensions) is a timed timeline, and a gradient in the mask fades the drawing out near the top and bottom edges, where the small text is.

Values to change

NameFileDefaultWhat it changes
NAMEscript.js'Aurel'The studio’s name waiting in the eye of the spiral; its width is measured on its own.
SQUARESscript.js12How many squares the rectangle is divided into, from 7 to 12: with fewer squares the spiral stops earlier and the eye stays empty.
LINEscript.js1The thickness of the drawing’s lines, in pixels; it stays the same at any zoom.
SPIRALscript.js1.8The thickness of the spiral, in pixels.
ZOOMscript.js11How close the camera gets to the eye at the end: 11 means eleven times closer.
SETTLEscript.js1.7How far the slashes, the measures and the letters overshoot before they settle (0 = no bounce).
RIDEscript.js1How much scrolling the whole thing takes: 2 is twice as much.
--accentostyle.css#e5432aThe colour of the spiral and of the measure it is crossing.
--inchiostrostyle.css#141414The colour of the lines and of the name.

Try them in the Playground

When to use it

For the opening of an architecture studio, a designer, a brand that works with proportion or a portfolio that wants to say “we measure everything”: the technical drawing that builds itself and leads to the name. It also works to present a method, a grid or a layout system.

On phones

The same: the drawing turns a quarter and the rectangle stands up, so it fills the tall screen; the dimensions go above and on the right, the measures are a touch smaller and the name is almost two thirds of the screen wide.

With reduced motion

Nothing draws itself or moves and Lenis stays off: the scroll goes through three stops, the divided rectangle with its measures, the complete spiral and the name in the eye, and between one stop and the next the drawing changes with a fade.

Pitfalls

  • Enlarging the drawing with transform: scale also thickens the lines (at eleven times they become 11 pixel bars) and the measures: the drawing is redone on the screen every frame, and the lines stay one pixel thin.
  • With the spiral split into equal lengths, the small squares flashed by and the big ones never ended: each quarter takes a share of scroll proportional to its side to the power of 0.42.
  • A linear zoom hardly moves at the start and races at the end: it is exponential, so every square grows at the same pace.
  • The shade of the square just closed, at 7 per cent, looked like a grey block on the first big square: it is at 3.5 per cent and fades at once.
  • The sentence under the name, crossed by the lines, could not be read: it has its own rectangle in the mask too, and the measures that end up under the name or the sentence step aside.
  • During the zoom on a phone the lines ran over the mark at the top: a gradient in the mask fades the drawing out near the edges.

Libraries

GSAP 3.15.0, ScrollTrigger 3.15.0, Lenis 1.3.26, Archivo (font variabile) 5.3.0.

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

Testing

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