Skip to content
animorio
IT
All components

The tide footer

Footers, Physics, HoverCanvas, GSAPAdvancedCompressed weight: Demo 19 KBGSAP 28 KBFreeDownload the zip

The deep blue footer of a small surf school, with the sea along its top edge: a row of springs tied to each other on three planes, with waves that run, bounce off the sides and die down, foam on the crests and the sun glinting under the surface. The pointer stirs the water, a link pointed at draws a small wave to itself, signing up to the newsletter sends a long wave from one side to the other and brings the tide up for a moment; a buoy and a board float for real.

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 tide footer</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the footer of a small surf school: the sea runs along its top edge, a row of coupled springs drawn on three
         planes with foam on the crests and the light glinting under the surface. The pointer stirs the water, a link
         pointed at draws a small wave to itself, and a sign-up to the swell report sends a long wave across the whole
         footer while the tide comes up for a moment; a buoy and a board float on it -->
    <footer class="tw" data-footer data-autoclic>
      <canvas class="tw__sea" aria-hidden="true" data-sea></canvas>
      <div class="tw__panel" data-panel>
        <div class="tw__top">
          <form class="tw__form" action="#" novalidate aria-labelledby="tw-news" data-form>
            <h2 class="tw__title" id="tw-news" data-in>The Thursday swell report</h2>
            <p class="tw__lede" data-in>The week’s best tides, the wind for the weekend and the lessons with places left.</p>
            <label class="sr" for="tw-email">Email address</label>
            <div class="tw__field" data-field data-in>
              <input class="tw__input" id="tw-email" name="email" type="email" inputmode="email" autocomplete="email" autocapitalize="off" spellcheck="false" enterkeyhint="send" placeholder="you@example.com" aria-describedby="tw-note" aria-invalid="false" data-input>
              <button class="tw__send" type="submit" data-send>
                <span class="tw__send-bg"></span>
                <span class="tw__send-label" data-send-label>Subscribe</span>
                <svg class="tw__spin" viewBox="0 0 24 24" aria-hidden="true" data-spin><circle cx="12" cy="12" r="8"/></svg>
                <svg class="tw__done" viewBox="0 0 24 24" aria-hidden="true" data-done><path d="M6.4 12.6l3.7 3.7 7.6-8.6"/></svg>
              </button>
            </div>
            <p class="tw__note" id="tw-note" aria-live="polite" data-note data-in><span class="tw__line">One email a week. Leave with one click.</span></p>
          </form>

          <nav class="tw__cols" aria-label="Footer">
            <div class="tw__col" data-in>
              <h3 class="tw__head">Learn</h3>
              <ul>
                <li><a class="tw__link" href="#" data-link>First waves</a></li>
                <li><a class="tw__link" href="#" data-link>Private coaching</a></li>
                <li><a class="tw__link" href="#" data-link>Kids’ camps</a></li>
                <li><a class="tw__link" href="#" data-link>Surf and yoga</a></li>
              </ul>
            </div>
            <div class="tw__col" data-in>
              <h3 class="tw__head">Hire</h3>
              <ul>
                <li><a class="tw__link" href="#" data-link>Boards</a></li>
                <li><a class="tw__link" href="#" data-link>Wetsuits</a></li>
                <li><a class="tw__link" href="#" data-link>Lockers</a></li>
                <li><a class="tw__link" href="#" data-link>Gift cards</a></li>
              </ul>
            </div>
            <div class="tw__col" data-in>
              <h3 class="tw__head">School</h3>
              <ul>
                <li><a class="tw__link" href="#" data-link>Surf report</a></li>
                <li><a class="tw__link" href="#" data-link>Our coaches</a></li>
                <li><a class="tw__link" href="#" data-link>Water safety</a></li>
                <li><a class="tw__link" href="#" data-link>Contact</a></li>
              </ul>
            </div>
          </nav>
        </div>

        <div class="tw__base" data-in>
          <p class="tw__brand">
            <svg class="tw__mark" viewBox="0 0 28 28" aria-hidden="true"><path d="M2.5 19.5c2.6 0 3.9-1.6 5.6-3.9 2.3-3.2 4.4-6.4 9.2-6.4 3.9 0 6.3 2.6 6.3 5.6 0 2.4-1.7 4-3.8 4-1.8 0-3-1.2-3-2.8 0-1.2.8-2 1.8-2"/><path d="M2.5 23.6c2.3 0 3.4-1.2 5.1-1.2s2.8 1.2 5.1 1.2 3.4-1.2 5.1-1.2 2.8 1.2 5.1 1.2"/></svg>
            <span class="tw__name">Tidewell Surf School</span>
            <span class="tw__copy"><svg viewBox="0 0 12 12" aria-hidden="true"><circle cx="6" cy="6" r="5.1"/><path d="M7.9 4.5a2.3 2.3 0 1 0 0 3"/></svg><span class="sr">Copyright</span> 2026 Tidewell Surf Ltd</span>
            <span class="tw__hours">Beach hut open daily, 7:30 to 19:00</span>
          </p>
          <nav class="tw__legal" aria-label="Legal">
            <a class="tw__link tw__link--small" href="#" data-link>Privacy</a>
            <a class="tw__link tw__link--small" href="#" data-link>Terms</a>
            <a class="tw__link tw__link--small" href="#" data-link>Cookies</a>
          </nav>
        </div>
      </div>
    </footer>
  </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.

