第136篇:Three.js基础入门动画API:setInterval 与 requestAnimationFrame的区别
Posted 养肥胖虎
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第136篇:Three.js基础入门动画API:setInterval 与 requestAnimationFrame的区别相关的知识,希望对你有一定的参考价值。
好家伙,书接上文
function animate()
//请求-动画-框架 requestAnimationFrame( animate ); //改变正方体在场景中的位置,让正方体动起来 cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); // 结合场景和相机进行渲染,即用摄像机拍下此刻的场景(最后一步)
这是一段动画的渲染方案
这里使用了requestAnimationFrame()而没有使用定时器setInterval
动画渲染部分为什么不使用定时器setTimeout而使用requestAnimationFrame()?
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
当你准备更新动画时你应该调用此方法。这将使浏览器在下一次重绘之前调用你传入给该方法的动画函数 (即你的回调函数)。
回调函数执行次数通常是每秒 60 次,但在大多数遵循 W3C 建议的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配。
----来自MDN文档
说到定时器setInterval,我们又要扯到异步,
requestAnimationFrame()优势:
1.requestAnimationFrame()更流畅
定时器setInterval存在延迟卡顿的问题
而使用 requestAnimationFrame 执行动画,能保证回调函数在屏幕每一次刷新间隔中只被执行一次,
确保不丢帧,动画不卡顿
2.requestAnimationFrame()更合理
定时器setInterval的执行频率由时间决定
而requestAnimationFrame()的执行频率与浏览器屏幕刷新次数相匹配
3.节约资源
当页面被隐藏时,定时器 setInterval 仍在后台执行动画任务
而requestAnimationFrame()的动画刷新会暂停
Three.JS提升学习6:创建动画和移动摄像机
*本文学习资源来自《Three.js开发指南 WebGL的JavaScript 3D库》
基础动画
基础渲染函数
render();
function render()
renderer.render(scene, camera);
requestAnimationFrame(render);
简单动画
我们可以通过改变物体的旋转、缩放、位置、材质、顶点、面以及其它很多方式来实现动画。
通过改变摄像机来实现动画
renderScene();
function renderScene()
group.rotation.x += 0.02;
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
改变物体位置等属性实现动画
render();
function render()
stats.update();
// rotate the cube around its axes
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
// bounce the sphere up and down
step += controls.bouncingSpeed;
sphere.position.x = 20 + ( 10 * (Math.cos(step)));
sphere.position.y = 2 + ( 10 * Math.abs(Math.sin(step)));
// render using requestAnimationFrame
requestAnimationFrame(render);
renderer.render(scene, camera);
选择对象
document.addEventListener(mousedown, onDocumentMouseDown, false);
document.addEventListener(mousemove, onDocumentMouseMove, false);
var projector = new THREE.Projector();
var tube;
function onDocumentMouseDown(event)
// 屏幕坐标转为三维场景中的坐标
var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
vector = vector.unproject(camera);
//创建raycaster向场景中发射光线
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
//哪些被光线照到
var intersects = raycaster.intersectObjects([sphere, cylinder, cube]);
if (intersects.length > 0)
//照到的修改属性
console.log(intersects[0]);
intersects[0].object.material.transparent = true;
intersects[0].object.material.opacity = 0.1;
Tween.js
实现动画
// create a tween
// http://sole.github.io/tween.js/examples/03_graphs.html
var posSrc = pos: 1;
var tween = new TWEEN.Tween(posSrc).to(pos: 0, 5000);
tween.easing(TWEEN.Easing.Sinusoidal.InOut);
var tweenBack = new TWEEN.Tween(posSrc).to(pos: 1, 5000);
tweenBack.easing(TWEEN.Easing.Sinusoidal.InOut);
tween.chain(tweenBack);
tweenBack.chain(tween);
var onUpdate = function ()
var count = 0;
var pos = this.pos;
loadedGeometry.vertices.forEach(function (e)
var newY = ((e.y + 3.22544) * pos) - 3.22544;
pointCloud.geometry.vertices[count++].set(e.x, newY, e.z);
);
pointCloud.sortParticles = true;
;
tween.onUpdate(onUpdate);
tweenBack.onUpdate(onUpdate);
加载模型及启动tween
var loader = new THREE.PLYLoader();
loader.load("../assets/models/test.ply", function (geometry)
loadedGeometry = geometry.clone();
var material = new THREE.PointCloudMaterial(
color: 0xffffff,
size: 0.4,
opacity: 0.6,
transparent: true,
blending: THREE.AdditiveBlending,
map: generateSprite()
);
pointCloud = new THREE.PointCloud(geometry, material);
pointCloud.sortParticles = true;
tween.start();
scene.add(pointCloud);
);
render();
运行效果:
使用摄像机
Three.js 提供了一些摄像机控件,使用这些控件可以控制场景中的摄像机。这些控件在Three.js发布包中,可以在examples/js/controls目录中找到它们。
名称 | 英文 | 描述 |
第一视角控件器 | FirstPersonControls | 类似第一视角射击游戏中的摄像机,使用键盘移动、鼠标转动 |
飞行控制器 | FlyControls | 飞行模拟控制器,用键盘和鼠标控制摄像机的移动 |
翻滚控制器 | RollControls | 飞行控制器的简化版,允许绕着z轴旋转 |
轨迹球控制器 | TrackBallControls | 最常用的控制器,可以使用鼠标(或控制球)来轻松移动、平移或缩放场景 |
轨道控制器 | OrbitControls | 该控件可以在特定的场景中模拟轨道中的卫星,可以使用鼠标和键盘在场景中游走 |
其它控件:
设备朝向控制器:DeviceOrientationControls
编辑控制器:EditorControls
眼睛控制器:OculusControls
正交轨迹球控制器:OrthographicTrackball Controls
鼠标锁定控制器:PointerLockControls
变换控制器:TransformCOntrols
VR控制器:VRControls
除了控制器,还可以通过修改position属性来移动摄像机,通过lookAt()方法来改变摄像机的朝向。
轨迹球控制器使用示例
<script type="text/javascript" src="../libs/TrackballControls.js"></script>
<script>
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
/// 把控制器绑定到摄像机上
var trackballControls = new THREE.TrackballControls(camera);
trackballControls.rotateSpeed = 1.0; //摄像机的旋转速度
trackballControls.zoomSpeed = 1.0;
trackballControls.noZoom = false; //允许缩放
trackballControls.panSpeed = 1.0;
trackballControls.staticMoving = true;
</script>
在render里更新摄像机的位置
function render()
//用来精确计算出此次调用距离上次调用的时间间隔
var delta = clock.getDelta();
//更新摄像机的位置
trackballControls.update(delta);
requestAnimationFrame(render);
webGLRenderer.render(scene, camera)
变形动画与骨骼动画
略……
以上是关于第136篇:Three.js基础入门动画API:setInterval 与 requestAnimationFrame的区别的主要内容,如果未能解决你的问题,请参考以下文章
Three.js基础坐标轴辅助器requestAnimationFrame处理动画Clock时钟resize页面尺寸