Frontend Development 13 min read

A Simplified Front‑End Multi‑Window 3D Scene Using three.js and localStorage

This article explains how a pure‑frontend implementation using three.js and localStorage creates a synchronized 3D scene across multiple browser windows, detailing the project structure, core code files, and the window‑management logic that enables cross‑window coordination without a back‑end.

IT Services Circle
IT Services Circle
IT Services Circle
A Simplified Front‑End Multi‑Window 3D Scene Using three.js and localStorage

Recently a video showing a pure‑frontend "quantum entanglement" effect went viral; the author open‑sourced a simplified version built with three.js and localStorage that creates a 3D scene shared across multiple browser windows. The project consists of three main files: index.html , main.js and WindowManager.js . The HTML loads the three.js library and the main module, while the JavaScript sets up an orthographic camera, scene, renderer and a window manager that stores each window’s shape in localStorage. <!DOCTYPE html> 3d example using three.js and multiple windows The main.js script imports the window manager, defines global variables, initializes the scene, creates a cube for each window, updates positions based on window coordinates, and runs a render loop with requestAnimationFrame . It also handles visibility changes, resizing, and synchronises window data through the manager. import WindowManager from './WindowManager.js' const t = THREE; let camera, scene, renderer, world; let near, far; let pixR = window.devicePixelRatio ? window.devicePixelRatio : 1; let cubes = []; let sceneOffsetTarget = {x:0, y:0}; let sceneOffset = {x:0, y:0}; let today = new Date(); today.setHours(0,0,0,0); today = today.getTime(); let internalTime = getTime(); let windowManager; let initialized = false; function getTime(){ return (new Date()).getTime() - today / 1000.0; } if (new URLSearchParams(window.location.search).get("clear")) { localStorage.clear(); } else { document.addEventListener("visibilitychange", () => { if (document.visibilityState != 'hidden' && !initialized) { init(); } }); window.onload = () => { if (document.visibilityState != 'hidden') { init(); } }; } function init(){ initialized = true; setTimeout(() => { setupScene(); setupWindowManager(); resize(); updateWindowShape(false); render(); window.addEventListener('resize', resize); }, 500); } function setupScene(){ camera = new t.OrthographicCamera(0, window.innerWidth, 0, window.innerHeight, -10000, 10000); camera.position.z = 2.5; near = camera.position.z - .5; far = camera.position.z + .5; scene = new t.Scene(); scene.background = new t.Color(0.0); scene.add(camera); renderer = new t.WebGLRenderer({antialias:true, depthBuffer:true}); renderer.setPixelRatio(pixR); world = new t.Object3D(); scene.add(world); renderer.domElement.setAttribute("id","scene"); document.body.appendChild(renderer.domElement); } function setupWindowManager(){ windowManager = new WindowManager(); windowManager.setWinShapeChangeCallback(updateWindowShape); windowManager.setWinChangeCallback(windowsUpdated); const metaData = {foo:"bar"}; windowManager.init(metaData); windowsUpdated(); } function windowsUpdated(){ updateNumberOfCubes(); } function updateNumberOfCubes(){ const wins = windowManager.getWindows(); cubes.forEach(c => world.remove(c)); cubes = []; for(let i=0;i The core WindowManager class tracks all windows, assigns unique IDs, listens for the storage event to detect changes from other tabs, and provides callbacks for shape changes and window list updates. It stores the window list in localStorage so that every tab can read the same state. class WindowManager { #windows; #count; #id; #winData; #winShapeChangeCallback; #winChangeCallback; constructor(){ addEventListener("storage", (event) => { if(event.key == "windows"){ const newWindows = JSON.parse(event.newValue); const winChange = this.#didWindowsChange(this.#windows, newWindows); this.#windows = newWindows; if(winChange && this.#winChangeCallback) this.#winChangeCallback(); } }); window.addEventListener('beforeunload', (e) => { const index = this.getWindowIndexFromId(this.#id); this.#windows.splice(index,1); this.updateWindowsLocalStorage(); }); } #didWindowsChange(pWins, nWins){ if(pWins.length != nWins.length) return true; for(let i=0;i By opening the project with a local server (e.g., Live Server) you can see multiple cubes moving in sync across different browser windows, demonstrating how pure front‑end code can achieve cross‑window coordination without a back‑end.

frontendJavaScriptThree.js3DlocalStoragewindow management
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.