-
Notifications
You must be signed in to change notification settings - Fork 6
/
animation.js
70 lines (60 loc) · 1.71 KB
/
animation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Animation {
constructor(schedule, rawInfo, spec) {
this.schedule = schedule;
this.moments = this.schedule.moments;
this.status = "ready";
this.spec = spec;
this.logs = [];
this._queue = [];
this.rawInfo = rawInfo;
}
log(timestamp, message, info) {
if (typeof message === "string" && typeof timestamp === "number") {
this.logs.push({
timestamp,
message,
info
});
}
return this.logs;
}
async play(targetElm) {
this.status = "playing";
// get moments and sort by sTime
const { moments } = this;
const globalSTime = new Date();
this._start(moments[0].starting, targetElm);
this.log(new Date() - globalSTime, "0-th moment");
for (let i = 1; i < moments.length; i++) {
const moment = moments[i];
await this._end(moment).then(() => {
const delay = Math.max(moment.time - (new Date() - globalSTime), 0);
return new Promise(resolve => setTimeout(() => resolve(), delay));
});
this._start(moment.starting, targetElm);
this.log(new Date() - globalSTime, `${i}-th moment`);
if (i === moments.length - 1) {
this.status = "ready";
return;
}
}
}
_start(steps, targetElm) {
steps.forEach(step => {
this._queue.push({
sTime: step.sTime,
eTime: step.eTime,
step,
result: step.template(this.rawInfo, step, targetElm) // contains the promise
});
});
}
async _end(moment) {
const { time } = moment;
const workingSteps = this._queue.filter(item => item.eTime === time);
for (let i = 0; i < workingSteps.length; i++) {
await workingSteps[i].result;
}
}
}
export { Animation };