2021SC@SDUSC
首先是requestanimationframe,兼容多种运行环境的 requestAnimationFrame 方法。 有两个重要的地方会依赖此方法:1.元素的渲染机制,在 Painter 类中会调用 2.元素的动画效果,在 Animation 类中会调用。这个是直接调用的,只要准备好更新屏幕上的动画,就应该调用此方法。这将要求在浏览器执行下一次重绘之前调用您的动画函数。回调方法传递一个参数 a DOMHighResTimeStamp ,它指示当前时间(基于自时间origin以来的毫秒数)。当多个排队的回调requestAnimationFrame()
开始在单个帧中触发时,每个回调都会收到相同的时间戳,即使在计算每个前一个回调的工作负载期间已经过了时间此时间戳是一个十进制数,以毫秒为单位,但最小精度为 1 毫秒(1000 微秒)。
在网上查找得知
requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
var _default = typeof window !== 'undefined' && (window.requestAnimationFrame && window.requestAnimationFrame.bind(window) || window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window) || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame) || function (func) {
setTimeout(func, 16); // 1000ms/60,每秒60帧,每帧约16ms
};
在requestAnimationFrame中,有类似clearInterval这样的类似方法——cancelAnimationFrame(),cancelAnimationFrame()接收一个参数 requestAnimationFrame默认返回一个id,cancelAnimationFrame只需要传入这个id就可以停止了。默认情况下,requestAnimationFrame执行频率是1000/60,大概是16ms多执一次。
接着是track(轨道),其与元素(Element)上可以用来进行动画的属性一一对应。 元素上存在很多种属性,在动画过程中,可能会有多种属性同时发生变化, 每一种属性天然成为一条动画轨道,把这些轨道上的变化过程封装在 Track 类中。
function Track(options) {
_classCallCheck(this, Track);
this.element = options.element;
this.path = options.path;
this.delay = options.delay;
this.currentValue = null;
this.isFinished = false;
this.keyframes = [];
this.timeline;
}
首先是自然是定义各个属性值的行为,属性的种类与元素上的属性一一对应。
_createClass(Track, [{
key: "addKeyFrame",
value: function addKeyFrame(kf) {
this.keyframes.push(kf);
}
然后就是向轨道中添加关键帧。其中kf数据结构为 {time:0,value:0}。
{
key: "nextFrame",
value: function nextFrame(time, delta) {
if (!this.timeline) {
return;
}
var result = this.timeline.nextFrame(time, delta);
if (dataUtil.isString(result) && result === 'destroy') {
this.isFinished = true;
} // console.log(`result=${result}`);
return result;
}
这里是进入下一帧,time是当前时间而delta是时间偏移量,调用了timeliness中的对应部分。
{
key: "fire",
value: function fire(eventType, arg) {
this.timeline.fire(eventType, arg);
}
当获得关键词为“fire”时,就会执行触发事件的操作。
key: "start",
value: function start() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var easing = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var forceAnimate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var options = this._parseKeyFrames(easing, this.path, loop, forceAnimate);
if (!options) {
return null;
}
var timeline = new Timeline(options);
this.timeline = timeline;
}
当关键词为“start”时,轨道会执行动画开始操作,这时会判定动画是否循环,是够调用缓动引擎以及在特定情况下是否需要强制开启动画,当然,在this._parseKeyFrames中如果传入的参数不正确,则无法构造实例。