// When creating the camera const storedCamera = JSON.parse(localStorage.getItem('camera')); if (storedCamera) { camera.position.set( storedCamera.position.x, storedCamera.position.y, storedCamera.position.z, ); controls.target.set( storedCamera.target.x, storedCamera.target.y, storedCamera.target.z, ); } else { camera.position.set(4, 2, 5); // Default starting position } // When the camera changes with a Three.js controller controls.addEventListener( 'change', // debounce is here to prevent saving to local storage every frame // when the controls have damping debounce( () => localStorage.setItem('camera', JSON.stringify({ position: { x: camera.position.x, y: camera.position.y, z: camera.position.z, }, target: { x: controls.target.x, y: controls.target.y, z: controls.target.z, }, })), ), ); // this default timeout works fine with the default values of the three.js Orbit controls function debounce(func, timeout = 120) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; }