Case Study · Interactive 3D Web

Apollo Tyres
Experience.

An immersive, scroll-driven 3D product showcase that turns a commodity tyre into a cinematic brand journey — built with React 19, Three.js, and a single design system shared across the DOM and the WebGL scene.

Overview

Apollo Tyres Experience is a single-page, fully immersive 3D website that turns a tyre product catalogue into a guided brand story. A photorealistic 3D tyre sits at the centre of the screen and animates continuously as the visitor scrolls, leading them through six full-screen narrative sections — a rotating hero product slider, a vehicle selector, durability and safety stories, a feature grid, and a final call-to-action.

The defining idea: the 3D scene and the HTML content are not two layers stacked on top of each other — they are one choreographed experience sharing a single colour palette, lighting language, and motion system.

Type
Interactive 3D Showcase
Platform
Responsive Web
Role
Design + Front-end
Built At
Bardbox Digital Growth LLP

The Challenge

Tyres are a low-engagement, high-commodity product — most tyre websites are static spec sheets. The brief was to make a tyre feel premium, engineered, and worth exploring, the way a car or a flagship phone is marketed. That created three hard problems:

The Approach

1. Scroll as the storytelling engine

Instead of native browser scroll, the experience is driven by ScrollControls from @react-three/drei across six "pages" of content. Native scrollbars are hidden and overflow is locked, so scrolling becomes a timeline scrubber rather than a document scroll. The tyre's movement is defined as keyframes — position and rotation targets at specific scroll offsets — interpolated with a smoothstep easing curve and continuous rotation to avoid any snapping:

const ANIMATION_SEQUENCE_DESKTOP = [
  { t: 0.00, pos: (0, -25, 0),     rot: (0, 0.4, 0) },    // Hero: centre
  { t: 0.18, pos: (130, 0, -50),   rot: (0.1, 1.8, 0.1) },// Vehicle select
  { t: 0.35, pos: (100, -10, -60), rot: (0, 3.2, 0.2) },  // Durability
  { t: 0.55, pos: (-120, 5, -40),  rot: (-0.1, 4.8, -0.1)},// Safety
  { t: 0.75, pos: (0, -10, -100),  rot: (0, 6.2, 0) },    // Features
  { t: 1.00, pos: (0, -30, -200),  rot: (0.2, 7.5, 0) }   // Footer: recedes
];

The camera itself reacts to scroll velocity — a "rush" impulse zooms in when scrolling down and eases out when scrolling up — giving the whole page a sense of momentum.

2. One palette, two renderers

The entire design system is declared once in the Tailwind config. The same hex values feed both Tailwind CSS classes and the Three.js lights and materials, so the WebGL tyre and the HTML headlines read as a single scene lit by the same studio.

Token Hex In the DOM In the 3D scene
orange #f7941d CTAs, accents Rim light, hover-pulse emissive
purple #5c2d91 Vehicle selector, borders Fill light, idle "breathing" emissive
backdrop #050505 Body background Canvas clear colour

3. A studio lighting rig in WebGL

Rather than flat lighting, the scene uses a multi-light photographic setup: a crisp white key light, strong purple fill and rim lights for brand-coloured edge definition, orange dramatic rim and kick lights, low ambient for contrast, and a blurred city environment map for realistic metal reflections. The rim "breathes" purple at idle and pulses orange on hover.

4. Tactile interaction

The tyre is a physical object you can play with: grab-and-drag to orbit it, with grab / grabbing cursor states for affordance; it spins faster as you scroll and slows when you hover to inspect it; and a point light kicks on under the hover state to make it gleam.

5. Built to adapt

A resize listener switches between two complete animation paths — a desktop sequence with wide horizontal movement and a mobile sequence constrained to a narrow viewport — and scales the model down on mobile. Device pixel ratio is capped at [1, 2] to protect performance on high-DPI screens.

6. A procedural fallback tyre

The project ships with a complete code path that builds a tyre entirely from primitives — cylinders and tori for the carcass, instanced meshes for 40 tread blocks and shoulder lugs, and curved 3D text spelling "APTERRA AT2" / "APOLLO" / "245/70 R16" wrapped around the sidewall. A single USE_CUSTOM_MODEL flag swaps between this generated geometry and the loaded .glb model.

Technology

Layer Choice Why
Framework React 19 + TypeScript Component model + type safety for a complex animated scene
Build Vite 6 Instant HMR, fast 3D-asset iteration
3D core Three.js Industry-standard WebGL engine
3D React layer @react-three/fiber Declarative Three.js as React components
3D helpers @react-three/drei ScrollControls, Environment, ContactShadows, useGLTF, Text
Styling Tailwind CSS Single-file design tokens shared with the 3D layer
Icons lucide-react Consistent, lightweight iconography
Fonts Orbitron + Rajdhani Technical, engineered typographic voice
Asset tyre.glb Custom GLTF product model

Highlights

Unified Design System

A single source-of-truth token set drives both the DOM and WebGL, eliminating the usual visual seam between 3D and HTML.

Velocity-Aware Camera

Scroll speed — not just position — shapes the cinematography, adding momentum to every movement.

Dual Responsive Choreography

Separate keyframe timelines and model scale for desktop and mobile, not just CSS breakpoints.

Resilient Geometry

A procedural fallback means the experience can render a full tyre even without the binary model asset.

Outcome

The result transforms a commodity product page into a premium, explorable showcase where the tyre is the hero and the brand's colour and lighting language carries consistently from the first pixel of HTML into the depths of the 3D scene. It demonstrates that real-time WebGL and conventional web content can be fused into one coherent, performant, responsive experience.