在实际开发中,3D美术提供的三维模型可能包含帧动画数据需要你解析渲染,比如一个机械的装配过程,一个车门开关的动作,一个物体的移动动画。这时候你首先要对建立帧动画的概念,然后对Threejs帧动画相关的API使用规则进行熟悉,这样才能很好的解析加载的外部模型包含的帧动画。
效果图:
Threejs提供了一系列用户编辑和播放关键帧动画的API,使用关键帧KeyframeTrack
和剪辑AnimationClip
编写一个关键帧动画,然后调用操作AnimationAction
、混合器AnimationMixer
播放编写好的关键帧动画。
主要代码:
<button onclick="pause()" type="button" style="position: absolute;padding: 10px;">暂停/继续</button> <button onclick="pos()" type="button" style="position: absolute;padding: 10px;left:90px">时间递增</button>
/** * 创建两个网格模型并设置一个父对象group */ var group = new THREE.Group(); mesh1.name = "Box"; //网格模型1命名 mesh2.name = "Sphere"; //网格模型2命名 group.add(mesh1); //网格模型添加到组中 group.add(mesh2); //网格模型添加到组中 /** * 编辑group子对象网格模型mesh1和mesh2的帧动画数据 */ // 创建名为Box对象的关键帧数据 var times = [0, 100]; //关键帧时间数组,离散的时间点序列 var values = [0, 0, 0, 150, 0, 0]; //与时间点对应的值组成的数组 // 创建位置关键帧对象:0时刻对应位置0, 0, 0 10时刻对应位置150, 0, 0 var posTrack = new THREE.KeyframeTrack('Box.position', times, values); // 创建颜色关键帧对象:10时刻对应颜色1, 0, 0 20时刻对应颜色0, 0, 1 var colorKF = new THREE.KeyframeTrack('Box.material.color', [50, 100], [1, 0, 0, 0, 0, 1]); // 创建名为Sphere对象的关键帧数据 从0~20时间段,尺寸scale缩放3倍 var scaleTrack = new THREE.KeyframeTrack('Sphere.scale', [30, 100], [1, 1, 1, 5, 5, 5]); // duration决定了默认的播放时间,一般取所有帧动画的最大时间 // duration偏小,帧动画数据无法播放完,偏大,播放完帧动画会继续空播放 var duration = 100; // 多个帧动画作为元素创建一个剪辑clip对象,命名"default",持续时间20 var clip = new THREE.AnimationClip("default", duration, [posTrack, colorKF, scaleTrack]) scene.add(group); // 暂停继续播放函数 function pause() { if (AnimationAction.paused) { // 如果是播放状态,设置为暂停状态 AnimationAction.paused = false; } else { // 如果是暂停状态,设置为播放状态 AnimationAction.paused = true; } } // 时间点设置函数 function pos() { // 开始结束时间设置为一样,相当于播放时间为0,直接跳转到时间点对应的状态 AnimationAction.time += 2; //操作对象设置开始播放时间 clip.duration = AnimationAction.time; //剪辑对象设置播放结束时间 AnimationAction.play(); //开始播放 } /** * 播放编辑好的关键帧数据 */ // group作为混合器的参数,可以播放group中所有子对象的帧动画 var mixer = new THREE.AnimationMixer(group); // 剪辑clip作为参数,通过混合器clipAction方法返回一个操作对象AnimationAction var AnimationAction = mixer.clipAction(clip); //通过操作Action设置播放方式 AnimationAction.timeScale = 20; //默认1,可以调节播放速度 // AnimationAction.loop = THREE.LoopOnce; //不循环播放 AnimationAction.play(); //开始播放