课程表

three.js课程

工具箱
速查手册

Three 帧动画模块

当前位置:免费教程 » JS/JS库/框架 » three.js

在实际开发中,3D美术提供的三维模型可能包含帧动画数据需要你解析渲染,比如一个机械的装配过程,一个车门开关的动作,一个物体的移动动画。这时候你首先要对建立帧动画的概念,然后对Threejs帧动画相关的API使用规则进行熟悉,这样才能很好的解析加载的外部模型包含的帧动画。

1.gif

2.gif


编辑关键帧并解析播放

Threejs提供了一系列用户编辑和播放关键帧动画的API,例如关键帧KeyframeTrack、剪辑AnimationClip、操作AnimationAction、混合器AnimationMixer。

1.jpg

为了让大家更好的理解关键帧动画,本节课不加载外部模型的帧动画数据,使用关键帧KeyframeTrack和剪辑AnimationClip编写一个关键帧动画,然后调用操作AnimationAction、混合器AnimationMixer播放编写好的关键帧动画。

创建两个用于动画的网格模型

先创建两个用于关键帧动画的网格模型。

  1. /**
  2.  * 创建两个网格模型并设置一个父对象group
  3.  */
  4. mesh1.name = "Box"; //网格模型1命名
  5. mesh2.name = "Sphere"; //网格模型2命名
  6. group.add(mesh1); //网格模型添加到组中
  7. group.add(mesh2); //网格模型添加到组中

在线运行案例


解析外部模型的帧动画

本节课通过一个案例来展示Threejs如何加载并播放外部模型中的帧动画数据。

关键帧数据

如果有兴趣,你可以打开模型文件model.json查看里面与帧动画有关的关键帧数据。

  1. "object": {
  2.   // 绑定动画的模型名称Box
  3.   "name": "Box",
  4. ...
  5. },
  6. // 动画数据
  7. "animations": [{
  8.   "name": "default",
  9.   "fps": 24,
  10.   "tracks": [
  11.     // 位置变化关键帧
  12.     {
  13.     "type": "vector3",
  14.     "name": "Box.position",
  15.     "keys": [{
  16.       "value": [0, 0, 0],
  17.       "time": 0
  18.     }, {
  19.       "value": [-100, 0, 0],
  20.       "time": 50
  21.     },...]
  22.   },
  23.   // 角度变化关键帧
  24.   {
  25.     "type": "quaternion",
  26.     "name": "Box.quaternion",
  27.     "keys": [{
  28.       "value": [0, 0, 0, 0],
  29.       "time": 0
  30.     },...]
  31.   },
  32.   // 颜色变化关键帧
  33.   {
  34.     "type": "color",
  35.     "name": "Box.material.color",
  36.     "keys": [{
  37.       "value": [1, 0, 0, 1],
  38.       "time": 20
  39.     }, ...]
  40.   }]
  41. }]

播放模型帧动画

  1. // 通过ObjectLoader加载模型文件model.json
  2. var loader = new THREE.ObjectLoader();
  3. var mixer = null; //声明一个混合器变量
  4. // 加载文件返回一个对象obj
  5. loader.load("model.json", function(obj) {
  6.   obj.scale.set(15, 15, 15);//缩放加载的模型
  7.   scene.add(obj);
  8.   // obj作为混合器的参数,可以播放obj包含的帧动画数据
  9.   mixer = new THREE.AnimationMixer(obj);
  10.   // obj.animations[0]:获得剪辑clip对象
  11.   // // 剪辑clip作为参数,通过混合器clipAction方法返回一个操作对象AnimationAction
  12.   var AnimationAction = mixer.clipAction(obj.animations[0]);
  13.   AnimationAction.play();
  14. });
  1. // 创建一个时钟对象Clock
  2. var clock = new THREE.Clock();
  3. // 渲染函数
  4. function render() {
  5.   renderer.render(scene, camera); //执行渲染操作
  6.   requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
  7.  
  8.   if(mixer!==null){
  9.     //clock.getDelta()方法获得两帧的时间间隔
  10.     // 更新混合器相关的时间
  11.     mixer.update(clock.getDelta());
  12.   }
  13. }
  14. render();

播放设置

你可以通过操作AnimationAction的相关属性设置播放效果。

  1. //不循环播放(默认是循环播放)
  2. AnimationAction.loop = THREE.LoopOnce;
  1. //暂停在最后一帧播放的状态
  2. AnimationAction.clampWhenFinished=true;

播放设置(暂停、时间段、时间点)