56 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 tide footer” from Animorio and fit it into my site

What it does

On a black background a deep blue footer, 1100 pixels wide and about 400 tall, rounded at the bottom corners, of Tidewell Surf School, a made-up surf school. On the left the sign-up to the Thursday report (The Thursday swell report, a line saying what arrives, the email field with the Subscribe button inside it and a line of help under it), on the right three columns of links (Learn, Hire, School) and at the bottom, after a rule, the mark with its drawn wave, the copyright, the beach hut's hours and the legal links. All along the top edge is the sea, drawn on a canvas: three rows of waves one behind the other, the far ones higher, darker and calmer, and in front the near water, turquoise and a little clear just under the surface, going down until it turns into the footer's blue. A long background swell keeps rolling in, in sets that grow and fall; a thread of light runs along the faces turned to the sun and short streaks of sun glint under the surface, following its slope. On arrival the tide comes up to its level while the words rise. The pointer passing through the water pushes it down and drags it along: a wave rises ahead of the hand, a wake stays behind it, and the waves run off both ways, bounce off the footer's sides and slowly die out; a click or a tap is a pebble dropping in, with the spray falling back into the sea. Where a crest gets steep or rises fast foam is born, a white line thicker where there is more of it and a lace that trails behind and fades. Pointing at a link, or reaching it with the Tab key, sends a push running over the water towards it at the speed of the waves, so a small wave builds up on the way and arrives over the link; meanwhile the letters of the word ride it one after the other, lifting and tipping, and the word turns light. On the water float a red buoy with white stripes, with its pole, its yellow mark and its mooring line going down into the blue, and a yellow board with a coral stripe and a fin: they rise and fall with the waves and lean with the slope of the water, the board pitches and a big wave carries it forward; what sticks out of the water is seen sharp, what is under it is seen through the water. The sign-up has its states: a wrong address makes the field shake, turn coral and say what is wrong, and the water over the form gets choppy; a right one makes the button's word go, the button narrows to a circle with a spinning arc, then a tick, the line underneath says thank you, a long wave sets off from the left side and crosses the whole footer, lifts the board and the buoy, hits the other side and comes back smaller, and meanwhile the tide comes up a few pixels and goes down again. Typing another address brings the button back.

How it works

A row of springs

The surface is a row of springs every 7 pixels: each has a height and a speed and is pulled by its two neighbours (the wave equation, at the speed WAVE_SPEED), a little towards the calm level, held back by the water (DAMPING) and with a term that smooths the shortest ripples away. The ends send the waves back. The frame's step is at most 1/30 of a second and is split into steps of 1/240 inside, so the springs stay stable even with fast waves.

Three planes and the swell

There are three rows, one behind the other: the far ones stand higher, are darker and only get part of the pushes. On each row a swell is added, made of three long travelling waves whose size grows and falls in sets (SWELL); the tide lifts all three. The height is eased with a hyperbolic tangent instead of being cut, so a big crest or a deep trough never goes flat.

