在搭建WebGL开发环境中介绍了如何开始使用webgl进行绘制。
本篇文章介绍如何在WebGL中创建动画
动画是一种通过快速显示一系列图像(或帧)模拟运动的技术。
网页上的动画基本分为三类:
抛开技术不谈,我们先梳理一下使用webgl技术怎么实现一个动画,比如最简单的,让一个点移动,过程如下:
只要我们每一帧的时间足够短,我们就能看到一个点在画布上运动。
setInterval()方法重复调用一个函数或执行一个代码片段,在每次调用之间具有固定的时间间隔。
var intervalID = setInterval(func, [delay, arg1, arg2, ...]);
毫秒
后执行一次。第一次调用发生在 delay 毫秒之后。如果未指定,则其默认值为 0,也就是每个事件循环都会执行一次
它返回一个 interval ID,该 ID 唯一地标识时间间隔,因此你可以稍后通过调用 clearInterval() 来移除定时器。
setTimeout() 方法设置一个定时器,一旦定时器到期,就会执行一个函数或指定的代码片段。
setTimeout(func, delay, arg1, arg2, /* … ,*/ argN)
毫秒
后执行的函数。如果省略该参数,则使用值 0,意味着“立即”执行
,或者更准确地说,在下一个事件循环执行。返回值 timeoutID 是一个正整数,表示由 setTimeout() 调用创建的定时器的编号。这个值可以传递给 clearTimeout() 来取消该定时器。
虽然Web开发人员很久以前就可以用setInterval和setTimeout函数创建动画,但是最近人们推荐另一种实现基于脚本的动画的方式。
requestAnimationFrame
,与setInterval和setTimeout函数一样,后者也是HTML DOM窗口对象的一部分
requestAnimationFrame是一个全局函数,是浏览器用于定时循环
操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘,让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。
关于requestAnimationFrame,需要注意一下几点:
requestAnimationFrame(callback)
callback:当你的动画需要更新时,为下一次重绘所调用的函数。该回调函数会传入一个参数,表示 requestAnimationFrame() 开始执行回调函数的时间戳。
注意:在同一个帧中的多个回调函数,它们每一个都会接受到一个相同的时间戳,即使在计算上一个回调函数的工作负载期间已经消耗了一些时间。该时间戳是一个十进制数,单位为毫秒,最小精度为 1ms
一个long整数,请求 ID,是回调列表中唯一的标识。是个非零值,没有别的意义。你可以传这个值给window.cancelAnimationFrame()
以取消回调函数请求。
下面是一个使用requestAnimationFrame设置动画的例子
// 所有动画回调的集合
var animCallbacks=new Array();
/**
* 设置刷新
* @param {*} fps 刷新率
* @param {*} updateCallback 回调函数,处理每帧的逻辑
*/
function setUpdate(fps,updateCallback)
{
updateCallback.interval = 1000/fps;
updateCallback.lastTime = undefined;
animCallbacks.push(updateCallback);
if(animCallbacks.length==1)
{
tick();
}
}
/**
* 时钟,用于确定是否需要刷新
*/
function tick(timeStamp)
{
requestAnimationFrame(tick.bind(this));
animCallbacks.forEach(callback => {
if(!callback)
{
return;
}
if(callback.lastTime == undefined)
{
callback.lastTime = timeStamp;
}
if(timeStamp && timeStamp - callback.lastTime>=callback.interval)
{
callback.lastTime = timeStamp;
callback();
}});
}
完整代码已上传gitlab