
Projects with elastic lines
Hover, Physics, SVG
NewFree
A tiled floor seen from above at an angle, drawn tile by tile in SVG. Under the pointer the tiles rise like little columns, the one underneath most and the others less and less, each on a spring. A click drops a pebble and a ring of raised tiles runs away from it; the two pieces standing on the floor go up and down with their tile.
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>Tiles that rise</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/fraunces@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/dm-sans@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="room" data-room>
<header class="bar">
<a class="brand" href="#">Grout & Co.</a>
<nav class="bar__nav" aria-label="Sections">
<a href="#">Terracotta</a>
<a href="#">Zellige</a>
<a href="#">Showroom</a>
</nav>
</header>
<div class="words">
<h1 class="words__title">Floors you want to touch.</h1>
<p class="words__line">Hand-glazed terracotta and zellige, laid by people who care about the grout.</p>
<a class="words__button" href="#">Book a showroom visit</a>
</div>
<!-- the floor: an isometric grid drawn by the script, one group per tile (two sides and the top) -->
<svg class="floor" data-floor aria-hidden="true"></svg>
<p class="hint" data-hint>Move over the floor. Click to drop a pebble.</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.
24 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 “Tiles that rise” from Animorio and fit it into my siteThe floor has its own coordinates, u and v, in tiles; on screen they become x = X0 + (u − v) · L/2 and y = Y0 + (u + v) · L/4, where L is a tile’s width from corner to corner. The same formula backwards takes the pointer onto the floor. Only the tiles that can be seen are made, plus a margin for raised ones.
Every tile is an SVG group with three polygons: the two front sides and the top. The top moves up by THICK plus the height; the sides run from the corners on the floor to those of the top, so at rest they are a thin edge and they stretch as the tile rises. The sides take the tile’s colour at 80% and 66%.
The tiles are added diagonal by diagonal, from the furthest to the nearest, so a raised tile covers the ones behind it and is covered by the ones in front without sorting anything. Each piece goes in right after its tile, and rises with it through a group that gets the same height.
For every tile the height wanted is LIFT · (1 − d/RADIUS)², where d is the distance from the pointer measured on the floor, in tiles: that is why the raised area is a circle on the floor and an ellipse on screen. The real height follows it on a spring, SPRING, stiffness and damping, which overshoots a little and comes back. Tiles at rest and at zero are not redrawn.
A click adds a growing ring: at distance d and time t it is worth PEBBLE[0] · e^(−PEBBLE[2]·t) · e^(−((d − PEBBLE[1]·t)/0.9)²). The rings add up with the pointer and go through the spring too, so the tiles sway as one passes.
| Name | File | Default | What it changes |
|---|---|---|---|
TILE | script.js | 74 | A tile’s width on screen, corner to corner, in pixels; on a narrow screen it shrinks. |
RADIUS | script.js | 2.4 | How far around the pointer the tiles rise, in tiles. |
LIFT | script.js | 34 | How high the tile under the pointer rises, in pixels. |
SPRING | script.js | 260, 15 | Every tile’s spring: stiffness and damping. With less damping they bounce more. |
PEBBLE | script.js | 26, 7, 1.6 | The pebble: its ring’s height in pixels, its speed in tiles per second, how fast it dies down. |
WANDER | script.js | 2.5 | The seconds without a pointer before an invisible one walks over the floor; at 0 never. |
GLAZES | script.js | #c8694a, #efe3cf | The chequerboard’s two glazes. |
JITTER | script.js | 0.05 | How far each tile’s glaze strays from its neighbours’, as in handmade tiles. |
THICK | script.js | 4 | A tile’s edge at rest, in pixels. |
For an opening page that should make people want to touch: tiles, floors, board games, a map, a chequerboard of products. It works with tiles big enough to be seen rising, 50 to 90 pixels, and a calm background; with small tiles the picture becomes a shimmer.
The floor starts lower and the tiles are smaller (at least 44 pixels). A finger on the floor raises them like the pointer and a tap drops the pebble; when the finger lifts, after two and a half seconds the invisible pointer walks. Over the floor the page does not scroll.
The tiles do not move and there are no pebbles and no walks: under the pointer the top faces lighten, up to a third of the way to white for the one underneath, and go back to their colour when the pointer leaves.
GSAP 3.15.0, Fraunces (font variabile) 5.3.0, DM Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.3 KB; the libraries: GSAP 28 KB.
Tested on 2 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.