2021SC@SDUSC
一、总述
前面说过了animation(动画)包中的几个类大题都是完成什么功能的,接下来就详细的对代码进行一些分析,这一篇主要是里面的Animatable和AnimationProcess两个JS文件,其中AnimationProcess内容较多,会分开来讲,这里主要开个头。
二、Animatable.js
首先是animatable,动画抽象类。任何需要动画功能的类都可以 mixin 此实现。要明确,混入Animatable 的类必须同时混入 Eventful ,因为动画过程中需要使用事件机制。这个类的功能包括了创建AnimationProcess实例,从对象上获取属性的路径,例如 'a.b.c',以及动画是否循环播放,动画的停止和删除等功能。所以再分析中绝大部分功能都是通过调用后面的AnimationProcess来实现的。
首先
var Animatable = function Animatable() {
this.animationProcessList = [];
};
这是开始对动画进行处理,为了方便后面对动画的处理,这里选择生成当前元素上的动画过程列表。以列表中列表中元素的方式与后面时间轴对应以及进行调整。
然后是
animate: function () {
let animatable = this;
let animationProcess = new AnimationProcess(animatable);
animationProcess.on('done', () => {
animatable.removeAnimationProcess(animationProcess);
});
animationProcess.on('stop', () => {
animatable.removeAnimationProcess(animationProcess);
});
animatable.animationProcessList.push(animationProcess);
if (animatable.__qr) {
animatable.__qr.globalAnimationMgr.addAnimatable(animatable);
}
return animationProcess;
},
这里进行了自定义animate动画方法中的function(运转),也就是动画的的过程。先是创建了一个新的AnimationProcess实例,确保后面的调用,然后调用done方法进行动画的开始,{String} path从对象上获取属性的路径,例如 'a.b.c',然后就是停止的stop和通过调用qrenderer.animation.AnimationProcess(qr)来判断动画是否循环播放。
接下来就是
stopAnimation: function (forwardToLast = false) {
this.animationProcessList.forEach(ap => {
ap.stop(forwardToLast);
});
this.animationProcessList.length = 0;
return this;
},
这里对停止进行了更深层的定义,主要目的在于利用forwardToLast来进行判断,动画在停止之后是否需要强制移动到最后一帧。
最后,当动画执行完或者手动进行停止之后
removeAnimationProcess(animationProcess) {
let index = this.animationProcessList.indexOf(animationProcess);
if (index >= 0) {
this.animationProcessList.splice(index, 1);
}
},
删除动画过程,也就是删除AnimationProcess实例。
三、AnimationProcess.js
AnimationProcess 表示一次完整的动画过程,每一个元素(Element)中都有一个列表,用来存储本实例上的所有动画过程。
列表中的动画过程按照顺序获得运行机会,在特定的时间点上只有一个 AnimationProcess 处于运行状态,系统中的所有动画过程都由 GlobalAnimationMgr 类进行调度。 AnimationProcess 运行完成之后会触发一个 done 事件,Element 实例在收到 done 事件之后,会把当前的动画过程从列表中删除。 如果 Element 实例的动画过程列表中存在多个实例,其中某个过程是无限循环运行的,那么后续所有动画过程都不会获得到运行机会。这个类的功能在于调用其他的动画组件,作为总领的功能,以此来保证动画的播放。
第一部分是
constructor(element) {
this.element = element;
this._trackCacheMap = new Map();
this._delay = 0;
this._running = false;
this._paused = false;
classUtil.inheritProperties(this, Eventful, this.options);
}
这里是定义了动画所需的一系列基本元素,包括
1.trackcachemap
可以被叫做轨迹缓存映射。canvas动画中的缓存映射,对一个矢量图动画,开启位图缓存能大大提高运行效率。所谓开启位图缓存,其实要自己动手,先创建一个临时canvas,然后把矢量图绘制到这个canvas上,到了实际绘制时,直接把这个临时canvas拷贝到真正canvas上。而位图拷贝的速度是非常快的,比重新绘制矢量图要快很多。
2.daily
动画的延迟系统,CSS中动画的延迟属性,这个控制着动画是否会延迟播放
3.running和paused
很明显,这是动画的播放的暂停属性,二者的布尔值是不同的,这两个值决定了一个动画实例的实时状态是播放还是停止