
Marquee that speeds up with scroll
Scroll, Text, Hover
Free
The rooms of a small hotel, in the minimal style: five narrow, light names. Under the pointer the name widens on the wdth axis and takes weight as much as its room is big, the others turn grey, and one thin vermilion dimension line glides on a spring to the row and stretches to the room’s square metres, to the same scale for all of them, while the number counts.
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>Rooms to measure</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>
<main class="stage" data-stage>
<header class="top">
<span class="top__name">Halden</span>
<span class="top__note">Rooms</span>
</header>
<!-- the rooms of a small hotel, one name per row, all narrow at rest. Under the pointer the name widens and takes
weight as much as its room is big, and one thin dimension line glides to it and stretches to the room's floor
area, while the square metres count -->
<ul class="rooms" aria-label="Rooms" data-rooms>
<li class="quota" aria-hidden="true" data-quota>
<i class="quota__line" data-quota-line></i>
<i class="quota__tick quota__tick--start"></i>
<i class="quota__tick quota__tick--end" data-quota-end></i>
<span class="quota__read" data-quota-read>0 m²</span>
</li>
</ul>
<p class="hint" data-hint>Point at a room</p>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.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.
27 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 “Rooms to measure” from Animorio and fit it into my siteThe dimension line is a single element, absolute inside the list: a one pixel line scaled with scaleX, a fixed tick at the start and one at the end moved with translateX, the number right after. Its length is the room’s area divided by the biggest one, times the width of the list less the room for the number: so the rooms can be compared at a glance.
Every frame, in GSAP’s ticker, the line follows the chosen row with a spring (LINE_SPRING) vertically and another one in length, in small steps of 1/240 of a second so the spring is the same at any screen rate. When it arrives within a pixel, the end tick gets a knock on a third, very stiff spring and gives a small jolt in height.
Archivo is variable in width (62–125) and weight (100–900). The name under the pointer goes from WIDTH[0] to WIDTH[0] + (WIDTH[1] − WIDTH[0]) × area / biggest area, and the same for the weight: the smallest room widens just a little, the biggest all the way. Every name has its own springs (NAME_SPRING) on both axes, written in font-variation-settings only when they change.
The number at the end of the line is the current length turned back into square metres, so it counts as the line grows; it never goes past the room’s area (nor the starting one), even when the spring overshoots.
The chosen row comes from the pointer’s y inside the list, so passing to the right of the name is enough. With a finger a touch chooses the room and leaves it chosen, dragging changes it, a touch outside lets it go; a touch or a mouse arriving during the opening are kept for when it ends. The rows have a tabindex and keyboard focus does the same.
| Name | File | Default | What it changes |
|---|---|---|---|
ROOMS | script.js | [['Single', 16], ['Double', 24], …] | The rooms: name and floor area in square metres. |
WIDTH | script.js | [80, 125] | The width axis of a name at rest and of the biggest room under the pointer (62 to 125). |
WEIGHT | script.js | [300, 680] | The weight of a name at rest and of the biggest room under the pointer (100 to 900). |
LINE_SPRING | script.js | [260, 26] | The dimension line’s spring: how stiff, and how much it is held back (less holds wobble more). |
NAME_SPRING | script.js | [210, 20] | The names’ spring, on their axes. |
UNIT | script.js | 'm²' | The unit written after the area (sq ft, for example). |
For a list of rooms in a hotel, a B&B or a holiday home, for the flat layouts of an estate agent, for the spaces to rent in a coworking or the halls of an event venue: wherever comparing sizes matters. It works with any quantity to compare (seats, metres, kilos) by changing ROOMS and UNIT.
The same animations with adapted measures: smaller names and a shorter line. Touching a room chooses it and it stays chosen, dragging the finger moves to the others and the line follows, a touch outside closes it. The hint at the bottom says Touch a room.
No springs: the dimension line appears already on the row and already as long as the room, with a short fade, and disappears the same way; the names change width, weight and colour without wobbling. When the page opens names and header fade in.
GSAP 3.15.0, Archivo (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 5.8 KB; the libraries: GSAP 28 KB.
Tested on 19 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.