您的位置:首页 > Web前端 > JavaScript

添加动画和控制组件(第一个例子)

2017-07-16 18:26 423 查看
这是第一个例子的最后学习.

这次学习会给第一个例子加上动画效果(requestAnimationFrame函数)。还会加入一个FPS监测组件(stats插件),一个简单的控制组件,控制立方体的旋转速度,球体的弹跳速度,通过鼠标来拖动控制组件来调节(dat.GUI库)

》》》》》stats插件

在例子中的HTML文件中,新加入一个ID为Stats-output的DIV,到时FPS监测插件会显示在这个DIV中

<!--构建一个DIV,显示一个FPS监测组件-->
<div id = "Stats-output">

</div>


写一个函数 initStats()来初始化stats插件,并返回一个stats插件对象

<!--一个FPS渲染监测插件-->
function  initStats() {
var  stats = new  Stats();
<!--setMode()参数:0-FPS监测;1-渲染时间监测-->
stats.setMode(0);
<!--stats插件位置-->
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
<!--插件加入到ID为Stats-output的DIV之中-->
$("#Stats-output").append(stats.domElement);
return stats;
}


在匿名的JQuery函数中,取得初始化好的stats变量,以备渲染时使用;主要是注意该变量的范围,不然引用不到,别的函数中要引用该变量,所以把该变量放在最开始的匿名的函数中,因为第一个例子中所有的操作都在这个匿名函数中,相当于一个全局的,其他的函数都定义在这个匿名函数中,所以其它任何定义在这个匿名函数中的函数,都可以引用到stats变量

$(function(){
....
var stats = initStats();
......
})


》》》》》》》》》》》》》添加动画:

通过requestAnimationFrame()你可以指定一个函数,按照浏览器指定的时间间隔进行调用。可以在这个指定函数中执行任何必要的绘画操作,浏览器会尽可能的保证绘画过程的平滑和高效。为了使用这个函数添加动画效果,我们需要再改写一下第一个例子中最后的渲染输出。重新定义一个渲染函数:

function renderScene() {
stats.update();
requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}


在重新定义的渲染函数中,requestAnimationFrame(renderScene)又调用了renderScene函数,这样可以保证动画的持续。

在第一个例子的最后渲染时,不直接调用renderer.render(scene,camera);而是改成调用重新定义的渲染函数。

..........
<!--利用JQuery查找到ID为WebGL-output的DIV,并把渲染到的东西输出到该DIV-->
$("#WebGL-output").append(renderer.domElement);
<!--利用渲染器以给定的相机去渲染场景-->
// renderer.render(scene,camera);
renderScene();


如果现在查看,可能看不到动画效果,但是可以看到页面左上角的FPS 监测有变化。

》》》》》dat.GUI控制组件使用:

添加控制组件,对立方体和球体的旋转和弹跳进行控制,添加完之后,可以看到明显的动画效果

首先定义一个JavaScript对象controls,含有2个进行控制的属性rotationSpeed和bouncingSpeed,保存我们希望通过dat.GUI库进行修改的变量。分别初始化为0.02和0.03

<!--dat.GUI插件加入,简单的页面控制组件-->
var controls = new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03
};


把定义的这2个属性rotationSpeed和bouncingSpeed加入到dat.GUI对象:

<!--构建一个dat.GUI插件对象,并加入相应的控制组件-->
var gui  = new dat.GUI();
gui.add(controls,'rotationSpeed',0,0.5);
gui.add(controls,'bouncingSpeed',0,0.5);


gui.add()函数的最后2个参数,指定变量控制的范围:0~0.5;[0,0.5]

定义一个全局的变量step,定义在最开始的匿名函数中,之后在定义的渲染函数中添加必要的控制操作:

var step = 0;
function renderScene() {
stats.update();

cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;

step += controls.bouncingSpeed;
sphere.position.x = 20 + (10*(Math.cos(step)));
sphere.position.y = 2+(10*Math.abs(Math.sin(step)));

requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}