你可以通过剪辑AnimationClip、操作AnimationAction、混合器AnimationMixer完成一些播放效果。

播放/暂停(.paused属性)

HTML按钮和点击事件代码:

  1. <button onclick="pause()" type="button" style="position: absolute;padding: 10px;">暂停/继续</button>
  2. <script>
  3.   // 暂停继续播放函数
  4.   function pause() {
  5.     if (AnimationAction.paused) {
  6.       // 如果是播放状态,设置为暂停状态
  7.       AnimationAction.paused = false;
  8.     } else {
  9.       // 如果是暂停状态,设置为播放状态
  10.       AnimationAction.paused = true;
  11.     }
  12.   }
  13. </script>

在线运行案例

播放clip特定时间段

  1. /**
  2.  * 播放编辑好的关键帧数据
  3.  */
  4. var mixer = new THREE.AnimationMixer(mesh); //创建混合器
  5. var AnimationAction = mixer.clipAction(clip); //返回动画操作对象
  6. // AnimationAction.timeScale = 5; //默认1,可以调节播放速度
  7. AnimationAction.loop = THREE.LoopOnce; //不循环播放
  8. AnimationAction.clampWhenFinished = true; //暂停在最后一帧播放的状态
  9. // 设置播放区间10~18   关键帧数据总时间是20
  10. AnimationAction.time = 10; //操作对象设置开始播放时间
  11. clip.duration = 18;//剪辑对象设置播放结束时间
  12. AnimationAction.play(); //开始播放

在线运行案例

定位在某个时间点

  1. // 开始结束时间设置为一样,相当于播放时间为0,直接跳转到时间点对应的状态
  2. AnimationAction.time = 10; //操作对象设置开始播放时间
  3. clip.duration = AnimationAction.time;//剪辑对象设置播放结束时间
  1. /**
  2.  * 播放编辑好的关键帧数据
  3.  */
  4. var mixer = new THREE.AnimationMixer(mesh); //创建混合器
  5. var AnimationAction = mixer.clipAction(clip); //返回动画操作对象
  6. // AnimationAction.timeScale = 5; //默认1,可以调节播放速度
  7. AnimationAction.loop = THREE.LoopOnce; //不循环播放
  8. AnimationAction.clampWhenFinished = true; //暂停在最后一帧播放的状态
  9. // 开始结束时间设置为一样,相当于播放时间为0,直接跳转到时间点对应的状态
  10. AnimationAction.time = 10; //操作对象设置开始播放时间
  11. clip.duration = AnimationAction.time;//剪辑对象设置播放结束时间
  12. AnimationAction.play(); //开始播放

在线运行案例

快进(按钮递增时间点)

  1. <button onclick="pos()" type="button" style="position: absolute;padding: 10px;">时间递增</button>
  2. <script>
  3.   // 时间点设置函数
  4.   function pos() {
  5.     // 开始结束时间设置为一样,相当于播放时间为0,直接跳转到时间点对应的状态
  6.     AnimationAction.time += 2; //操作对象设置开始播放时间
  7.     clip.duration = AnimationAction.time;//剪辑对象设置播放结束时间
  8.     AnimationAction.play(); //开始播放
  9.   }
  10. </script>

控制部分:

  1. /**
  2.  * 播放编辑好的关键帧数据
  3.  */
  4. var mixer = new THREE.AnimationMixer(mesh); //创建混合器
  5. var AnimationAction = mixer.clipAction(clip); //返回动画操作对象
  6. // AnimationAction.timeScale = 5; //默认1,可以调节播放速度
  7. AnimationAction.loop = THREE.LoopOnce; //不循环播放
  8. AnimationAction.clampWhenFinished = true; //暂停在最后一帧播放的状态

在线运行案例

滚动条拖动播放帧动画

通过一个滚动条拖动播放帧动画,就像你观看视频一样,有一个视频条可以拖动。

关于前端滚动条的代码,这里使用的是H5原生的range控件。

  1. <input type="range" id="rg" value="10" min="0" max="20" step="1" onchange="changeV()" />
  2. <script>
  3. function changeV() {
  4. var boxL = parseInt(document.getElementById('rg').value);
  5. AnimationAction.time = boxL; //操作对象设置开始播放时间
  6. clip.duration = boxL;//剪辑对象设置播放结束时间
  7. AnimationAction.play(); //开始播放
  8. }
  9. </script>

在线运行案例

转载本站内容时,请务必注明来自W3xue,违者必究。
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号