// Implementing Responsive Design in Three.js
// Source: https://threejsfundamentals.org/threejs/threejs-responsive.html
'use strict';
/* global THREE */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 75;
const aspect = 2; // the default for canvas
const near = 0.1;
const far = 250;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(20, 10, 20);
const controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(0, 0, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('white');
function addLight(...pos) {
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(...pos);
scene.add(light);
}
addLight(-1, 2, 4);
addLight( 1, 2, 2);
const shape = new THREE.Shape();
shape.moveTo(-1, -1);
shape.lineTo( 0, -1);
shape.lineTo( 0, -2);
shape.lineTo( 2, 0);
shape.lineTo( 0, 2);
shape.lineTo( 0, 1);
shape.lineTo(-1, 1);
const extrudeSettings = {
depth: 1,
bevelEnabled: false,
};
const geometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings);
geometry.applyMatrix(new THREE.Matrix4().makeRotationY(Math.PI * -0.5));
const arrows = [];
const spread = 5;
for (let z = -3; z <= 3 ; ++z) {
for (let x = -3; x <= 3; ++x) {
const material = new THREE.MeshPhongMaterial({
color: new THREE.Color().setHSL(Math.abs(Math.atan2(x, z)) / Math.PI, 1, 0.5),
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
arrows.push(mesh);
mesh.position.set(x * spread, 0, z * spread);
}
}
const geometry2 = new THREE.SphereBufferGeometry();
const sphere = new THREE.Mesh(geometry2, new THREE.MeshPhongMaterial({color:'red'}));
const base = new THREE.Object3D();
scene.add(base)
base.position.y = 10;
const base2 = new THREE.Object3D();
base.add(base2);
base2.position.z = 15;
const base3 = new THREE.Object3D();
base2.add(base3);
base3.position.z = 5;
base3.add(sphere);
sphere.position.y = 5;
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render(time) {
time *= 0.001;
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
base.rotation.y = time;
base2.rotation.y = time * 0.77;
base3.rotation.z = time * 2.33;
const temp = new THREE.Vector3();
for (const arrow of arrows) {
sphere.getWorldPosition(temp);
temp.y = arrow.position.y
arrow.lookAt(temp);
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
body { margin: 0; }
#c { width: 100vw; height: 100vh; display: block; }
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>