我的笔记代码并不是完全和视频一致的。
这一小节有趣的一点是做了setInterval的迭代式形式。 nextTick函数,其中有requestAnimationFrame(nextTick)。
其中不断更新记录上一帧结束的时间lastTick。
而这样的话,lastTick- startTime /interval 大概就是过了多少帧了。
代码:
function startTimeline(timeline, startTime) {
//设置实例上的数据,储存用
timeline.startTime = startTime
//为用requestAnimationFrame加上的callback.interval
nextTick.interval = timeline.interval
//记录最后一次回调的时间戳
var lastTick = +new Date();
nextTick();
//+new Date() == new Date().getTime()
//其实这是一个迭代形式的setInterval
//每一帧都执行的函数哦
function nextTick() {
//判断如果时间到interval设定了的时间了,就执行回调,
var now = +new Date();
timeline.animationHandler = requestAnimationFrame(nextTick)
if (now - lastTick >= timeline.interval) {
timeline.onenterframe(now - startTime)
//并且更新最后一次回调的时间
lastTick = now;
}
}
}
类:
function Timeline(interval) {
//当前动画的状态。
this.state = STATE_INITIAL;
//当前动画进行时间。
this.startTime = 0;
//每次回调的时间间隔。
this.interval = DEFAULT_INTERVAL;
//setTimeout的ID
this.animationHandler = 0;
//动画开始了多久,暂停的时候储存留待再次开始
this.dur = 0;
}
/**
* 动画停止
*/
Timeline.prototype.stop = function (interval) {
if (this.state !== STATE_START) {
return
}
this.state = STATE_STOP;
//如果动画已经开始了,那么记录一下已经开始多久了。
if (this.stateTime) {
this.dur = +new Date() - this.startTime
}
cancelAnimationFrame(this.animationHandler)
}
/**
* 重新播放动画
*/
Timeline.prototype.restart = function (interval) {
if (this.state !== STATE_START) {
return
}
if (!this.dur || this.interval) {
return
}
this.state = STATE_START
//从停止那一刻算起,开始动画
startTimeline(this, +new Date() - this.dur)
}
这里是定义具体执行异步函数的方法。
首先是处理window.requestAnimationFrame 和window.cancelAnimationFrame的兼容性问题。这里使用的自执行函数,通过 || 返回经过类型转换后为true的值。如果不支持这个方法,就用setTimeout,如果用setTimeout,默认的时间间隔是1000/60毫秒。
代码:
var DEFAULT_INTERVAL = 1000/60
//requestAnimationFrame每17毫秒会刷新一次。
var requestAnimationFrame = (function () {
//浏览器兼容
return window.requestAnimationFrame ||
window.webketRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
//如果不支持,则用setTimeout ,默认为 1000/60 毫秒后
function (callback) {
return window.setTimeout(callback(),callback.interval || DEFAULT_INTERVAL)
}
})()
var cancelAnimationFrame = (function () {
return window.cancelAnimationFrame ||
window.webketCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
//如果不支持,则用setTimeout ,默认为 1000/60 毫秒后
function (id) {
return window.clearTimeout(id)
}
})()
接下来定义class。