Case study
- Role
- Sole developer
- Organisation
- Study project
iPhone Clone
A rebuild of Apple's iPhone 16 Pro product page: a rotating 3D device you can recolour and resize at runtime, scroll-driven reveals, and the section-by-section pacing Apple uses to tell a product story. Built to understand how that class of page is actually put together.

01 / Overview
What I did.
A deliberate study of the two techniques that make pages like this work, real-time 3D and scroll-linked animation, and of the architecture underneath them. The interesting constraint was that the device model is interactive: colour and size are chosen by the visitor, which rules out most of the shortcuts a page like this could otherwise take.
02 / Architecture
Layers listed outermost first.
How it's put together.
Each section of the story owns its own animation lifecycle, and the 3D scene is a single long-lived canvas that sections drive rather than each creating their own. Splitting it the other way, with one global timeline or a scene per section, is what makes these pages stutter.
Page composition
One component per story beat.
Hero, video, model viewer, chip, intelligence, titanium. Each section is self-contained and sets up and tears down its own animations, so a change to one beat cannot desynchronise another.
3D scene
The device, live.
A Three.js scene holding the iPhone model, with materials swapped for the colour variants and the camera and model scaled for the two size options. Rendered into one canvas that persists across the section rather than being recreated.
Scroll choreography
Position in the page drives the animation.
GSAP timelines bound to scroll position, so progress through a section is progress through its animation, scrubbable in both directions rather than fire-and-forget on entry.
Media
Video as a first-class section.
Embedded product video treated as part of the scroll narrative rather than a widget dropped into the page.
03 / Decisions
Each of these had a credible alternative. The trade-off is stated, not hidden.
Choices, and what they cost.
A real Three.js model, not a pre-rendered image sequence
- Chose
- A live 3D scene with runtime materials and scaling
- Instead of
- A pre-rendered sprite sheet or frame sequence per variant
- A static hero image
- Why
- The page lets the visitor pick a colour and a size. With pre-rendered frames that is a full rotation sequence per colour per size: every combination shipped as image data, and every new variant a re-render. A real scene makes a colour change a material swap, so the number of variants stops affecting the payload at all.
- Trade-off
- It costs GPU time on the client and needs a genuine loading state for the model, where an image sequence would have degraded gracefully to simply appearing slowly.
GSAP timelines over CSS scroll-driven animation
- Chose
- GSAP with scroll-bound timelines
- Instead of
- CSS scroll-driven animations
- IntersectionObserver triggering CSS transitions
- Why
- The sections sequence several elements against each other and against scroll position, and need to run correctly when scrolled backwards. A timeline is the right model for that, because you can position, overlap and scrub it. IntersectionObserver only tells you something entered the viewport, which is enough for a fade and not for choreography.
- Trade-off
- A JavaScript animation dependency on the critical path, and animation that no longer respects a reduced-motion preference for free, so that has to be handled explicitly rather than inherited from the platform.
A persistent canvas driven by sections, not a canvas per section
- Chose
- One long-lived scene the sections animate
- Instead of
- Mounting a new Three.js canvas per section that needs 3D
- Why
- Creating and destroying WebGL contexts as the visitor scrolls means repeated model parsing, repeated context setup and a visible hitch at every boundary, and browsers limit how many contexts you may hold at once. One scene pays the setup cost once.
- Trade-off
- The scene becomes shared state between sections, so its lifecycle has to be managed above them rather than by whichever section is currently on screen.
04 / Stack
Grouped by the job they do rather than listed as a keyword run.
Technologies.
- Application
- 3D
- Animation
- Hosting
05 / Gallery
Select any image to view it full size.
How it looks.
Sections
Hero. Video, sequenced into the scroll narrative. The live model, with colour and size chosen at runtime, which is why it is a real scene rather than pre-rendered frames. Rotation, driven by scroll position. Material storytelling. Chip section. Intelligence section.
06 / Outcome
Where it landed.
Hands-on understanding of scroll-linked animation, WebGL lifecycle and the performance ceiling of both. More usefully, it taught me to read a high-fidelity commercial page and work out which of its effects are architectural decisions and which are decoration. That habit transfers to work far less flashy than this.