Pushes that run

A link pointed at starts a bell-shaped push running towards it at the same speed as the waves: that way it keeps feeding the crest it makes, and the wave builds up on the way until it arrives over the link. The sign-up does the same from one side to the other with a wide push, harder at the start, while GSAP brings the tide up by TIDE pixels and down again. The pointer pushes down where it goes down and under itself, and lifts the water ahead of it in proportion to its speed.

Foam and light

Every frame foam grows where the crest is steep, pointed or rising fast, and slowly fades: it is drawn as a white line in four thicknesses, plus a dashed lace just under it. The light is a line along the surface, stronger on the faces turned to the sun, and some fifty short streaks under the water that come and go each at its own pace, tilted like the surface and only where it faces the light.

Floating for real

The board is made of five slices: each gets a push in proportion to how far it sits under the surface, square to the surface itself, so on the slope of a wave the board slides forward; the water holds back its motion and carries it with its flow, worked out from the waves' slope. The slices' pushes also give its turning and pitching. The buoy is a ball with its weight low, which rights itself and leans with the slope, held by its mooring. Moving up and down, both push the water and send off small rings.

Values to change

NameFileDefaultWhat it changes
SWELLscript.js1How much the sea rolls on its own: at 0 it stays flat until something stirs it, and once it is calm again the canvas stops redrawing.
WAVE_SPEEDscript.js260How fast a wave runs along the water, in pixels a second.
DAMPINGscript.js0.5How quickly the waves die down: less lets them bounce off the sides for longer.
STIRscript.js1How much the pointer stirs the water as it passes through.
FOAMscript.js1How much foam the crests throw up (and how much spray): at 0 no foam.
TIDEscript.js10How many pixels the tide comes up for a moment after a sign-up.
FLOATERSscript.js2How many things float: 0, 1 (the buoy) or 2 (the buoy and the board).
WAITscript.js1.1How long the sign-up takes in the demo, in seconds.

Try them in the Playground

When to use it

For the footer of a surf school, a beach club, a board or kayak hire, a sailing club, a swimming pool, a beach festival or a swimwear brand: anywhere the bottom of the page can be the sea, and signing up deserves a wave.

On phones

The footer takes the width of the screen: the newsletter goes on top, then the columns stack, two side by side and the third underneath, with taller rows to tap; the mark, the copyright, the hours and the legal links go one under the other. The sea stays as tall with fewer springs, and the board is a little shorter and further left. A finger dragged sideways through the water stirs it like the pointer (up and down scrolls the page), a tap is a pebble dropping in, and tapping a link sends the wave its way and the letters ride it as with the hover.

With reduced motion

The sea is drawn once, still, with its waves and its glints, and fades in: no swell, no waves from the pointer, the links or the sign-up, and the tide does not move. The buoy and the board lie still on the water. Pointing at a link the word only changes colour; the button does not narrow and the arc keeps still; a wrong field does not shake.

Pitfalls

  • A still push over a link only made a hump that split in two and ran off both ways: the push runs towards the link at the speed of the waves, so it keeps feeding the same crest and the wave arrives grown right there.
  • The sign-up's long wave, with an even push, was invisible at first and huge at the end (over 40 pixels): the push is weaker but harder in the first moments, so the wave starts whole and crosses the footer at the same height.
  • With the height cut at its limits, a deep trough made by the pointer became a flat stretch and the highest crest of the tide cut the buoy's mark at the top of the canvas: the height is eased with a hyperbolic tangent, and upwards it stops leaving room for the buoy's pole.
  • Where the water went down, the straight edge of the footer's blue showed over the surface: its colour starts 30 pixels under the calm level (--drop), lower than the deepest trough, and above it there is only the canvas.
  • The board and the buoy, drawn behind the near water, which is a little clear, looked sunk even while floating: they are drawn twice, behind the water and then again clipped above the surface, so the dry part is sharp.
  • The letters split for the wave on the links were read one by one by screen readers: the whole word is in a span hidden from the eyes and the letters in a span with aria-hidden.

Libraries

GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0.

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

Testing

Tested on 8 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 components