那么我们就要给它插手一个终止条件。我们这个条件判定应该放在执行 animation.run 之前,假如当前的时间已经高出了动画的时长。这个时候我们就需要遏制执动作画了。
首先我们需要改革 start 函数中的 animation 轮回挪用,在执行 animation.run 之前插手一个条件判定。这里我们需要判定假如当前时间是否已经大于 animation 中的 duration 动画时长。假如创立动画就可以遏制执行了,而且需要把这个 animation 移除 ANIMATIONS 行列。
export class Timeline { constructor() { this[ANIMATIONS] = new Set(); } start() { let startTime = Date.now(); this[TICK] = () => { let t = Date.now() - startTime; for (let animation of this[ANIMATIONS]) { if (t > animation.duration) { this[ANIMATIONS].delete(animation); } animation.run(t); } requestAnimationFrame(this[TICK]); }; this[TICK](); } pause() {} resume() {} reset() {} add(animation) { this[ANIMATIONS].add(animation); } }
就这样我们就插手了遏制条件了,并没有什么巨大的逻辑。最后我们在 main.js 中,改一下 Animation 的第一个参数。在传入的工具中插手一个 setter,这样我们就可以让我们的 animation 打印出时间。这样利便我们调试。
tl.add( new Animation( { set a(a) { console.log(a); }, }, 'property', 0, 100, 1000, null ) );
我们看到动画确实是遏制了,可是照旧有一个问题。我们配置的 duration 动画时长是到 1000 毫秒,可是这里最后一个是 1002,明明超出了我们的动画时长。
所以我们是需要在碰着动画竣事条件的时候,需要给 animation 传入它的 duration(动画时长的值)。这里我们就应该这样写:
start() { let startTime = Date.now(); this[TICK] = () => { let t = Date.now() - startTime; for (let animation of this[ANIMATIONS]) { let t0 = t; if (t > animation.duration) { this[ANIMATIONS].delete(animation); t0 = animation.duration; } animation.run(t0); } requestAnimationFrame(this[TICK]); }; this[TICK](); } pause() {} resume() {} reset() {} add(animation) { this[ANIMATIONS].add(animation); } }
这样我们劈头的 Timeline 和 Animation 的本领就成立起来了。
设计时间线的更新接下来我们就给这个 Timeline 插手更多的成果,让我们 Animation 这个库酿成真正的可用 。
在 CSS Animation 动画中,我们知道它有一个 duration(动画时长),其实同时还会有一个 delay(动画延迟时间)。
那么首先我们先来实验添加这个成果。
添加 Delay 属性支持在开拓傍边,当我们要去给原有的库添加成果。我们首先要思量的是 “找到一个公道的处所去添加这个成果”。
其实直观的来说,我们第一感受是会想把这个 delay 放入 Animation 类傍边,究竟这个成果属于动画的一部门。可是这里有一个更好的思路,就是把 delay 放到 Timeline 内里。
我们可以这么领略,一个动画的开始时间、终止时间、时间的节制,都是 Timeline 时间轴的相关事务,其实与 Animation 存眷的是有区此外。而 Animation 我以为更多是存眷动画的结果,运行等事务。
所以 delay 放在 Timeline 显然是越发符合的。
在 Timeline 的 add() 要领中,添加 animation 到行列的时候,给它添加一个 delay。
在添加 delay 这个逻辑的同时,我们还可以处理惩罚掉一个问题。就是当我们在添加 animation 动画到行列的时候,大概 Timeline 已经在执行了。这样其实我们插手动画的时候,我们动画的开始时间是差池的。
别的尚有一个问题,就是在 start 要领中,我们的 t 开始时间和 t0 其实不必然一致的。因为我们的 startTime 是可以按照 delay 被手动界说的。所以这一个值也是需要我们从头去编写一下逻辑的。
好,那么在实现我们的 delay 成果的同时,我们就可以把这两个因素都涵盖进去。
首先我们来插手一个 delay 参数:
export class Animation { constructor(object, property, startValue, endValue, duration, delay, timingFunction) { this.object = object; this.property = property; this.startValue = startValue; this.endValue = endValue; this.duration = duration; this.timingFunction = timingFunction; this.delay = delay; } run(time) { console.log(time); let range = this.endValue - this.startValue; this.object[this.property] = this.startValue + (range * time) / this.duration; } }
这里无非就是给 constructor 中,插手一个 delay 参数,而且存储到类的属性工具傍边。