Skip to content
animorio
IT
Back to the library

Rooms to measure

Hover, TextGSAP, CSS onlyMediumCompressed weight: Demo 5.8 KBGSAP 28 KBFreeDownload the zip

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.

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>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>

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.

27 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 “Rooms to measure” from Animorio and fit it into my site

What it does

On warm white paper, at the top the name of a small made-up hotel, Halden, and on the right Rooms; in the middle five large room names, one under the other, in narrow and light Archivo: Single, Double, Garden room, Junior suite and Loft. When the page opens the names rise one after the other out of a slot. Under the pointer the room’s name widens on the width axis and takes weight, the more the bigger the room is: the Single just a little, the Loft all the way; the other names narrow a little and turn grey. Under the name a thin vermilion dimension line, a hairline with a vertical tick at each end, opens from the left margin and stretches to the room’s square metres, to the same scale for all of them: 16 m² is a short line, 68 m² crosses almost the whole page. At the end of the line the number counts as it grows. Moving to another room the same line glides on a spring to the new row and changes length, going a hair too far and back; when it lands the end tick gives a small jolt. Leaving the list the line folds back to the left and the names all go back to the same.

How it works

One dimension line for all the rows

The 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.

The springs in the ticker

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.

The name as wide as the room

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 counting number

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.

Pointer, finger and keyboard

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.

Values to change

NameFileDefaultWhat it changes
ROOMSscript.js[['Single', 16], ['Double', 24], …]The rooms: name and floor area in square metres.
WIDTHscript.js[80, 125]The width axis of a name at rest and of the biggest room under the pointer (62 to 125).
WEIGHTscript.js[300, 680]The weight of a name at rest and of the biggest room under the pointer (100 to 900).
LINE_SPRINGscript.js[260, 26]The dimension line’s spring: how stiff, and how much it is held back (less holds wobble more).
NAME_SPRINGscript.js[210, 20]The names’ spring, on their axes.
UNITscript.js'm²'The unit written after the area (sq ft, for example).

Try them in the Playground

When to use it

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.

On phones

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.

With reduced motion

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.

Pitfalls

  • A pointer already over the list during the opening did nothing: the events arrive before the list is ready. The last position of the mouse (and of the finger) is kept and used as soon as the opening ends.
  • The number at the end of the line, computed from its length, showed 70 m² for a 68 m² Loft while the spring overshot: now it never goes past the room’s area.
  • The preview moves a fake pointer that sends pointerleave from every element it leaves: only a pointerout with no destination and outside the window says the mouse has gone.

Libraries

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.

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