
Words that melt into each other
Text, Scroll, SVG
NewFree
Scroll inside the preview
As you scroll, a red cabin climbs the cable from the village in the valley to the station on top of the mountain: it swings when it starts, jolts on the rollers of every pylon, crosses woods, pastures with cows, rocks, clouds and snow while the altimeter counts the metres. At the top it docks, the doors open and the view takes the whole screen.
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 cable car up the mountain</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/big-shoulders-display@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/albert-sans@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/martian-mono@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- a made-up ski area, Alder Crown. The stage sticks while you scroll: a cable car leaves the village in the valley
and climbs the cable to the summit, swinging at every pylon, through woods, pastures, rocks, clouds and snow.
At the top it docks in the station, the doors open and the view takes the whole screen.
The landscape, the cabin and the view are SVG drawn by the script -->
<main>
<section class="corsa" data-corsa>
<div class="palco" data-palco>
<div class="cielo" aria-hidden="true"><div class="cielo__quota" data-quota></div></div>
<svg class="mondo" data-mondo aria-hidden="true"></svg>
<header class="marchio" data-hud>
<svg class="marchio__segno" viewBox="0 0 40 40" aria-hidden="true">
<path d="M3 33 15 14l6 8 5-6 11 17z" class="marchio__monte"/>
<path d="M15 14l-3 5 3-1 2 2 2-3z" class="marchio__neve"/>
<path d="M2 9 38 3" class="marchio__cavo"/>
<path d="M23 6v4" class="marchio__cavo"/>
<rect x="19" y="10" width="8" height="7" rx="2" class="marchio__cabina"/>
</svg>
<p class="marchio__nome">Alder Crown<span>Cable car</span></p>
</header>
<aside class="altimetro" data-hud aria-label="Altimeter">
<svg class="quadrante" viewBox="0 0 80 80" aria-hidden="true">
<circle cx="40" cy="40" r="37" class="quadrante__fondo"/>
<g data-tacche></g>
<path d="M40 40V19" class="quadrante__corta" data-corta/>
<path d="M40 46V9" class="quadrante__lunga" data-lunga/>
<circle cx="40" cy="40" r="3.4" class="quadrante__perno"/>
</svg>
<div class="altimetro__dati">
<p class="altimetro__etichetta">Altitude</p>
<p class="altimetro__quota" data-quota-testo>1,240 m</p>
<p class="altimetro__aria" data-aria>15 °C</p>
</div>
</aside>
<div class="zona" data-hud>
<p class="zona__etichetta">Now passing</p>
<h2 class="zona__nome" data-zona><span>Alder Hollow</span></h2>
<p class="zona__riga" data-zona-riga>The valley station opens at eight. Bells, fresh bread, one last coffee.</p>
</div>
<p class="cenno" data-cenno>
<span>Scroll to ride up</span>
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="M10 3v13M4.5 10.5 10 16l5.5-5.5"/></svg>
</p>
<div class="panorama" data-panorama>
<svg class="panorama__scena" data-pano viewBox="0 0 1600 1000" preserveAspectRatio="xMidYMid slice" aria-hidden="true"></svg>
<div class="panorama__testo">
<p class="panorama__quota" data-pano-quota>Crown Station</p>
<h1 class="panorama__titolo" data-pano-titolo>The whole range at your feet</h1>
<p class="panorama__riga" data-pano-riga>Seventy peaks in one look, a terrace in the sun and the last ride down at five.</p>
<a class="tasto" href="#" data-tasto><span>Plan your ride</span></a>
</div>
</div>
</div>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.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.
55 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 “The cable car on scroll” from Animorio and fit it into my siteThe cable runs through the two stations and the tops of the pylons; between two supports it is a parabola sagging 3% of the span, so at every pylon it makes a corner like a real cable. The cabin’s position is a number p: the whole part says the span, the decimals where it is inside it. Pylons start 300 units above the ground and a small loop raises them until the cabin hanging below always clears the ground, even over the bumps of the rocks.
ScrollTrigger gives the section’s progress, smoothed every frame; from there the phases: the doors close (up to 0.03), the journey (0.04-0.80, half linear and half power1.inOut, so it leaves and arrives slowly), then the camera moving in, the doors opening with back.out and the view widening. The section is 100lvh tall plus 900lvh times RIDE.
The cabin is a pendulum: every frame the carriage’s horizontal acceleration is measured and fed to a lightly damped spring, so it lags behind when it starts and swings forward when it brakes. When p crosses a whole number (a pylon) the angle gets a kick and so does the vertical jolt spring, and the pylon head shakes with elastic.out. In the station the damping triples and the cabin settles quickly.
Each layer has a depth d: its group moves by minus the camera position times d (0.03 the sun, 0.1 and 0.22 the ranges, 0.36 the sea of clouds, 1 the slope, 1.22 the clouds in front, 1.45 the trees and rocks in the foreground). To put something where it belongs, pick the point of the ride where it should show and draw it at camera times d plus the wanted offset on screen. The zones of the ground are stacked polygons whose toothed edge runs across the slope into the ground.
At the end the camera moves in with a scale on the whole drawing, centred on the cabin. The view is a div above the stage with an inset clip-path worked out every frame from the getBoundingClientRect of the doorway: first as wide as the open doors, then growing to the whole screen with power3.inOut. The title is a timed timeline that starts when the opening is almost done and rewinds faster if you scroll back up.
| Name | File | Default | What it changes |
|---|---|---|---|
PYLONS | script.js | 4 | How many pylons stand between the two stations, from 2 to 6: more pylons, more jolts. |
SWING | script.js | 1 | How much the cabin swings when it starts, brakes and rolls over a pylon (0 = stiff). |
BUMP | script.js | 1 | How hard the jolt is on the rollers of every pylon and at the arrival (0 = smooth). |
DEPTH | script.js | 1 | How deep the landscape is: the gap in speed between near and far layers (0 = flat). |
RIDE | script.js | 1 | How much scroll the whole ride takes: 2 is twice as much. |
COWS | script.js | 6 | How many cows graze in the pastures, from 0 to 10. |
BASE_ALT | script.js | 1240 | The altitude of the valley station, in metres: the altimeter starts here. |
TOP_ALT | script.js | 3086 | The altitude of the summit station, in metres: the altimeter ends here and writes it above the title. |
To tell a journey that climbs: the site of a ski area or a mountain hut, a lift company, a mountain hotel, a route in stages, a page that leads from the problem to the solution “at the top”, a product launch revealed only at the end.
The same animation with the sizes adapted: the view is narrower and taller, the cabin sits closer to the centre, at the start the camera looks less far back to the village, the altimeter is smaller and the zone card takes the whole width at the bottom.
No journey, no swinging and no smooth scrolling: the cabin stops at six points of the climb and the landscape fades from one to the next. The doors and the view appear with a fade, without moving in, and the title fades in; cows, smoke, clouds and birds stand still.
GSAP 3.15.0, Lenis 1.3.26, Big Shoulders Display (font variabile) 5.3.0, Albert Sans (font variabile) 5.3.0, Martian Mono (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 18 KB; the libraries: GSAP + ScrollTrigger 45 KB, Lenis 5.3 KB.
Tested on 11 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.