Three.js--6.使用dat.GUI库添加一个用户界面
使用dat.GUI 很容易可以创建一个简单的页面组件,用以修改代码中的变量;
示例中:
- 控制球体弹跳的速度
- 控制方块的旋转
首先,先引入库
<script src="./libs/dat.gui.js"></script>
接下来,我们定义一个JavaScript 对象,用来保存我们想要通过dat.GUI 库来修改的那些变量;
在这个JavaScript 对象里,定义了两个属性(this.rotationSpeed和this.bouncingSpeed),以及它们的默认值;
var controls = new function() {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
}
再接下来,我们把这个对象传递给dat.GUI对象,并定义这两个属性值的范围:
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls, 'bouncingSpeed', 0, 0.5);
属性rotationSpeed和 bouncingSpeed 的取值范围都是从0到0.5;
现在要做的就是保证在animate 循环里直接引用这两个属性;
这样当我在dat.GUI 用户界面里修改时可以直接影响物体的旋转速度和弹跳速度;
var animate = function() {
...
step += controls.bouncingSpeed;
requestAnimationFrame(animate);
sphere.position.x = 8 + (15 * (Math.cos(step)));
sphere.position.y = 2 + (5 * Math.abs(Math.sin(step)));
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
...
}
实现效果图和代码(请忽视效果图右下角的输入法图标哈)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>这世界唯一的妳</title>
</head>
<style>
body{
margin: 0;
overflow: hidden;
}
</style>
<script src="./libs/three.js"></script>
<script src="./libs/stats.js"></script>
<script src="./libs/dat.gui.js"></script>
<body onload='init();'>
<div id="dv">
</div>
<script>
function init(){
var stats = initStats();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000000);
renderer.setSize(window.innerWidth,window.innerHeight);
document.getElementById('dv').appendChild(renderer.domElement);
var spotLight = new THREE.SpotLight();
spotLight.position.set(-40,60,-10);
scene.add(spotLight);
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
var planeGeometry = new THREE.PlaneBufferGeometry(50, 20);
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5 *Math.PI;
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.position.x = -15;
cube.position.y = 3;
cube.position.z = 0;
scene.add(cube)
var sphereGeometry = new THREE.SphereGeometry(3, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x = -20;
sphere.position.y = 4;
sphere.position.z = 0;
sphere.castShadow = true;
scene.add(sphere)
camera.position.x = -30;
camera.position.y = 20;
camera.position.z = 30;
camera.lookAt(scene.position);
function initStats(){
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById('dv').appendChild(stats.domElement);
return stats;
}
var controls = new function() {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
}
// 设置取值范围
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls, 'bouncingSpeed', 0, 0.5);
var step = 0
var animate = function() {
stats.update();
//球的弹跳速度
step += controls.bouncingSpeed;
requestAnimationFrame(animate);
sphere.position.x = 8 + (15 * (Math.cos(step)));
sphere.position.y = 2 + (5 * Math.abs(Math.sin(step)));
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
renderer.render(scene, camera);
}
animate();
}
</script>
</body>
</html>