Creating a 360° Image Viewer with Three.js The Easy Way
Table of Content
Three.js is a fantastic JavaScript library that makes adding 3D graphics to your web projects a breeze. By leveraging WebGL, it allows developers to create interactive 3D environments with smooth animations, realistic lighting, and dynamic textures—all directly in the browser.
If you’ve ever wanted to build a 3D experience for your website or app, Three.js is a go-to tool that opens up endless possibilities.
In this tutorial, we’ll guide you through building a 360° image viewer using Three.js. You'll learn how to integrate a seamless 360° image experience and add a handy sidebar with instructions for users to interact with the viewer.
Plus, we'll set everything up using Vite, a modern and fast development tool that ensures a smooth and efficient setup. This project is perfect for developers looking to bring immersive content to their web applications with minimal hassle. Let’s get started!
Prerequisites
Before we start, make sure you have the following installed:
- Node.js (v16 or higher)
- A code editor (e.g., Visual Studio Code)
Step 1: Set Up the Project with Vite
Start the development server:
Run the following command to start the Vite development server:
npm run dev
Your project will be available at http://localhost:5173
.
Install Three.js:
Install Three.js as a dependency:
npm install three
Create a new project:
Open your terminal and run the following commands:
npm create vite@latest 360-image-viewer
cd 360-image-viewer
npm install
When prompted, select Vanilla as the framework and JavaScript as the variant.
Step 2: Prepare the 360° Image
For this tutorial, you'll need a 360° equirectangular image. You can find free images online or use your own.
Place the image in the public
folder of your project. For example, save it as public/360-image.jpg
.
Step 3: Create the 360° Image Viewer
Create the Three.js scene:
Replace the content of main.js
with the following:
import * as THREE from 'three';
// Scene, Camera, Renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Create a sphere and add the 360° image as a texture
const geometry = new THREE.SphereGeometry(500, 60, 40);
// This is an important step :D
geometry.scale(-1, 1, 1); // Invert the sphere to render the image inside
// Now we will load the image as a sphere Texture (Cool huh?)
const texture = new THREE.TextureLoader().load('/360-image.jpg');
const material = new THREE.MeshBasicMaterial({ map: texture });
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
// Position the camera
camera.position.set(0, 0, 0.1);
// Add controls to look around
let isDragging = false;
let previousMousePosition = { x: 0, y: 0 };
document.addEventListener('mousedown', () => (isDragging = true));
document.addEventListener('mouseup', () => (isDragging = false));
document.addEventListener('mousemove', (event) => {
if (isDragging) {
const deltaX = event.clientX - previousMousePosition.x;
const deltaY = event.clientY - previousMousePosition.y;
sphere.rotation.y += deltaX * 0.005;
sphere.rotation.x += deltaY * 0.005;
}
previousMousePosition = { x: event.clientX, y: event.clientY };
});
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// Animation loop
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
Update index.html
:
Replace the content of index.html
with the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>360° Image Viewer</title>
<style>
body { margin: 0; overflow: hidden; }
#sidebar {
position: absolute;
top: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
font-family: Arial, sans-serif;
z-index: 1;
}
</style>
</head>
<body>
<div id="sidebar">
<h2>How to View</h2>
<ul>
<li>Drag to look around.</li>
<li>Use arrow keys to navigate.</li>
</ul>
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
Step 4: Run the Project
- Open your browser and navigate to
http://localhost:5173
. You should see the 360° image rendered inside a sphere. You can drag to look around or use the arrow keys to navigate.
Start the development server if it's not already running:
npm run dev
Step 5: Customize the Sidebar
The sidebar provides instructions on how to interact with the viewer. You can customize the content or style of the sidebar by editing the #sidebar
section in the index.html
file.
Conclusion
Congratulations! You've created a 360° image viewer using Three.js and Vite. This project can be extended by adding more interactivity, such as zooming, hotspots, or even integrating it into a larger application.
Three.js is a powerful tool for creating immersive 3D experiences on the web, and this tutorial is just the beginning of what you can achieve.
Resources
Happy coding! 🚀