import * as THREE from 'three'; /** * Initialise the Three.js wireframe background scene. * @param canvas – the `` element to render into. */ export function initBackground(canvas: HTMLCanvasElement): void { const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true }); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.setSize(window.innerWidth, window.innerHeight); const scene = new THREE.Scene(); const aspect = window.innerWidth / window.innerHeight; const camera = new THREE.PerspectiveCamera(60, aspect, 0.1, 200); camera.position.set(0, 0, 10); camera.lookAt(new THREE.Vector3(0, 0, 0)); // Wireframe sphere at exact origin const geo = new THREE.SphereGeometry(3.5, 32, 32); const mat = new THREE.MeshBasicMaterial({ color: 0x00ffe7, wireframe: true, opacity: 0.28, transparent: true, }); const mesh = new THREE.Mesh(geo, mat); mesh.position.set(0, 0, 0); scene.add(mesh); // Grid floor const grid = new THREE.GridHelper(30, 30, 0xff2d78, 0xff2d78); grid.material.opacity = 0.1; grid.material.transparent = true; grid.position.y = -3.2; scene.add(grid); // Handle resize window.addEventListener('resize', () => { const w = window.innerWidth; const h = window.innerHeight; renderer.setSize(w, h); camera.aspect = w / h; camera.updateProjectionMatrix(); }); const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; (function animate() { requestAnimationFrame(animate); if (!reduced) { mesh.rotation.y += 0.003; mesh.rotation.z += 0.004; grid.rotation.y += 0.0008; } renderer.render(scene, camera); })(); }