Skip to content
animorio
IT
All components

The room chart

Charts, Physics, SVG, TransitionsGSAPAdvancedCompressed weight: Demo 13 KBGSAP 28 KBFreeDownload the zip

Where a solar home's energy goes, drawn as the house cut in half: every use is a room as wide as its share of the month. Changing the month the walls slide on springs and the lamps hanging from the ceilings swing with the jolt; the chosen room switches its light on, a warm cone that sways with the lamp, and the others go dark. In January the panels are under snow, which melts in spring.

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 room chart</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/albert-sans@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the energy card of a home with solar panels: where a month's energy went, drawn as the house cut open. Every
         use is a room, as wide as its share of the month; changing the month the walls slide on springs and the lamps
         swing. The use picked with the pointer, a finger or the keys switches its light on, and the other rooms go
         dark. The house is drawn by the script; the numbers are in a table for screen readers -->
    <section class="home" aria-labelledby="home-title" data-home>
      <div class="home__head">
        <h2 class="home__title" id="home-title">Home energy</h2>
        <div class="months" role="tablist" aria-label="Month" data-months data-autoclic>
          <span class="months__thumb" aria-hidden="true" data-thumb></span>
          <button class="months__btn" type="button" role="tab" aria-controls="home-house" data-month>Jan</button>
          <button class="months__btn" type="button" role="tab" aria-controls="home-house" data-month>Apr</button>
          <button class="months__btn" type="button" role="tab" aria-controls="home-house" data-month>Jul</button>
        </div>
      </div>

      <p class="home__figure"><span class="home__value" data-value>0</span><span class="home__unit">kWh</span></p>
      <p class="home__note" data-note></p>

      <div id="home-house" role="tabpanel" data-panel>
        <div class="house" data-house>
          <svg class="house__svg" aria-hidden="true" data-svg></svg>
        </div>

        <div class="key" role="group" aria-label="Where it went" data-key></div>

        <table class="sr" data-table></table>
      </div>
      <p class="sr" aria-live="polite" data-said></p>
    </section>
  </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.

31 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 room chart” from Animorio and fit it into my site

What it does

On a black background a dark card 440 pixels wide: Home energy, on the right three months in a grey track, Jan, Apr and Jul, below them a big total, 1,300 kWh, with In January, 19% came from your panels. In the middle a house seen from the front with its front wall taken away: a grey roof with two rows of solar panels, half under snow, and five rooms in a row, each in the colour of its use and as wide as its share of the month: the blue garage with the car and its charging cable, the orange room of the heat pump, the green bathroom with the shower, the yellow kitchen with the pot and the pink study with the laptop. Every room is a box seen from the front, with its ceiling, floor and sides in shadow, and a lamp hangs from every ceiling. Under the house, in the same order as the rooms, the key: for every use its drawing in its colour, its name and its percentage. When the page opens the rooms start all the same and the walls slide to their places, the lamps sway, the snow settles on the roof and the numbers count up. Choosing another month a pill slides under its name and the four walls slide to their new places, one a moment after the other, go a little too far and come back; the lamps lag behind when the ceiling sets off and swing when it stops, then calm down. In January the heat pump takes nearly half the house, in July the garage; the snow melts from the bottom up to the ridge and uncovers the panels, while the total and the percentages count to their new values. Moving over the house or the key, touching a room or sliding a finger across it, or with the arrows on the key, the chosen room switches its light on: under the lamp a warm cone opens and lights the object and the floor, and the object starts working (the fan turns, the shower runs, the pot steams, the laptop types, the cable charges the car). The other rooms go dark and keep only a veil of their colour, with their drawing and lamp in the room's colour; at the top the total counts to that use's kWh and under it the name appears with its share of the month. If the light is on while the month changes, the cone sways with the lamp.

How it works

A stacked bar with a roof

The five rooms stand in a row and each is as wide as its share of the month, worked out from the real kWh: the house is a stacked bar, with the walls between the rooms in place of the two-pixel gaps. The percentages written down are rounded by largest remainder, so they always add up to a hundred. The drawing is as wide as the card, so its sizes are real pixels on a phone too.

The walls on springs

Every wall is a number, the share of the month to its left. Changing the month its goal slides to the new place in SLIDE seconds with power2.inOut, each wall 30 milliseconds after the one before, and the wall chases it on a spring (WALLS): it lags a little, goes too far and settles. The spring is worked out in steps of 1/240 of a second on GSAP's ticker, and each wall's acceleration comes from there too.

The lamps are pendulums

