File size: 5,611 Bytes
1a62613 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 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();
}); |