ΛNKIT.
Computer Graphics Oct 2026 • 12 min Read

Interactive Web Experiences: Getting Started with Three.js & Canvas Particles

By The Ankit Goswami • Verified Engineering Guide

The modern web is evolving rapidly from static, text-heavy 2D documents into kinetic, immersive 3D digital experiences. When a visitor lands on theankit.co.in, they aren't just greeted by flat text; they step into a responsive digital space with an interactive particle mesh, subtle depth parallax, and magnetic mouse tracking.

Building these experiences requires a strong grasp of mathematics (vectors, linear interpolation) paired with WebGL and libraries like Three.js. In this tutorial, we explore the core building blocks required to craft high-performance 3D canvas environments that captivate audiences without crashing their mobile browsers.

1. The Core Three.js Triad: Scene, Camera, and Renderer

Every Three.js application begins with three fundamental components:

  1. The Scene: The virtual universe container holding all 3D geometries, materials, particles, and lighting sources.
  2. The Camera: The perspective lens through which the virtual scene is observed. The PerspectiveCamera simulates real-world optical characteristics, featuring a Field of View (FOV), Aspect Ratio, Near Clipping Plane, and Far Clipping Plane.
  3. The WebGLRenderer: The graphics engine that calculates matrix projections and outputs pixels onto an HTML5 <canvas> element.
import * as THREE from 'three';

// 1. Initialize Scene
const scene = new THREE.Scene();

// 2. Setup Perspective Camera (75 deg FOV)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 3. Setup WebGL Renderer with Alpha (Transparency)
const renderer = new THREE.WebGLRenderer({
    canvas: document.getElementById('threeCanvas'),
    alpha: true,
    antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

2. Creating Lightweight Particle Geometries with `BufferGeometry`

In older versions of Three.js, developers created individual THREE.Mesh objects for every particle. Rendering 2,000 separate meshes flooded the GPU with 2,000 separate draw calls per frame, crippling rendering speed.

The modern, highly optimized technique is to store thousands of particle coordinates in a single contiguous memory block using THREE.BufferGeometry and render them via THREE.Points:

const particleCount = 1500;
const positions = new Float32Array(particleCount * 3);

// Generate random 3D coordinates
for (let i = 0; i < particleCount * 3; i += 3) {
    positions[i] = (Math.random() - 0.5) * 15;     // X coordinate
    positions[i + 1] = (Math.random() - 0.5) * 15; // Y coordinate
    positions[i + 2] = (Math.random() - 0.5) * 15; // Z coordinate
}

const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

// Custom Point Material with Additive Blending
const material = new THREE.PointsMaterial({
    size: 0.03,
    color: 0x00f2fe, // Neon cyan accent
    transparent: true,
    opacity: 0.8,
    blending: THREE.AdditiveBlending
});

const particleSystem = new THREE.Points(geometry, material);
scene.add(particleSystem);

Using THREE.Points, the GPU processes all 1,500 particles in a single draw call, consuming virtually 0% CPU overhead!

3. Organic Movement with Linear Interpolation (`lerp`)

To make 3D backgrounds feel alive, they must react to user cursor input. However, directly snapping camera rotation to mouse coordinates creates harsh, jittery movement. Instead, use Linear Interpolation (lerp) to smoothly glide between current and target positions:

let mouseX = 0, mouseY = 0;
let targetX = 0, targetY = 0;

window.addEventListener('mousemove', (e) => {
    // Normalize coordinates from -1 to 1
    targetX = (e.clientX / window.innerWidth) * 2 - 1;
    targetY = -(e.clientY / window.innerHeight) * 2 + 1;
}, { passive: true });

function animate() {
    requestAnimationFrame(animate);
    
    // Smooth Lerp: 5% movement towards target per frame
    mouseX += (targetX - mouseX) * 0.05;
    mouseY += (targetY - mouseY) * 0.05;
    
    // Rotate particle system gently with mouse
    particleSystem.rotation.y = mouseX * 0.4;
    particleSystem.rotation.x = -mouseY * 0.4;
    
    renderer.render(scene, camera);
}
animate();

4. Essential Performance Safeguards for Production

When deploying 3D web applications to production, implement these safeguards:

Conclusion

Three.js and WebGL allow developers to transform the web browser into an interactive canvas of limitless possibilities. By prioritizing single-draw-call buffer geometries, mathematical interpolation, and memory stewardship, you can build mesmerizing 3D digital experiences that wow audiences across every device.

The Ankit Goswami
AUTHOR & CREATIVE DIRECTOR

The Ankit Goswami

Ankit is a cinematic video director, visual storyteller, and full-stack software engineer. Founder of ΛNKIT PRODUCTIONS, he specializes in high-fidelity GPU web experiences and cinematic smartphone filmmaking.

Back to All Articles