Three.js: Building an Interactive 2.5D Web Environment
The core of this setup is a 2.5D scene where the avatar isn't just a looping animation—it's an entity with its own state machine. I've mapped specific CTA hover events to trigger movement vectors, so when a user interacts with a button, the character physically moves toward an object (like a chest) within the scene.
To make the environment feel organic, I implemented several game-dev mechanics:
- Autonomous Logic: Random movement patterns when idle.
- Collision Detection: Simple bounding boxes to keep the avatar within the environment.
- Dynamic States: A day/night cycle and weather system that changes based on real-world time.
Performance and Optimization
The biggest risk with Three.js is tanking your Lighthouse scores. To keep the site responsive and maintain strong Core Web Vitals, I focused on optimizing the render loop and asset sizes. Despite adding real-time rendering and autonomous behaviors, the performance hit was negligible, and the experience remains fully responsive on mobile.
Technical Implementation Path
If you're looking to build something similar, here is a high-level look at the AI workflow I used to iterate on the logic:
1. Scene Setup: Define the 3D coordinate system but constrain movement to a 2D plane to achieve that 2.5D retro aesthetic.
2. Input Mapping:
// Conceptual logic for linking DOM events to 3D movement
button.addEventListener('mouseenter', () => {
avatar.setDestination(targetObject.position);
avatar.setState('INTERACTING');
});3. State Management: Use a simple state machine to handle transitions between IDLE, WANDERING, and REACTING.This approach transforms a landing page from a static brochure into a memorable digital space. The next step is expanding the environmental triggers so the avatar's behavior changes entirely based on the time of day—sitting by a campfire at night or idling during the day.
For those interested in the result, the live deployment is here:https://matteosantoro.dev/en