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

来源:互联网 发布:淘宝男士挎包 单肩包 编辑:程序博客网 时间:2024/05/29 17:55

这是第一个例子的最后学习.
这次学习会给第一个例子加上动画效果(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>

整个页面效果:
这里写图片描述

动画效果:
这里写图片描述

原创粉丝点击