Every lamp is a pendulum 18 centimetres long, if a pixel were a centimetre: θ'' = −ω²(sin θ + SWING · 0.4 · a/g · cos θ) − damping, where a is the ceiling's acceleration, the average of the room's two walls. So the lamp lags when the ceiling sets off and swings when it stops, and calms down within a second and a half.

The light on

The chosen room shows a warm cone hanging from the lamp, turning with it, a pool of light on the floor following the cone's tip and a glow on the ceiling, all cut to the room by a clipPath that moves with the walls. The other rooms keep NIGHT of their colour, and the drawing and the lamp go from the card's colour to the room's, so they can still be read in the dark. The object works on a clock that runs as fast as the light is on: switching off, it slows down and stops without a jump.

The snow and the numbers

The snow is a path from the ridge down with a wavy edge and a few round drips, cut to the roof: its depth goes to one in January and to zero in the other months, and the edge climbs back to the ridge as it melts. The total and the percentages count with GSAP; the line under the total says how much came from the panels, or the name and share of the use that is lit.

Keys, fingers, screen readers and the preview

The months are tabs with the arrow keys. The key is a group of buttons with the arrows, Home and End: the light follows the focus, Esc turns it off, and an aria-live region reads the use, its kWh and its share; a hidden table holds every number of the month. With a mouse, passing over lights a room and a click keeps it lit; with a finger a touch lights it, sliding changes room, a second touch turns it off. A click from a script on the months (the library's preview) picks the next month and, once the walls are done, lights the room that grew the most.

Values to change

NameFileDefaultWhat it changes
SLIDEscript.js0.6The seconds the walls take to slide to a new month.
WALLSscript.js[260, 0.5]The springs that pull the walls: how stiff they are and how much they are held back (1 = no overshoot).
SWINGscript.js1How much the lamps swing when the walls move (0 = they hang still).
GLOWscript.js0.75How bright the light is in the room that is lit.
NIGHTscript.js0.2How much colour the other rooms keep while one is lit.
COUNTscript.js0.7The seconds the numbers take to count to new ones.

Try them in the Playground

When to use it

For the app of a home with panels and a heat pump, an energy supplier's dashboard, a bill explained, but also for any total that splits into parts tied to places: a shop's spending by department, an office's hours by room. The change of month shows where the spending moved (winter into the heat pump, summer into the garage), and the light switched on answers the viewer's question: how much does this part weigh?

On phones

On a phone the card takes the width of the screen and the house is redrawn at its size, the rooms in real pixels and as many panels as fit; in narrow rooms the object gets smaller. Touching a room switches its light on, sliding the finger sideways goes from room to room (the page still scrolls up and down), and a second touch or a touch outside turns it off. The key tightens its columns so the names fit whole.

With reduced motion

The walls do not slide and the lamps do not swing: changing the month the house fades out, changes and fades back in, and the numbers change at once. The light still fades on and off, the objects stay still and the snow appears and goes without coming down.

Pitfalls

  • With springs alone the walls arrived in a quarter of a second and the change could not be seen; with the true physical push the lamps would have gone round. Each wall's goal slides with an ease and the wall chases it on its spring, and the push on the lamp is scaled down (0.4): so the lamp lags at the start and swings at the end, by fifteen or twenty degrees.
  • Rounding the percentages one by one gives 99 or 101: largest remainders are used. And the loop adding the missing points must count them first, not read the sum again on every turn, or it stops after the first (here the heat pump said 47% instead of 48%).
  • Five colours that touch: in the house only neighbouring rooms touch, so the fixed order of the colours was tested on neighbouring pairs (distance for colour-blind eyes at least 8.4, for normal sight at least 19.3), and every use also has its drawing and its name.
  • Dimming the key with opacity took the names below 4.5:1 contrast: in the dimmed entries only the drawings fade, and the percentages turn to the grey of the labels.
  • Putting the object back to rest when the light went off made the fan jump and turned the water's dashes into lines at once: the object's clock runs as fast as the light is on, and the gaps between the dashes close with it into a line.
  • A mouse click focuses the button before the click: if the focus lights the room and the click toggles it, the light goes straight off. The focus lights only when it is :focus-visible, that is from the keyboard.
  • Leaving the key for the months switched the room off, so the same use could not be seen in another month: the light goes off only when the focus leaves the card.
  • stop-color in the markup does not read CSS variables: the light's colour is read from the stylesheet and written into the stops, the panels' sits in a style attribute.

Libraries

GSAP 3.15.0, Albert Sans (font variabile) 5.3.0.

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

Testing

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