完整页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Three.js 第一章学习</title>
<!--需要的基本JS库-->
<script src="jquery19.js"></script>
<script src="three.js"></script>
<script src ="stats.js"></script>
<script src = "dat.gui.js"></script>
<script src = "controlKit.js"></script>
<!--给body加入一个样式,边框为0(零,不显示边框);滚动条隐藏-->
<style type="text/css">
body{
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!--建立一个DIV,WebGL渲染的基本物体会在此处输出-->
<div id="WebGL-output">

</div>

<!--构建一个DIV,显示一个FPS监测组件--> <div id = "Stats-output"> </div>

<!--定义一个JQuery函数,所有的WebGL操作展示将在该函数中进行-->
<script type="text/javascript">
$(function () {
<!--构建场景-->
var scene = new THREE.Scene();
<!--建立相机,查看场景,透视相机-->
var camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
<!--构建渲染器,进行渲染-->
var renderer = new THREE.WebGLRenderer();
<!--渲染背景色,不知道为什么在此学习过程中,该函数setClearColorHex()老是提示错误?-->
// renderer.setClearColorHex(0xEEEEEE);
renderer.setClearColor(0xAAFFCC);
<!--渲染尺寸-->
renderer.setSize(window.innerWidth,window.innerHeight);

<!--告诉渲染器需要渲染出阴影-->
renderer.shadowMapEnabled = true;

<!--添加一个辅助坐标轴-->
var axes = new THREE.AxisHelper(20);
scene.add(axes);

<!--构建一个平面,物体将会放置在这个平面上-->
<!--平面尺寸,100x60,宽度方向平分几分,高度方向平分几分,如果参数最后2位不是(1,1),平面会显示为网格平面-->
var planeGeometry = new THREE.PlaneGeometry(100,60,10,10);
<!--平面材质,仅仅指定颜色 0xcccccc-->
// var planeMaterial = new THREE.MeshBasicMaterial({color:0xccaacc});

<!--临时修改材质为MeshLambertMaterial-->
var planeMaterial = new THREE.MeshLambertMaterial({color:0xFFFFFF});

<!--有尺寸和材质构建一个平面-->
var plane = new THREE.Mesh(planeGeometry,planeMaterial);
<!--把平面选择-90°,方便观察-->
plane.rotation.x = -0.5*Math.PI;
<!--指定平面的位置-->
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;

<!--指定平面接受阴影,就是物体投射出的阴影会出现在该平面上-->
plane.receiveShadow = true;

<!--把平面加入到场景中-->
scene.add(plane);
<!--建立物体,一个立方体,一个球体-->
<!--建立一个立方体-->
<!--指定立方体的几何尺寸,长宽高,不包括位置-->
var cubeGeometry = new THREE.CubeGeometry(4,4,4);
<!--指定立方体的材质,仅仅指定颜色:0xFF0000,是否使用线框模式显示:是-->
// var cubeMaterial = new THREE.MeshBasicMaterial({color:0xFF0000,wireframe:true});
<!--临时修改材质为MeshLambertMaterial-->
var cubeMaterial = new THREE.MeshLambertMaterial({color:0xFF0000});
<!--以给定的几何尺寸和材质构建一个立方体-->
var cube = new THREE.Mesh(cubeGeometry,cubeMaterial);
<!--指定立方体的具体位置xyz-->
cube.position.x =-4;
cube.position.y =3;
cube.position.z = 0;

<!--指出物体会投射阴影-->
cube.castShadow = true;

<!--把建立的立方体放入场景-->
scene.add(cube);

<!--建立一个球体sphere-->
<!--指定球体的几何尺寸,不包括位置;最后2个参数感觉是指定网格密度-->
var sphereGeometry = new THREE.SphereGeometry(4,50,50);
<!--指定球体材质,仅仅指定颜色:0xFF0000,是否以线框形式显示:是-->
// var sphereMaterial = new THREE.MeshBasicMaterial({color:0xff0000,wireframe:true});

<!--临时修改材质为MeshLambertMaterial-->
var sphereMaterial = new THREE.MeshLambertMaterial({color:0x7777FF});

<!--以给定的几何尺寸和材质,建立一个球体-->
var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
<!--指定球体的位置 X Y Z-->
sphere.position.x =20;
sphere.position.y=4;
sphere.position.z = 2;

<!--指出物体会投射阴影-->
sphere.castShadow = true;

<!--把建立的球体加入到场景中-->
scene.add(sphere);

<!--建立一个聚光灯变量,用来照射物体来产生阴影-->
<!--建立一个spotLight变量,指定颜色:0xFFFFFF-->
var spotLight = new THREE.SpotLight(0xFFFFFF);
<!--指定spotLight的位置-->
spotLight.position.set(-40,60,-10);

<!--指出此光源照射物体,使物体产生阴影-->
spotLight.castShadow = true;

<!--把spotLight加入到场景中-->
scene.add(spotLight);

<!--指定相机的位置和方向,决定我们在场景中如何看,能看到什么-->
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);

<!--动画:requestAnimationFrame()-->

<!--一个FPS渲染监测插件-->
function initStats() {
var stats = new Stats();
<!--setMode()参数:0-FPS监测;1-渲染时间监测-->
stats.setMode(0);
<!--stats插件位置-->
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
<!--插件加入到ID为Stats-output的DIV之中-->
$("#Stats-output").append(stats.domElement);
return stats;
}
var stats = initStats();

<!--dat.GUI插件加入,简单的页面控制组件-->
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);

var step = 0;
function renderScene() {
stats.update();

cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;

step += controls.bouncingSpeed;
sphere.position.x = 20 + (10*(Math.cos(step)));
sphere.position.y = 2+(10*Math.abs(Math.sin(step)));

requestAnimationFrame(renderScene);
renderer.render(scene,camera);
}

<!--利用JQuery查找到ID为WebGL-output的DIV,并把渲染到的东西输出到该DIV-->
$("#WebGL-output").append(renderer.domElement);
<!--利用渲染器以给定的相机去渲染场景-->
// renderer.render(scene,camera);
renderScene();
}) ;
</script>

</body>
</html>


整个页面效果:



动画效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