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(() => {
 ...