Skip to content
animorio
IT
Back to the library

Tables on the plan

Hover, SVGGSAPMediumCompressed weight: Demo 7.9 KBGSAP 28 KBFreeDownload the zip

In the minimal style: the dining room of a small restaurant drawn like an architect’s plan, in thin lines. The table under the pointer pulls its chairs out one after the other, on a spring that overshoots by a hair, each turned a little as if someone had just stood up, and turns blue; a table already booked is hatched, its chairs stay put and the table gives a small shake. A click holds the table for you.

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>Tables on the plan</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@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">Lume</span>
      <span class="top__note">Book a table, Friday at eight</span>
    </header>

    <!-- the plan of a small restaurant drawn in thin lines. The table under the pointer pulls its chairs out, one
         after the other, as if the room were ready for you; a booked table stays put and gives a small shake -->
    <section class="room" aria-label="The dining room" data-room>
      <svg class="plan" data-plan role="img" aria-label="The plan of the dining room"></svg>
    </section>

    <div class="read" aria-live="polite">
      <span class="read__win"><span class="read__what" data-what>Choose a table</span></span>
      <span class="read__win"><span class="read__when" data-when>Friday, 8 pm</span></span>
    </div>
  </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.

64 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 “Tables on the plan” from Animorio and fit it into my site

What it does

On a paper-coloured ground there is the plan of a dining room: a rectangle of walls two pixels thick, with a gap at the bottom left for the door (its leaf drawn and its dashed swing) and two windows in the top wall, marked by a grey line and the word WINDOW. Inside there are seven pieces of furniture in thin lines, with their numbers in the middle: a round table for two, two square tables for four, a long table for six, a round table for four with its chairs on the diagonals, another round table for two and the bar counter with four stools. Tables 3 and 6 are already booked: they are grey and hatched with slanting lines. When the page opens the walls draw themselves in one stroke, the tables swell from their centres and the chairs slide in from under the tables, one table after the other; then table 2 pulls its chairs out by itself. When the pointer goes over a free table, its chairs move a few pixels away one after the other, go a hair past the mark and come back, each turned a little one way or the other; table, chairs and number turn blue. Leaving the table, the chairs go back in the opposite order. On a booked table the chairs stay put and the table gives a small sideways shake. Under the plan a line names the table (Table 2, four seats, by the window) and says on the right whether it is free; a click keeps the table yours, the chairs stay out, the inside takes a very light blue and the line says Table 2 is yours.

How it works

A plan in an SVG

The room is drawn on a plan of 1000 by 600 units inside an SVG with a viewBox, which fits any size by itself. The tables are a table (TABLES): number, shape, place, seats, a note and whether it is booked. For each shape a function works out the size of the top and where the chairs go: in a circle round the round ones, one per side for the square ones, in two rows for the long table, in a column in front of the counter. A booked table has hatching of slanting lines cut with a clipPath to its shape.

Every chair faces out

Every chair sits in a group moved to its place and turned so that its vertical axis points away from the table. So pulling it out only means moving the y of the rectangle inside the group: GSAP moves it by PULL units with back.out, each chair STAGGER seconds after the last, and turns it by TURN degrees, one chair one way and the next the other. On the way back the order is reversed and the overshoot smaller.

The pointer on the plan

The point on the screen is brought into the plan’s units with the inverse of getScreenCTM. The nearest table answers, measured from the rectangle that holds its top and its chairs, as long as it is within WALK units: so there is no dead gap between one table and the next. The colour turns blue with a tween on stroke and fill, the number takes weight on the wght axis. A booked table does not move its chairs: it gives a sideways shake with GSAP keyframes.

Tall or wide

On a screen taller than it is wide the plan is drawn with x and y swapped (a mirror on the diagonal): the room stands upright, the counter goes to the bottom, the door to the top right, and the chairs’ angles become 90 minus the angle. The words are not turned. The drawing is only redone when the screen goes from wide to tall; otherwise the SVG resizes itself.

The opening and the line at the bottom

A GSAP timeline draws the walls with stroke-dashoffset in a single stroke, brings in the door and the windows, swells the tables from their centres and slides the chairs in from under the tables, one table after the other; at the end the first free square table pulls its chairs out by itself. The line under the plan rolls through two little windows at every change: table, seats and note on the left, free, booked or yours on the right.

Values to change

NameFileDefaultWhat it changes
TABLESscript.js[[1, 'round', 170, 175, 2, 'in the quiet corner', false], …]The tables: number, shape (round, square, long or bar), place on a plan 1000 by 600, seats, a note, booked or not.
PULLscript.js13How far a chair is pulled out, in plan units.
TURNscript.js7How far a pulled chair turns, in degrees.
STAGGERscript.js0.05The pause between one chair and the next, in seconds.
OVERSHOOTscript.js2.4How far the chairs overshoot (1 barely, 4 a lot).
TIMEscript.js'Friday, 8 pm'The evening written in the line at the bottom.
WALKscript.js46How far from a table, on the plan, the pointer still chooses it.
--accentstyle.css#2446ffThe colour of the table under the pointer.

Try them in the Playground

When to use it

For the booking page of a restaurant, a bar or a trattoria, for the room of an event venue, for the tables at a wedding or the desks of a coworking space to choose on a small plan. Changing TABLES draws any room.

On phones

The same animations with adapted sizes: on a tall screen the plan turns (x and y swapped) and the room stands upright, so it fills the page. Touching a table brings its chairs out and the table stays yours; touching the floor lets it go; dragging the finger goes from table to table. The line at the bottom goes onto two lines.

With reduced motion

Nothing moves: the chairs stay where they are and the booked table does not shake. The table under the pointer turns blue with a short fade, the line at the bottom changes with a fade and the page appears already drawn.

Pitfalls

  • Moving a chair with x and y in the plan’s space needed a sine and a cosine for each one and the turn threw it off course: inside a group already turned to face out, moving y is enough.
  • With the wide plan on a phone the room became a strip two fingers tall: on tall screens x and y are swapped, and the chairs’ angles become 90 minus the angle.
  • The thin line of the furniture got thinner until it vanished as the SVG shrank: vector-effect non-scaling-stroke keeps it at one pixel at any size.
  • The ResizeObserver fires once straight away: redrawing the plan in the middle of the opening brought the tables back already still. It only redraws when the screen goes from wide to tall.

Libraries

GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 7.9 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