🚧 Work in progress — content may change! ðŸš§

Car Dashboard

v2.0 March 2026
Simulation Study

0

km/h

0 rpm

F
C
Off
0
0
0
0
0
0
km

Motivation

Car dashboards are one of the most information-dense UIs in everyday life — speed, RPM, fuel, temperature, gear, warnings, and more, all readable at a glance while driving. I wanted to recreate that experience in the browser: not just the visual design, but the underlying physics that make the gauges feel alive. The first version was simple — a gasoline engine, one transmission mode, basic gauges. That was enough to get hooked.

v2.0 grew out of curiosity about the gaps. What would it take to simulate a diesel or electric drivetrain? How does procedural engine sound actually work? Can the Gamepad API turn a real controller into a gas pedal? Each question became a feature, and the project kept expanding until it felt like a proper simulation sandbox.

Tools and technologies

Astro React Motion TailwindCSS TypeScript GitHub Copilot Claude Web Audio API Gamepad API

Building blocks

The dashboard is assembled from small, focused components — gauges, indicators, the on-board computer, physics simulation, engine audio, and gamepad input. Each building block is documented and shown in isolation on a dedicated page.

Components & Primitives Gauges, gear selector, on-board computer, and more

Acceleration test stand

The physics simulation is not just for visuals — it produces measurable numbers. This test stand creates a fresh car instance with the parameters below, cranks the engine, puts the transmission in Sport mode, and applies full throttle until the car reaches its drag-limited top speed. The 0–100 and 0–200 km/h times are recorded with linear interpolation between frames for sub-timestep accuracy.

Drag the sliders to change engine power, vehicle weight, or the rev limit. The benchmark re-runs instantly because the entire simulation is deterministic and completes in under a millisecond.

Power200 HP
Weight1500 kg
Max RPM6000 rpm
Efficiency73 %
0–100 km/h7.1s
0–200 km/h28.6s
Top Speed244km/h
Power / Weight133HP/ton

Engine sound

The dashboard generates engine audio entirely in the browser — no recorded samples, just maths. A procedural synthesiser built on the Web Audio API constructs a real-time audio graph that responds to RPM, throttle position, and cylinder count every animation frame.

The core idea is the firing frequency of a four-stroke engine: f = RPM × cylinders / 120. Three oscillators are tuned to this frequency and its 2nd and 3rd harmonics — a sawtooth for the fundamental growl, another sawtooth an octave up, and a square wave two octaves up for bite. An LFO modulates their combined amplitude at half the firing rate to recreate the rhythmic combustion "chug" you hear at idle.

On top of the tonal layer sits an exhaust noise channel: a looped white-noise buffer routed through a bandpass filter whose centre frequency rises with RPM. A master lowpass filter opens from 500 Hz at idle to 3 500 Hz at redline — plus an extra 800 Hz boost from throttle — so the sound brightens as the engine revs. Finally, a waveshaper adds soft-clip distortion that deepens with throttle, giving full-throttle pulls a grittier edge.

Every parameter transition uses setTargetAtTime with a 40 ms time constant, so there are no clicks or pops even though values change 60 times per second. The AudioContext is lazily created on the first frame where the engine is running — this satisfies the browser autoplay policy because the simulation loop is kicked off by clicking "Start Engine." Unmute the dashboard above to hear it.

Engine type
Cylinders
RPM800 rpm
Throttle0 %
Firing frequency26.7Hz

Gamepad support

The dashboard accepts input from a standard gamepad alongside the keyboard — both work simultaneously. The implementation uses the browser-native Gamepad API (navigator.getGamepads()) with a polling model: every animation frame the simulation reads the current gamepad state instead of relying on events.

Analog triggers provide proportional throttle and brake — a light squeeze gives partial input, unlike the binary on/off of a keyboard press. A dead-zone of 0.08 filters out drift from resting triggers. For one-shot actions (cycle drive mode, toggle engine) edge detection compares the current button state against the previous frame so the action fires exactly once per press.

Input from both sources is merged with Math.max(keyboard, gamepad), so whichever device provides the larger value wins. This means you can drive with the gamepad and tap the keyboard at any time without conflict. A green "Gamepad" indicator appears in the controls bar when a controller is connected. Click the controls icon next to the sound toggle to see the full control mapping.

Learnings

The simulation core was the most educational part. Modelling a powertrain as a chain of objects — engine, ECU, transmission, wheels — made the physics natural to reason about and easy to test. Unit tests for gear-shift logic and fuel consumption caught subtle edge cases early and gave confidence when refactoring the entire class hierarchy for v2.0.

Procedural audio via the Web Audio API turned out to be surprisingly approachable. The main challenge was managing the AudioContext lifecycle across React renders: contexts must be created on user interaction, suspended when the tab is hidden, and cleaned up properly to avoid memory leaks. Getting the engine note to track RPM smoothly required tuning oscillator frequencies and low-pass filter cutoffs by ear.

The Gamepad API uses a polling model rather than events, which meant integrating it into the existing animation loop rather than adding separate listeners. Handling analog trigger dead zones, normalising axis values, and merging keyboard and gamepad input without conflict took a few iterations to get right.

References and inspiration

Timeline

  1. v1

    v1.0 — Initial Release

    19 May 2025

    First working dashboard with gauges and a physics simulation.

    • Core gauges — Speedometer Tachometer Circular Gauge Linear Gauge Fuel Level
    • Physics simulation — Car, Chassis, Engine, Fuel Tank, Transmission, and Wheels
    • Manual gear-shift logic with transmission utils and unit tests
    • Full dashboard layout and Storybook stories for all gauge components
  2. v2

    v2.0

    Current

    March 2026

    Complete rewrite — new engine, new UI, new features.

    • Multiple powertrain types — Gasoline Diesel Electric with separate engine and car classes
    • Automatic and Manual transmission models with realistic gear-shift logic and ECU
    • Procedural engine audio via Web Audio API — separate synthesisers for gasoline, diesel, and electric
    • Gamepad API support with analog throttle/brake triggers and edge-detected button actions
    • On-board computer with Trip, Vehicle, and Consumption pages
    • Configurable acceleration test stand — instant 0–100 and 0–200 km/h benchmarks
    • Dedicated component library page, Gear Selector, Start/Stop button, mobile layout
  3. v3

    Future

    Planned
    • Hybrid powertrain simulation
    • Regenerative braking simulation
    • Advanced manual transmission simulation
    • More gauges
    • Advanced trip computer
    • Connect dashboard to a car — simple driving game