跪拜 Guibai
← All articles
Three.js · Vue.js

A Production-Ready 3D Car Showroom with Vue and Three.js

By Tony费 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Most Three.js examples skip resource cleanup, which causes memory leaks and GPU memory bloat in SPAs with frequent route changes. This implementation shows the full lifecycle — from model load to complete disposal — that a production Vue app actually needs.

Summary

A full 3D car showroom implementation pairs Vue with Three.js to deliver a commercial-grade interactive experience. The setup loads a GLTF model with built-in skeletal animations and wraps it in a minimalist showroom environment with a semi-transparent grid floor, layered lighting, and fog.

Two camera positions are available: an external orbit view with damping and disabled panning, and a driver's-seat first-person perspective. Switching between them uses TWEEN for a 1.5-second smooth transition rather than an abrupt jump. Door open/close animations are driven by the model's own animation clips, managed through an AnimationMixer and synchronized across devices via a clock delta.

The component's `leaveDestory` method traverses the scene to dispose of every geometry and material, cancels all animation frames, stops TWEEN and skeletal animations, and destroys the renderer, camera, and controls. This prevents the memory leaks that plague many Three.js demos when routes change repeatedly.

Takeaways
GLTF models can carry their own animation clips, which an AnimationMixer reads and controls without external keyframe data.
Disabling OrbitControls panning and enabling damping creates a showroom-appropriate interaction that feels smoother than default settings.
TWEEN-based camera transitions prevent the visual jump that occurs when directly setting camera coordinates for interior/exterior view switches.
Using `clock.getDelta()` inside the render loop keeps animation playback speed consistent across devices with different frame rates.
A thorough `leaveDestory` method must traverse the scene to dispose of geometries and materials, cancel all requestAnimationFrame IDs, stop TWEEN instances, and nullify renderer, camera, and controls references.
Conclusions

The code stores scene objects on `window` to survive hot module reloads and Vue's reactivity system, a pragmatic but leak-prone pattern that makes the explicit cleanup even more critical.

Binding button visibility to boolean flags like `isLoad` and `isAnimation` keeps the UI logic simple, but the state management is entirely local — a multi-component 3D app would need a shared store to avoid prop drilling.

The lighting setup uses a HemisphereLight for ambient fill and a single SpotLight for shadows, which is enough for a showroom but would need area lights or an environment map for reflective car paint to look realistic.

Concepts & terms
AnimationMixer
A Three.js object that plays and controls animation clips stored in a 3D model (like a GLTF file). It manages playback, stopping, and crossfading of skeletal or morph-target animations.
OrbitControls
A Three.js add-on that lets users rotate, zoom, and pan a camera around a target point using mouse or touch input. Panning and damping can be toggled independently.
TWEEN
A JavaScript tweening library that interpolates values over time. Used here to smoothly animate the camera position and controls target between exterior and interior viewpoints.
GLTF
A royalty-free specification for efficient transmission and loading of 3D scenes and models. It supports embedded animations, textures, and binary data, making it the preferred format for web-based 3D.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