OrbiterControls 在 three.js 应用程序中无法正常工作
OrbiterControls not working properly in three.js app
我正在尝试创建一个基本场景,其中包含一个可以围绕中心旋转的轨道器控件,即始终注视 (0,0,0)。我希望它的行为完全像这样 https://threejs.org/examples/misc_controls_orbit.html。但在我的版本中,如果我单击并拖动到 left/right,相机只会旋转一圈,始终注视着 (0,0,0)。我该如何解决这个问题?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body {
margin: 0;
}
</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';
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 );
// 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.listenToKeyEvents( window );
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;
//controls.screenSpacePanning = false;
//controls.minDistance = 100;
//controls.maxDistance = 500;
//controls.maxPolarAngle = Math.PI / 2;
//controls.minPolarAngle = Math.PI / 2;
//controls.maxPolarAngle = Math.PI / 2;
camera.position.set(0, -5, 5);
camera.lookAt( 0, 0, 0 );
camera.up.set( 0, 0, 1 );
//controls.target = new THREE.Vector3(0, 0, 0);
controls.update();
// ADD CUBE
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
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,
//alphaMap: alpha,
//transparent:true
});
const map_plane = new THREE.Mesh(map_geometry, map_material);
//map_plane.position.set(0, 0, 0);
scene.add( map_plane );
// RENDER
function animate() {
requestAnimationFrame( animate );
//cube.rotation.x += 0.01;
//cube.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
代码需要多次修改。请改用下面的代码并将其与您的代码进行比较,以找出我更改了哪些部分。
<!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>
- 在animate函数中写入
controls.update();
controls.maxPolarAngle = Math.PI/2.2;
不让相机下地
controls.target.set(0, 0, 0);
使控制楼梯在中心。
- 我添加了
map_plane.rotation.x = Math.PI/2;
所以飞机会像地板一样水平放置。
- 并且
side: THREE.DoubleSide,
帮助地板从所有角度都可见。
- 我还在脚本中添加了一个
onWindowResize
函数来使应用程序响应。现在,它会在调整大小时响应浏览器的宽度和高度。
- 在 CSS 的情况下,页面也有默认填充。因此,在 CSS 代码中添加
padding: 0;
也是一个不错的主意。
我正在尝试创建一个基本场景,其中包含一个可以围绕中心旋转的轨道器控件,即始终注视 (0,0,0)。我希望它的行为完全像这样 https://threejs.org/examples/misc_controls_orbit.html。但在我的版本中,如果我单击并拖动到 left/right,相机只会旋转一圈,始终注视着 (0,0,0)。我该如何解决这个问题?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body {
margin: 0;
}
</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';
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 );
// 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.listenToKeyEvents( window );
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;
//controls.screenSpacePanning = false;
//controls.minDistance = 100;
//controls.maxDistance = 500;
//controls.maxPolarAngle = Math.PI / 2;
//controls.minPolarAngle = Math.PI / 2;
//controls.maxPolarAngle = Math.PI / 2;
camera.position.set(0, -5, 5);
camera.lookAt( 0, 0, 0 );
camera.up.set( 0, 0, 1 );
//controls.target = new THREE.Vector3(0, 0, 0);
controls.update();
// ADD CUBE
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
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,
//alphaMap: alpha,
//transparent:true
});
const map_plane = new THREE.Mesh(map_geometry, map_material);
//map_plane.position.set(0, 0, 0);
scene.add( map_plane );
// RENDER
function animate() {
requestAnimationFrame( animate );
//cube.rotation.x += 0.01;
//cube.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
代码需要多次修改。请改用下面的代码并将其与您的代码进行比较,以找出我更改了哪些部分。
<!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>
- 在animate函数中写入
controls.update();
controls.maxPolarAngle = Math.PI/2.2;
不让相机下地controls.target.set(0, 0, 0);
使控制楼梯在中心。- 我添加了
map_plane.rotation.x = Math.PI/2;
所以飞机会像地板一样水平放置。 - 并且
side: THREE.DoubleSide,
帮助地板从所有角度都可见。 - 我还在脚本中添加了一个
onWindowResize
函数来使应用程序响应。现在,它会在调整大小时响应浏览器的宽度和高度。 - 在 CSS 的情况下,页面也有默认填充。因此,在 CSS 代码中添加
padding: 0;
也是一个不错的主意。