Inside F1 — Interactive 3D F1 Experience
Interactive educational experience exploring Formula 1 with a 3D Ferrari F1-75 model (React Three Fiber + Three.js, Draco-compressed GLB ~2 MB). 18 clickable car parts with GSAP camera zoom and info panels.
Role
Full-stack Developer
Team
Solo
Company/Organization
Personal Project
The Problem
Formula 1 engineering is deeply technical — understanding aerodynamics, DRS mechanics, and how 1000+ car components work together is inaccessible...
No interactive 3D tool existed to explore an F1 car part-by-part — fans couldn't click individual components (front wing, diffuser, power unit) to...
Aerodynamic principles (downforce, drag reduction, airflow management) are abstract without visualization — static diagrams fail to convey how air...
F1 data (driver standings, constructor rankings, circuit information) is scattered across multiple websites — no single experience combined car...
Existing F1 educational content was passive (videos, articles) — no interactive, self-paced learning experience with chapters covering car...
The Solution
Built a fully interactive 3D educational platform combining WebGL car exploration, physics visualizations, and live F1 data.
3D Car Explorer (React Three Fiber + Three.js)
F1Car.tsx — Loads Ferrari F1-75 GLB model (Draco-compressed to ~2 MB) with useGLTF hook. Custom material setup for metallic paint, carbon fiber...
Scene.tsx — Three.js canvas with performance monitoring, shadow configuration, and adaptive device pixel ratio. Manages 3D rendering pipeline.
PartsListSidebar.tsx — Left sidebar listing 18 car parts (external: front wing, rear wing, sidepods, floor, diffuser, bargeboards, halo, nose,...
InfoPanel.tsx — Right-side sliding panel displaying part name, category, description, technical specifications, and engineering role. Animates...
CameraRig.tsx — GSAP-powered camera animations. When user clicks a part, camera smoothly transitions from current position to optimal viewing...
Physics Visualizations
Exploded View — Animated component separation using config/explodedView.ts offset definitions per part. Components fly outward from center to...
Airflow Visualization — Particle streamlines rendered as animated points following aerodynamic flow paths defined in config/airflow.ts. Shows how...
DRS Animation — Rear wing drag reduction system opening/closing animation from config/drs.ts. Flap rotation matches real DRS actuation angle...
Educational Content
ChapterOverlay.tsx — Top tab navigation between 5 chapters. Each chapter lazy-loaded from components/chapters/ to minimize initial bundle size.
Guided Chapters — What is F1 (sport overview, history, regulations), The F1 Car (engineering breakdown, aerodynamics, power unit), Drivers...
IntroSequence.tsx — Cinematic intro with GSAP timeline: camera flies around car while key facts appear with staggered animations.
Live Data Integration
services/f1Api.ts — Ergast + OpenF1 API client with response caching (in-memory Map with TTL), retry logic (3 attempts with exponential backoff),...
Driver/Constructor Standings — Season selector (2000–present), tabular display with position, name, team, points.
F1 Circuits — 24 track layouts from data/ directory. Each circuit has SVG path for track shape, country flag, location, lap record, circuit...
Audio & Performance
Spatial engine audio via Web Audio API tied to user interactions.
Adaptive DPR for GPU-appropriate rendering, baked shadows, Draco compression (~15 MB → ~2 MB), lazy-loaded chapters (~40% bundle reduction), API...
Design Decisions
React Three Fiber over raw Three.js — declarative React component model for 3D scenes, hooks (useFrame, useGLTF) integrate naturally with React state...
GSAP for camera animations over Three.js Tween — provides eased interpolation with timeline sequencing, enabling cinematic camera movements between...
Draco compression for GLB model — reduced Ferrari F1-75 from ~15 MB to ~2 MB without visible quality loss. Critical for web delivery where initial...
Separated configuration from components — camera positions, airflow settings, DRS config, exploded view offsets, performance settings all in...
Ergast API over building custom F1 data backend — public API with comprehensive historical data (2000–present), no API key required, reduces...
Lazy-loaded chapters over eager loading — chapter content is text-heavy but not needed on initial render. Dynamic imports reduce initial JavaScript...
SVG track layouts over map tiles — crisp vector rendering at any zoom, tiny file size (~2KB per circuit vs megabytes for map tiles), and easy styling...
Web Audio API for engine sound over HTML Audio — spatial positioning, real-time parameter control (pitch, volume based on interaction), and...
Tradeoffs & Constraints
WebGL dependency — 3D visualization requires GPU-capable browser with WebGL2 support. Older mobile devices or browsers without WebGL may experience...
Draco decompression adds ~200ms to initial model load — client-side decompression trades bandwidth savings (~13 MB saved) for CPU time. Acceptable on...
Ergast API has ~24h data delay — standings update after race results are official, not in real-time during events. Acceptable for educational context.
Single car model (Ferrari F1-75) — showcasing one team's car limits comparative education. Adding multiple team models would multiply asset size.
No backend/database — entirely client-side with external API calls. Limits ability to track user progress or save preferences across devices.
Would improve: Add multiple team car models for comparison, implement VR mode (WebXR) for immersive exploration, add real-time race data during Grand...
Outcome & Impact
Complete interactive F1 educational experience combining 3D car exploration, physics visualizations, live competitive data, and guided learning in a...
Ferrari F1-75 3D model with 18 clickable car parts — each triggers smooth GSAP camera animation to optimal viewing angle and opens info panel with...
Three physics visualization modes: Exploded View (animated component separation showing assembly), Airflow (particle streamlines showing aerodynamic...
5 guided chapters (What is F1, The F1 Car, Drivers, Teams, Race Weekend) with lazy-loading reducing initial bundle by ~40%. Cinematic GSAP intro...
Live F1 standings for any season 2000–present via Ergast API with in-memory caching (TTL), retry logic (3 attempts, exponential backoff), and request...
24 F1 circuit layouts rendered as SVG track shapes with country flags, location data, lap records, and circuit specifications.
Performance optimized: Draco-compressed GLB (~2 MB vs ~15 MB raw), adaptive DPR, baked shadows, lazy-loaded chapters, cached API responses.
Docker multi-stage production image for GCP Cloud Run deployment. GitHub Actions CI pipeline (install, lint, build). Makefile with 6 commands.
Tech Stack
Frontend: Next.js 14, TypeScript, Tailwind CSS, Framer Motion
3D: React Three Fiber, Three.js, @react-three/drei (controls, helpers, performance)
Animation: GSAP (camera transitions, intro sequence, exploded view)
3D Model: Ferrari F1-75 GLB with Draco compression (~2 MB)
Data: Ergast F1 API (standings, circuits), OpenF1 API, in-memory cache with TTL
Audio: Web Audio API (spatial engine sound)
Infrastructure: Docker (multi-stage build), GitHub Actions CI, Makefile