Skip to content
animorio
IT
Back to the library

The contour line background

Backgrounds, HoverGSAP, Canvas, CSS onlyAdvancedCompressed weight: Demo 6.4 KBGSAP 28 KBFreeDownload the zip

An animated background to put behind a heading or a section: the contour lines of an invented landscape on an almost black ground, drifting slowly and coming back the same after a round. Two tones of grey, only the highest level in the accent colour; under the heading the land flattens into a plateau and the pointer raises a hill ringed by its own lines. 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>Altura</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>
  <!-- the background: contour lines of an invented landscape on a canvas behind the page; the land drifts slowly and
       under the title it flattens into a plateau, so no line ever crosses the words -->
  <main class="pagina" data-pagina>
    <canvas class="fondo" aria-hidden="true" data-fondo></canvas>

    <header class="testa">
      <p class="marchio">Altura</p>
      <p class="testa__nota">Mountain lodge</p>
    </header>

    <section class="eroe">
      <div class="blocco" data-blocco>
        <p class="occhiello" data-entra>Twelve rooms above the tree line</p>
        <h1 class="titolo" data-titolo aria-label="Above the weather.">Above the weather.</h1>
        <div class="azione" data-entra>
          <a class="pillola" href="#">
            <span class="pillola__scritta" data-testo="Book a room">Book a room</span>
            <svg class="pillola__freccia" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 8h10.5M9 3.8 13.2 8 9 12.2" /></svg>
          </a>
        </div>
      </div>
    </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>

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.

21 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 contour line background” from Animorio and fit it into my site

What it does

A whole page in almost black, the background of an invented mountain lodge, Altura. Behind everything, on a canvas, the contour lines of a landscape that does not exist: thin warm grey lines closing into rings on the summits, crowding on the slopes and spreading out in the valleys; one line in five, the index line, is lighter, and only the highest level is orange, small rings appearing and disappearing on the summits. In the middle, small, the heading: Twelve rooms above the tree line, then Above the weather. in Archivo and a light pill (Book a room) with its arrow; the brand and Mountain lodge at the top. Under the heading the land flattens into a plateau: the lines go round it and none crosses the words. The landscape drifts slowly, two layers of noise turning in circles at different speeds, so the hills change shape, summits split and merge, and in twenty-six seconds everything is back as it was. Where the pointer goes the land rises into a soft hill: concentric rings close in round it and an orange ring lights up on top, following it on a spring and disappearing when the pointer leaves. When the page opens the landscape rises from flat: first small rings appear on the highest summits, then they spread and multiply until they fill the page, a hair too far and back; the letters of the heading rise one after another, going from wide and light to narrow and heavy.

How it works

The land

A grid of points every 8 px (6 on a phone) covers the page; at each point the height is 0.68 · noise(p/SCALA + a) + 0.32 · noise(2.3·p/SCALA + b), a 2D Perlin noise written in the script with a fixed seed. a and b move round two circles (of radius DERIVA, the second twice as fast and the other way) following the phase of a repeating GSAP timeline GIRO seconds long: the landscape changes shape and after each round it is exactly the same again.

The lines with marching squares

For every grid cell the heights of the four corners are taken, and only the levels between the lowest and the highest (QUOTA is the step between levels). For each level the four corners give a number from 0 to 15, and a table says which sides of the cell the line crosses; the exact point on each side is found by interpolation. The segments go into three Path2D objects, fine lines, index lines (one every MAESTRA) and the highest level, and each is drawn with a single stroke.

The plateau under the heading

The heading block is measured and round it a distance from a slightly squared oval (a superellipse) is worked out. Inside, the height is brought smoothly, with a feather of ALTOPIANO pixels, to halfway between two levels: there the land is flat and no line crosses it, and the lines outside go round it as round a lake.

The pointer's hill

The pointer adds COLLINA · e^(−d²/2·LARGA²) to the land: a hill steeper than the landscape, so concentric rings close round it and the highest level, in the accent colour, sits on top. The centre of the hill follows the pointer on a spring, its height on another, and when the pointer leaves the page the hill sinks and disappears.

The opening and the pause

A timeline takes the land's amplitude from 0 to 1 with back.out: the lines are born on the summits and spread. The letters of the heading, each in two spans (GSAP moves the outer one), rise with back.out while font-stretch goes from 125% to 100% and the weight from 300 to 640. An IntersectionObserver and visibilitychange stop the ticker and the round when the page is not visible.

Values to change

NameFileDefaultWhat it changes
GIROscript.js26How many seconds the landscape takes to come round to the same shape.
SCALAscript.js380The size of the hills, in px: larger, wider hills and fewer lines.
DERIVAscript.js0.45How far the landscape travels in a round: higher, it changes more.
QUOTAscript.js0.07The distance between one line and the next: smaller, more lines.
MAESTRAscript.js5How often an index line, lighter, comes round.
COLLINAscript.js0.6How much the pointer raises the land (0 no hill).
LARGAscript.js95How wide the pointer's hill is, in px.
ALTOPIANOscript.js70How many px of flat land are left round the heading.
SPESSOREscript.js1The thickness of the lines, in px (index lines and the highest one a little more).

Try them in the Playground

When to use it

As the background of the first screen of a mountain hut, a mountain hotel or a holiday home in the hills, a hiking clothing brand, a trail race or a trails app; in general behind a short heading when you want a dark, living page that speaks of places. The two greys and the orange are set in the CSS.

On phones

The same animations with the sizes adapted: the grid is finer (a point every 6 px) so the lines stay smooth, the heading is smaller and the plateau follows it. The finger raises the hill while it touches and drags.

With reduced motion

The landscape is still, already risen, with the plateau under the heading: no drift, no pointer hill. The heading, the small line and the pill fade in.

Pitfalls

  • The plateau made as a rounded rectangle left a line round the heading that looked like a frame: with a rounder, slightly wider superellipse the lines go round it as round a lake.
  • The header texts sat on top of the lines and were harder to read: the canvas fades out at the top with a mask-image, and the header stays on clean black.
  • With a point every 10 px the small orange rings on the summits looked jagged: with 8 px (6 on a phone) they are round, and drawing stays at 60 frames because each cell only looks at the levels that cross it.
  • The first pointer hill was low and wide and could not be told apart from the landscape: taller and narrower, it is steeper than the land round it and reads at once as a summit with its rings.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 6.4 KB; the libraries: GSAP 28 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