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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值