An immersive portfolio experience that combines traditional website navigation with first-person 3D exploration.
- Website Mode: Traditional scrollable portfolio interface
- FPS Mode: First-person navigation using WASD + mouse controls
- Interactive Objects: Click or press 'E' to view project details
- Smooth Transitions: GSAP-powered animations between modes
- State Management: Zustand for clean state handling
- React 18 + TypeScript
- Vite - Build tool
- Three.js - 3D rendering
- React Three Fiber - React renderer for Three.js
- React Three Drei - Useful helpers for R3F
- GSAP - Animation library
- Zustand - State management
Start the dev server:
npm run devOpen http://localhost:5173 in your browser.
npm run build- Scroll through the portfolio content
- Click "Enter My Room" button to switch to 3D mode
- WASD or Arrow Keys: Move around
- Mouse: Look around
- Left Click or E Key: Interact with objects when looking at them
- ESC: Exit to website mode
- In FPS mode, look at a colored cube or click on it
- The object will highlight when you hover over it
- Press E or Left Click to view project details
- Click "Back to Room" or press ESC to return
src/
├── components/
│ ├── Scene.tsx # R3F Canvas setup
│ ├── WebsiteOverlay.tsx # Scrollable website content
│ ├── ObjectViewer.tsx # Modal for viewing projects
│ └── Crosshair.tsx # FPS crosshair
├── experience/
│ ├── Room.tsx # 3D room environment
│ ├── Controls.tsx # FPS controls
│ └── InteractiveObject.tsx # Clickable 3D objects
├── store/
│ └── useStore.ts # Zustand state management
└── App.tsx # Main app component
Edit src/experience/Room.tsx:
<InteractiveObject
position={[x, y, z]}
color="#yourcolor"
objectData={{
id: "unique-id",
title: "Project Title",
content: "Project description...",
}}
/>- Place
.glbor.gltffiles inpublic/models/ - Use
useGLTFfrom@react-three/drei:
import { useGLTF } from "@react-three/drei";
function MyModel() {
const { scene } = useGLTF("/models/your-model.glb");
return <primitive object={scene} />;
}