class CubeWarp { constructor() { this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); this.cubes = []; this.mouseX = 0; this.mouseY = 0; this.targetX = 0; this.targetY = 0; this.init(); this.animate(); } init() { // Setup renderer this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setClearColor(0x000000, 0); document.getElementById('container').appendChild(this.renderer.domElement); // Create multiple cubes with different colors and positions const colors = [ 0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xffeaa7, 0xdda0dd, 0x98d8c8, 0xf7dc6f, 0xbb8fce ]; for (let i = 0; i < 15; i++) { const geometry = new THREE.BoxGeometry(2, 2, 2); const material = new THREE.MeshPhongMaterial({ color: colors[i % colors.length], transparent: true, opacity: 0.8, shininess: 100 }); const cube = new THREE.Mesh(geometry, material); // Position cubes in a spherical arrangement const radius = 8 + Math.random() * 4; const theta = Math.random() * Math.PI * 2; const phi = Math.acos((Math.random() * 2) - 1); cube.position.x = radius * Math.sin(phi) * Math.cos(theta); cube.position.y = radius * Math.sin(phi) * Math.sin(theta); cube.position.z = radius * Math.cos(phi); cube.userData = { originalPosition: cube.position.clone(), speed: 0.5 + Math.random() * 1.5, rotationSpeed: { x: (Math.random() - 0.5) * 0.02, y: (Math.random() - 0.5) * 0.02, z: (Math.random() - 0.5) * 0.02 }, warpFactor: 0 }; this.scene.add(cube); this.cubes.push(cube); } // Add lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); this.scene.add(ambientLight); const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(5, 5, 5); this.scene.add(directionalLight); const pointLight = new THREE.PointLight(0x4ecdc4, 1, 100); pointLight.position.set(-5, -5, -5); this.scene.add(pointLight); // Position camera this.camera.position.z = 15; // Mouse move event document.addEventListener('mousemove', (event) => { this.mouseX = (event.clientX / window.innerWidth) * 2 - 1; this.mouseY = -(event.clientY / window.innerHeight) * 2 + 1; }); // Window resize window.addEventListener('resize', () => { this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); this.renderer.setSize(window.innerWidth, window.innerHeight); }); } animate() { requestAnimationFrame(() => this.animate()); // Smooth mouse movement this.targetX += (this.mouseX - this.targetX) * 0.05; this.targetY += (this.mouseY - this.targetY) * 0.05; // Update cubes this.cubes.forEach((cube, index) => { const data = cube.userData; // Calculate warp effect based on mouse position and cube distance const distanceToCenter = cube.position.length(); const mouseDistance = Math.sqrt(this.targetX * this.targetX + this.targetY * this.targetY); // Warp factor increases with mouse movement and proximity data.warpFactor = Math.min(1, mouseDistance * 2 + (1 - distanceToCenter / 20)); // Rotation cube.rotation.x += data.rotationSpeed.x * (1 + data.warpFactor * 2); cube.rotation.y += data.rotationSpeed.y * (1 + data.warpFactor * 2); cube.rotation.z += data.rotationSpeed.z * (1 + data.warpFactor * 2); // Position warping - cubes move towards each other and distort const time = Date.now() * 0.001; const warpX = Math.sin(time + index) * data.warpFactor * 3; const warpY = Math.cos(time + index * 0.7) * data.warpFactor * 3; const warpZ = Math.sin(time * 0.5 + index * 0.3) * data.warpFactor * 3; cube.position.x = data.originalPosition.x + warpX + this.targetX * 2; cube.position.y = data.originalPosition.y + warpY + this.targetY * 2; cube.position.z = data.originalPosition.z + warpZ; // Scale warping const scale = 1 + data.warpFactor * 0.5; cube.scale.set(scale, scale, scale); // Color intensity based on warp factor cube.material.color.setHSL( (index * 0.1 + time * 0.1) % 1, 0.8, 0.6 + data.warpFactor * 0.4 ); // Opacity pulsing cube.material.opacity = 0.6 + Math.sin(time * 2 + index) * 0.2; }); this.renderer.render(this.scene, this.camera); } } // Initialize when page loads window.addEventListener('load', () => { new CubeWarp(); });