-
Notifications
You must be signed in to change notification settings - Fork 1
/
animation.js
116 lines (95 loc) · 2.89 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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class Clip {
constructor(startFrame, endFrame, frameTime, direction) {
this.startFrame = startFrame;
this.endFrame = endFrame;
this.frameIndex = startFrame;
this.frameTime = frameTime;
this.time = 0;
this.direction = direction;
}
update(dt) {
this.time += dt;
if (this.time > this.frameTime) {
this.time = 0;
this.frameIndex += this.direction;
if (this.frameIndex > this.endFrame) {
this.frameIndex = this.startFrame;
} else if (this.frameIndex < this.startFrame) {
this.frameIndex = this.endFrame;
}
return true;
}
return false;
}
isLastFrame() {
return this.frameIndex === this.endFrame;
}
}
export default class Animation {
constructor(geometry, cols, rows) {
this.geometry = geometry;
this.frames = [];
const tw = 1 / cols;
const th = 1 / rows;
// Initialize frames (UVs)
for(let x1, x2, y1, y2 = 1; y2 > 0; y2 = y1) {
y1 = y2 - th;
for(x1 = 0; x1 < 1; x1 = x2) {
x2 = x1 + tw;
this.frames.push(
new Float32Array(
[
x1, y2, // 0, 1
x2, y2, // 1, 1
x1, y1, // 0, 0
x2, y1, // 1, 0
]
)
);
}
}
this.clips = {};
this.currentClip = null;
}
getClip(id) {
return this.clips[id];
}
create(id, startFrame = 0, endFrame = 0, frameTime = 0.5, direction = 1 ) {
this.clips[id] = new Clip(startFrame, endFrame, frameTime, direction);
return this;
}
remove(id) {
const clip = this.clips[id];
delete this.clips[id];
if(this.currentClip === clip) {
this.currentClip = null;
}
}
stop() {
this.currentClip = null;
}
play(id, callback) {
this.currentClip = this.clips[id];
this._update(this.currentClip.frameIndex);
this.callback = callback;
return this;
}
clear() {
this.clips = {};
this.currentClip = null;
}
update (dt) {
if(this.currentClip != null
&& this.currentClip.update(dt)) {
this._update(this.currentClip.frameIndex);
if(this.callback && this.currentClip.isLastFrame()) {
this.callback();
}
}
}
_update(index) { // Update UVs
const uv = this.geometry.attributes.uv;
uv.array = this.frames[index];
uv.needsUpdate = true;
}
}