OrbiterControls not working properly in three.js app
Solution 1:
The code needed several modifications. Use the code below instead and compare it with yours to find out which parts did I change.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body {
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js';
import {OrbitControls} from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
// BUILDING THE SCENE
const scene = new THREE.Scene();
// ADDING CAMERA
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, -5, 5);
scene.add(camera);
// CREATING THE RENDERER
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// ADD LIGHT
const light = new THREE.PointLight(0xffffff, 2);
light.position.set(0, 5, 10);
scene.add(light);
// ADD ORBITER
const controls = new OrbitControls(camera, renderer.domElement);
controls.maxPolarAngle = Math.PI/2.2;
controls.minDistance = 5;
controls.maxDistance = 10;
controls.target.set(0, 0, 0);
// ADD CUBE
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({color: 0x00ff00});
const cube = new THREE.Mesh(geometry, material);
cube.position.set(0, .5, 0);
scene.add(cube);
// ADD MAP
const loader = new THREE.TextureLoader();
const height = loader.load('/data/images/height.png');
const texture = loader.load('/data/images/height.png');
const map_geometry = new THREE.PlaneBufferGeometry(10,10,64,64);
const map_material = new THREE.MeshStandardMaterial({
color:'orange',
side: THREE.DoubleSide,
map:texture,
displacementMap: height,
displacementScale: 0.5,
});
const map_plane = new THREE.Mesh(map_geometry, map_material);
map_plane.rotation.x = Math.PI/2;
scene.add(map_plane);
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// ANIMATING THE SCENE
function animate() {
controls.update();
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html>
- Write
controls.update();
in the animate function. -
controls.maxPolarAngle = Math.PI/2.2;
doesn't let the camera to go under the ground. -
controls.target.set(0, 0, 0);
makes the control stair at the center. - I added
map_plane.rotation.x = Math.PI/2;
so the plane will be placed horizontally as the floor. - And
side: THREE.DoubleSide,
helps the floor to be visible from all angels. - I also added an
onWindowResize
function to the script to make the applicaion responsive. Now, it'll response to the browser's width and height when its resized. - In case of CSS, the page has default padding as well. So, adding a
padding: 0;
to the CSS code is not a bad idea as well.