Cubes
by Grzegorz Matyszewski
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.9/dat.gui.min.js"></script>
<canvas class="webgl"></canvas>
SCSS
body {
background: black;
margin: 0;
padding: 0;
overflow: hidden;
&::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 1) 100%);
z-index: 1;
}
}
TypeScript
const options = {
amount: 200,
speed: 0.01,
bitrate: 0.696,
};
// Scene
const scene = new THREE.Scene();
const wrap = new THREE.Group();
scene.add(wrap);
// Objects
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial();
const cubes = [];
for (let i = 0; i < options.amount; i++) {
const mesh = new THREE.Mesh(geometry, material);
mesh.position.x = (-1 + Math.random() * 2) * 4;
mesh.position.y = (-1 + Math.random() * 2) * 4;
mesh.position.z = Math.random() * -4;
mesh.userData.speedX = -1 + Math.random() * 2;
mesh.userData.speedY = -1 + Math.random() * 2;
mesh.userData.speedZ = -1 + Math.random() * 2;
mesh.userData.scale = 0.7 + Math.random() * 0.7;
wrap.add(mesh);
cubes.push(mesh);
}
// Camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight);
camera.position.z = 3;
scene.add(camera);
// Renderer
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('canvas.webgl'),
});
renderer.setSize(window.innerWidth, window.innerHeight);
// Lights
const light = new THREE.PointLight(0xff4000, 1, 7, 2);
light.position.set(1, -1, 1);
scene.add(light);
let lightDirection = -1;
const light2 = new THREE.PointLight(0x0090ff, 1, 7, 2);
light2.position.set(1, 1, 1);
scene.add(light2);
let light2Direction = 1;
// Animation loop
const loop = (t) => {
cubes.forEach(mesh => {
mesh.rotation.x += mesh.userData.speedX * options.speed;
mesh.rotation.y += mesh.userData.speedY * options.speed;
mesh.rotation.z += mesh.userData.speedZ * options.speed;
});
light.position.x += 0.009 * lightDirection;
if (light.position.x > 2 || light.position.x < -2) {
lightDirection *= -1;
}
light2.position.x += 0.011 * light2Direction;
if (light2.position.x > 2 || light2.position.x < -2) {
light2Direction *= -1;
}
renderer.render(scene, camera);
requestAnimationFrame(loop);
}
loop();
// Animations
window.setInterval(() => {
...