Three.js 3D Scroll Experience
What it does
A fixed Three.js chair model (GLB) scales in on load, floats with a sine bob, and tilts on its X axis proportionally to scroll progress driven by a Lenis + GSAP ticker loop; a SplitType-lined outro headline reveals via a staggered translateY masked by ScrollTrigger.
How it's built
| Category | 3d-webgl |
|---|---|
| Tech | gsap, three, lenis, split-type |
| GSAP plugins | ScrollTrigger |
| Complexity | page |
| Performance cost | heavy |
| Mobile-safe | desktop-first |
| Scroll | hijacks scrolling |
How it works
An editorial page for a furniture studio with one designer chair floating over everything. When the page opens, the chair grows out of nothing in the middle of the screen. From then on it never stops breathing: it bobs gently up and down on its own. And the page scroll turns it: as you move down through the huge headline, the collection list and the closing statement, the chair tumbles slowly head over heels, all the way round and round again by the time you reach the bottom. The type scrolls underneath it, so the object always sits in front of the content like a piece on a plinth.
It combines Three.js for the model, GSAP with ScrollTrigger for the text and the entrance, Lenis for smooth scrolling and SplitType for the line reveal.
A fixed object over a moving page
The 3D scene is not part of any section. It is one transparent WebGL canvas fixed over the whole viewport, above the page, and the content scrolls beneath it. That simple layering is what makes the chair feel like it belongs to the whole page rather than to one block.
The chair is loaded from a glTF file, centred on its own bounding box and framed by placing the camera at a distance proportional to its largest dimension, so any reasonably modelled piece of furniture fits without tuning.
Two motions added together
The model's movement is the sum of two independent parts computed on every frame. One is a slow sine wave on its height, which runs forever whether or not you scroll and keeps the object alive at rest. The other is its tilt, which is read from the page's scroll position as a fraction from top to bottom and turned into rotation. The rotation is recalculated absolutely each frame rather than added in steps, so it always matches the scrollbar exactly, reverses perfectly when you scroll up and stops when you reach the end. Lenis and the render loop share GSAP's ticker, so the smooth scroll and the frame that draws the chair are always in step.
The entrance and the closing line
The entrance is a short GSAP tween on the model's scale from zero, played once the file has loaded. The closing headline is split into lines, each wrapped in a clipping mask with its text pushed below, and when the section reaches the middle of the screen the lines rise in turn; scrolling back hides them again.
Where it gets hard, and mobile
The look depends on real display typography and a dark page as much as on the model, and the transparent canvas must sit above the content without blocking it. The scene renders at the full device pixel ratio with shadows enabled, which is heavy for phones; capping the pixel ratio, dropping shadows and handling resize are the first changes to make before shipping it on mobile.
Rebuild it with AI
This component's prompt is part of the paid library. Below you can read how it starts; the full prompt, the exact structure, timing and easing an AI agent needs to rebuild the effect, unlocks with any paid plan, yearly or lifetime.
# Three.js 3D Scroll Experience
## Goal
Build a full-page editorial hero for a fictional furniture design studio (**"oak atelier"**) whose star effect is a **fixed Three.js furniture model** (a designer chair loaded from a GLB) floating in the center of the viewport. On load the model **scales up from nothing** with an elastic-free ease; it then **bobs gently up and down forever** (a sine float) while its **X-axis rotation is driven directly by page-scroll progress** — as you scroll the 400vh page the chair tumbles head-over-heels through two full revolutions (4π radians). Smooth scrolling is handled by **Lenis**, wired into GSAP's ticker, and the same ticker also runs the Three.js render loop. A secondary effect: the closing headline is split into lines and **each line masks up into view with a staggered translateY** via ScrollTrigger.
## NON-NEGOTIABLE visual requirements (get these exactly right)
These are essential — a reproduction that misses them does not look like the original, even if the animation is perfect:
1. **Dark canvas, always.** The page background is a near-black **`#111111`** with **white (`#fff`) text**. There is no light mode, no white page. The transparent WebGL chair floats above this dark canvas. If you ship a white/unstyled page you have failed the brief.
2. **The stylesheet MUST be linked.** The `index.html` `<head>` must contain `<link rel="stylesheet" href="./styles.css" />`. Without it the page renders 100% unstyled (white background, browser-default type, a raw blue underlined link) — this is the single most common way this build breaks. See the full HTML skeleton below.
3. **Real display typography.** A **huge 225px uppercase grotesque headline** and **120px serif archive titles** — load actual web fonts (below). System-font fallbacks (Helvetica/Times) do not read like the original.
## Tech
Vanilla HTML/CSS/JS with ES module imports. Use **`gsap` (npm)** plus the GSAP plugin **`ScrollTrigger`**, **`three`** (Three.js core + `GLTFLoader` from `three/examples/jsm/loaders/GLTFLoader.js`), **`lenis`** for smooth scroll, and **`split-type`** for the headline line-split. Imports:
```js
import gsap from "gsap";
…
Premium prompt
Unlock this prompt, and every other one
From $99/year, or $139 once for lifetime access. Commercial license included.
See pricing Or start with the free set Already bought? Sign in
New components in your inbox
One email a week, only when new components ship, each with its live demo and prompt.