Skip to content

Instantly share code, notes, and snippets.

@artemuzz
Created April 21, 2020 00:26
Show Gist options
  • Save artemuzz/ebf2f3152c65dff843a55a7bf1c5fd9a to your computer and use it in GitHub Desktop.
Save artemuzz/ebf2f3152c65dff843a55a7bf1c5fd9a to your computer and use it in GitHub Desktop.
Max Headroom in Three.js

Max Headroom in Three.js

I maybe watched too many old reruns during covid-19. :)

A Pen by Monica on CodePen.

License.

const THREE = window.THREE;
const WALL_SIZE = 40;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
function makeWall(lineCount, color, pointsFn) {
const material = new THREE.LineBasicMaterial({ color });
const wall = new THREE.Mesh();
for(let i = 0; i < lineCount; i++) {
const geometry = new THREE.BufferGeometry().setFromPoints(pointsFn(i));
wall.add(new THREE.Line(geometry, material));
}
return wall;
}
const floor = makeWall(WALL_SIZE*2, 0xFFFF00, i => [
new THREE.Vector3(i, 0, 0),
new THREE.Vector3(i, 0, WALL_SIZE*2),
])
scene.add(floor);
const leftWall = makeWall(WALL_SIZE, 0xFF00FF, i => [
new THREE.Vector3(0, i, 0),
new THREE.Vector3(0, i, WALL_SIZE*2),
])
scene.add(leftWall);
const backWall = makeWall(WALL_SIZE, 0x00FF00, i => [
new THREE.Vector3(0, i, 0),
new THREE.Vector3(WALL_SIZE*2, i, 0),
])
scene.add(backWall);
camera.position.x = WALL_SIZE/3;
camera.position.y = WALL_SIZE/3;
camera.position.z = WALL_SIZE/3;
const PI = 3.14159;
function addToVector(dest, vec) {
dest.x += vec.x;
dest.y += vec.y;
dest.z += vec.z;
}
function randomNumber(min, max) {
return Math.random() * (max - min) + min;
}
function getCameraAnimation() {
// We only have two walls and a floor - need to make sure the camera doesn't look
// away into empty space. So:
//
// rotation.x should be between 0 and -0.5*PI
// rotation.y should be between 0 and 0.5*PI
// rotation.z can be anything.
// position.x/y/z should be between at most WALL_SIZE/4, and at least around 4
// (0 would be in the same plane as a wall/floor).
const newRotation = {
x: randomNumber(0, -0.5 * PI),
y: randomNumber(0, 0.5 * PI),
x: randomNumber(-0.15 * PI, -0.15 * PI),
z: Math.random() * 0.3 * PI - 0.15,
};
const newPosition = {
x: randomNumber(WALL_SIZE/4, WALL_SIZE/3),
y: randomNumber(WALL_SIZE/6, WALL_SIZE/3),
z: randomNumber(WALL_SIZE/4, WALL_SIZE/3),
};
const newPY = Math.random() * (WALL_SIZE/4 - 2) + 2;
const animationFrames = 240;
return {
animationFrames,
rotationIncrement: {
x: (newRotation.x - camera.rotation.x) / animationFrames,
y: (newRotation.y - camera.rotation.y) / animationFrames,
z: (newRotation.z - camera.rotation.z) / animationFrames,
},
positionIncrement: {
x: (newPosition.x - camera.position.x) / animationFrames,
y: (newPosition.y - camera.position.y) / animationFrames,
z: (newPosition.z - camera.position.z) / animationFrames,
},
};
}
let animationFrames = 0;
let rotationIncrement = {x: 0, y: 0, z: 0};
let positionIncrement = {x: 0, y: 0, z: 0};
const animate = function () {
requestAnimationFrame(animate);
if (animationFrames === 0) {
({animationFrames, rotationIncrement, positionIncrement} = getCameraAnimation());
}
addToVector(camera.rotation, rotationIncrement);
addToVector(camera.position, positionIncrement);
animationFrames--;
renderer.render(scene, camera);
};
animate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.js"></script>
body {
margin: 0;
}
canvas {
display: block;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment