
Marquee that speeds up with scroll
Scroll, Text, Hover
Free
Scroll inside the preview
The last section of the page slides away and uncovers the footer, still underneath as if it had always been there, while the letters of the motto rise one after the other out of their line. Once it is open, the letter under the pointer reaches for it, up or down, its two neighbours follow half as far, and all three take a colour and lean towards the hand.
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>Letters within reach</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/familjen-grotesk@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- the last section of the page: it slides away and uncovers the footer -->
<main class="closing">
<div class="closing__inner">
<p class="closing__brand">Common Room</p>
<h1 class="closing__title">Long tables, loud dinners, and chairs that can take it.</h1>
<p class="closing__line">Oak tables for ten, benches for twelve, chairs that stack when the guests go home.</p>
<a class="closing__button" href="#">Find your table</a>
</div>
<p class="closing__hint" data-hint>Scroll to the end</p>
</main>
<!-- the footer waits under the page: the mask makes room for it, the footer itself stays put while the page moves -->
<div class="mask" data-mask>
<footer class="foot" data-foot>
<div class="foot__top">
<p class="foot__lead">Dinner is better with more people at the table.</p>
<nav class="foot__cols" aria-label="Footer">
<div>
<p class="foot__head">Shop</p>
<a href="#">Tables</a>
<a href="#">Benches</a>
<a href="#">Chairs</a>
</div>
<div>
<p class="foot__head">Visit</p>
<a href="#">The workshop</a>
<a href="#">Opening hours</a>
</div>
<div>
<p class="foot__head">Say hello</p>
<a href="#">Write to us</a>
<a href="#">Instagram</a>
</div>
</nav>
</div>
<!-- the motto: each letter is its own span, so the pointer can reach it -->
<p class="slogan" data-slogan aria-label="good company">good company</p>
<div class="foot__bottom">
<p>Common Room, tables built in small batches</p>
<button class="foot__top-link" type="button" data-top>Back to top</button>
</div>
</footer>
</div>
<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/gsap@3.15.0/dist/CustomEase.min.js"></script>
<script src="script.js"></script>
</body>
</html>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.
36 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “Letters within reach” from Animorio and fit it into my siteThe footer sits in a mask as tall as itself, under the closing section, which has the higher z-index. A single ScrollTrigger tween moves it from yPercent −100 to 0 while the mask travels from the bottom of the screen to its own lower edge, scrubbed and with no curve: the footer comes down exactly as far as the page goes up, so on screen it stays still and looks uncovered rather than arriving.
The motto is split into letters, each made of two spans. The outer one waits RISE heights further down, hidden by the line’s overflow: hidden, and rises with a paused timeline that follows the footer’s progress: STAGGER seconds between one letter and the next, on a CustomEase curve that lands softly. At 95% of the opening the line opens up (overflow: visible) and the letters may leave it; it closes again only under 88%, so it does not flicker at the edge.
The letter under the pointer is the one it is over, measured with offsetLeft and offsetWidth, which ignore transforms; between two letters it is the nearer one. The space does not count: the neighbours of “d” are “o” and “c”. Before anything else the pointer must be inside the visible part of the footer, or the letters go back into place.
The vertical distance between the pointer and the line, times REACH (a quarter for the letter under it, an eighth for its neighbours), says how far the inner span moves. The lean comes from the horizontal distance to the letter’s centre, up to LEAN degrees, in the direction that turns it towards the hand. The colour is fixed per letter, from the COLORS list. Every change is a PAINT-second tween with overwrite auto, and only when the value really changes.
After GHOST seconds with no pointer on the footer, a GSAP ticker moves a fake pointer: back and forth across the motto in 5.2 seconds, up and down on a faster sine, always inside the footer. One real move is enough to switch it off.
| Name | File | Default | What it changes |
|---|---|---|---|
REACH | script.js | 0.25, 0.125 | How far the letter under the pointer follows it, and how far its two neighbours, as a part of the distance from the line. |
LEAN | script.js | 6 | How far the reached letters lean towards the pointer, in degrees. |
PAINT | script.js | 0.18 | The seconds a letter takes to change colour and height. |
SETTLE | script.js | 0.28 | The seconds they take to settle back into line when the footer closes. |
RISE | script.js | 1.3 | How far below the line the letters wait before the footer opens, in letter heights. |
STAGGER | script.js | 0.04 | The delay between one letter and the next as they rise, in seconds of a 0.6-second rise. |
GHOST | script.js | 2.5 | The seconds without a pointer before the invisible hand plays with the letters. At 0 it never comes. |
COLORS | script.js | #d9643a, #7d8b4a, #9b6aa8, #e8a427, #3e8e8c | The letters’ colours, one per letter, in turn. |
--sand | style.css | #e8dcc6 | The footer’s colour. |
--night | style.css | #1f2a22 | The colour of the section that slides away. |
For the footer of any site with a name or a short motto to show big: two words, a dozen letters at most. With a long phrase the letters become small and the game cannot be read. It wants a solid typeface with separate letters; a joined script would break at its connections.
The footer is uncovered the same way, scrolling with a finger. Touching the motto and dragging, the letters follow the finger; over the motto the page does not scroll, above it it does. When the finger lifts the letters go back into line and, after two and a half seconds, the invisible hand comes.
The footer simply sits under the page and the letters are already in line. Under the pointer they take their colour but neither move nor lean, and there is no invisible hand.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, CustomEase (GSAP) 3.15.0, Familjen Grotesk (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.1 KB; the libraries: GSAP + ScrollTrigger + CustomEase 49 KB.
Tested on 1 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.