chnobli 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -10
- package/package.json +9 -3
- package/src/animation/animation.js +203 -0
- package/src/animation/property.js +191 -0
- package/src/animation/public.js +53 -0
- package/src/animator.js +185 -0
- package/src/chnobli.js +64 -0
- package/src/scroll/event.js +41 -0
- package/src/scroll/public.js +17 -0
- package/src/scroll/scroll.js +169 -0
- package/src/stagger/stagger.js +45 -0
- package/src/timeline/public.js +154 -0
- package/src/timeline/timeline.js +250 -0
- package/src/timing/ease.js +16 -0
- package/src/timing/easing.js +292 -0
- package/src/timing/ticker.js +114 -0
- package/src/timing/timing.js +195 -0
- package/src/utils/events.js +35 -0
- package/src/utils/internal.js +7 -0
- package/src/utils/motionpath.js +44 -0
- package/src/utils/target.js +164 -0
- package/src/utils/utils.js +55 -0
- package/src/utils/value.js +38 -0
- package/LICENSE-APACHE +0 -201
- /package/{LICENSE-MIT → LICENSE.md} +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { takeProp } from '../utils/internal.js';
|
|
2
|
+
import Timing, {
|
|
3
|
+
parseEase, parseRepeat, parseAlternate, parseReversed,
|
|
4
|
+
STATE_RUNNING
|
|
5
|
+
} from '../timing/timing.js';
|
|
6
|
+
import Ticker from '../timing/ticker.js';
|
|
7
|
+
import Animation from '../animation/animation.js';
|
|
8
|
+
|
|
9
|
+
export default class Timeline {
|
|
10
|
+
/*
|
|
11
|
+
{
|
|
12
|
+
ease,
|
|
13
|
+
repeat: -1 - x,
|
|
14
|
+
alternate
|
|
15
|
+
}
|
|
16
|
+
*/
|
|
17
|
+
constructor(props = {}) {
|
|
18
|
+
const nProps = {
|
|
19
|
+
duration: 1000,
|
|
20
|
+
ease: parseEase(takeProp(props, 'ease', null)),
|
|
21
|
+
repeat: parseRepeat(takeProp(props, 'repeat', false)),
|
|
22
|
+
alternate: parseAlternate(takeProp(props, 'alternate', true)),
|
|
23
|
+
reversed: parseReversed(takeProp(props, 'reversed', false))
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
this.timing = new Timing(nProps);
|
|
27
|
+
this.ticker = Ticker.global();
|
|
28
|
+
|
|
29
|
+
// { type: label|animation, value: {}, offset, start: x, end: y, render }
|
|
30
|
+
this.entries = [];
|
|
31
|
+
|
|
32
|
+
this._initialized = false;
|
|
33
|
+
this._renderQueue = null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// relative represents the point which the offset should be taken
|
|
37
|
+
// if relative 1 is done the offset will be taken from the previous - 1
|
|
38
|
+
add(targets, props, offset = null, relative = 0) {
|
|
39
|
+
const animation = new Animation(targets, this.ticker, props);
|
|
40
|
+
|
|
41
|
+
if (!animation.isFinite())
|
|
42
|
+
throw new Error('the animation needs to be finite');
|
|
43
|
+
|
|
44
|
+
this.entries.push({
|
|
45
|
+
type: 'animation',
|
|
46
|
+
value: animation,
|
|
47
|
+
offset: new Offset(offset),
|
|
48
|
+
relativeOffset: relative
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
label(label, offset = null) {
|
|
55
|
+
this.entries.push({
|
|
56
|
+
type: 'label',
|
|
57
|
+
value: label,
|
|
58
|
+
offset: new Offset(offset),
|
|
59
|
+
relativeOffset: 0
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
advance(change) {
|
|
66
|
+
this.timing.advance(change);
|
|
67
|
+
|
|
68
|
+
this._updateTimings();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
seek(pos) {
|
|
72
|
+
this.timing.seek(pos);
|
|
73
|
+
|
|
74
|
+
this._updateTimings();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
init() {
|
|
78
|
+
if (this._initialized)
|
|
79
|
+
return;
|
|
80
|
+
this._initialized = true;
|
|
81
|
+
|
|
82
|
+
let duration = 0;
|
|
83
|
+
|
|
84
|
+
const labels = {};
|
|
85
|
+
|
|
86
|
+
let i = -1;
|
|
87
|
+
for (const entry of this.entries) {
|
|
88
|
+
i++;
|
|
89
|
+
let offset = entry.offset;
|
|
90
|
+
|
|
91
|
+
if (offset.type === 'label') {
|
|
92
|
+
if (!(offset.value in labels))
|
|
93
|
+
throw new Error('could not find label ' + offset.value);
|
|
94
|
+
|
|
95
|
+
offset = new Offset(labels[offset.value]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const pos = this.entries[i - 1 - entry.relativeOffset]?.end ?? 0;
|
|
99
|
+
|
|
100
|
+
let start = offset.calculate(pos);
|
|
101
|
+
if (start < 0)
|
|
102
|
+
throw new Error('cannot go in the past start < 0');
|
|
103
|
+
|
|
104
|
+
let end = start;
|
|
105
|
+
if (entry.type === 'animation')
|
|
106
|
+
end += entry.value.duration;
|
|
107
|
+
|
|
108
|
+
if (entry.type === 'label')
|
|
109
|
+
labels[entry.value] = start;
|
|
110
|
+
|
|
111
|
+
entry.start = start;
|
|
112
|
+
entry.end = end;
|
|
113
|
+
|
|
114
|
+
duration = Math.max(end, duration);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.timing.setDuration(duration);
|
|
118
|
+
|
|
119
|
+
this._initAnimations();
|
|
120
|
+
|
|
121
|
+
// console.log(this.entries.map(e => e.value._props[0]));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
_initAnimations() {
|
|
125
|
+
// we don't won't to have a reversed timing
|
|
126
|
+
const reversed = this.timing.reversed;
|
|
127
|
+
this.timing.reversed = false;
|
|
128
|
+
|
|
129
|
+
// now initialize all animtaions
|
|
130
|
+
const startOrdered = this.entries.filter(e => e.type === 'animation');
|
|
131
|
+
startOrdered.sort((a, b) => a.start - b.start);
|
|
132
|
+
|
|
133
|
+
for (let i = 0; i < startOrdered.length; i++) {
|
|
134
|
+
const entry = startOrdered[i];
|
|
135
|
+
|
|
136
|
+
this.timing.seek(entry.start / this.timing.iterDuration);
|
|
137
|
+
|
|
138
|
+
const pos = this.timing.position * this.timing.iterDuration;
|
|
139
|
+
|
|
140
|
+
// seek all previous and render
|
|
141
|
+
for (let y = 0; y < i; y++) {
|
|
142
|
+
const prevEntry = startOrdered[y];
|
|
143
|
+
const prevAnimation = prevEntry.value;
|
|
144
|
+
|
|
145
|
+
const p = (pos - prevEntry.start) / prevAnimation.duration;
|
|
146
|
+
|
|
147
|
+
prevAnimation.seek(p);
|
|
148
|
+
prevAnimation.render();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
entry.value.init();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.timing.seek(-1);
|
|
155
|
+
this.timing.reversed = reversed;
|
|
156
|
+
startOrdered.forEach(e => {
|
|
157
|
+
e.value.seek(-1);
|
|
158
|
+
e.value.render();
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
render() {
|
|
163
|
+
// the rendering order needs to be as follows
|
|
164
|
+
// upcoming
|
|
165
|
+
// passed
|
|
166
|
+
// active
|
|
167
|
+
|
|
168
|
+
for (const animation of this._renderQueue.upcoming) {
|
|
169
|
+
animation.render();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const animation of this._renderQueue.passed) {
|
|
173
|
+
animation.render();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
for (const animation of this._renderQueue.active) {
|
|
177
|
+
animation.render();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
_updateTimings() {
|
|
182
|
+
this._renderQueue = {
|
|
183
|
+
upcoming: [],
|
|
184
|
+
passed: [],
|
|
185
|
+
active: []
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const pos = this.timing.position * this.timing.iterDuration;
|
|
189
|
+
|
|
190
|
+
for (const entry of this.entries) {
|
|
191
|
+
if (entry.type !== 'animation')
|
|
192
|
+
continue;
|
|
193
|
+
|
|
194
|
+
const animation = entry.value;
|
|
195
|
+
|
|
196
|
+
const p = (pos - entry.start) / animation.duration;
|
|
197
|
+
|
|
198
|
+
const prevState = animation.timing.state;
|
|
199
|
+
|
|
200
|
+
animation.seek(p);
|
|
201
|
+
|
|
202
|
+
if (p > 1) {
|
|
203
|
+
this._renderQueue.passed.push(animation);
|
|
204
|
+
} else if (p < 0) {
|
|
205
|
+
this._renderQueue.upcoming.push(animation);
|
|
206
|
+
} else {
|
|
207
|
+
this._renderQueue.active.push(animation);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class Offset {
|
|
215
|
+
constructor(offset = null) {
|
|
216
|
+
this.type = 'none';
|
|
217
|
+
|
|
218
|
+
if (typeof offset === 'number') {
|
|
219
|
+
this.type = 'absolute';
|
|
220
|
+
this.value = offset;
|
|
221
|
+
} else if (typeof offset === 'string') {
|
|
222
|
+
if (offset.startsWith('-=')) {
|
|
223
|
+
this.type = 'sub';
|
|
224
|
+
this.value = parseFloat(offset.substring(2));
|
|
225
|
+
} else if (offset.startsWith('+=')) {
|
|
226
|
+
this.type = 'add';
|
|
227
|
+
this.value = parseFloat(offset.substring(2));
|
|
228
|
+
} else {
|
|
229
|
+
this.type = 'label';
|
|
230
|
+
this.value = offset;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
calculate(pos) {
|
|
236
|
+
if (this.type === 'none')
|
|
237
|
+
return pos;
|
|
238
|
+
|
|
239
|
+
if (this.type === 'absolute')
|
|
240
|
+
return this.value;
|
|
241
|
+
|
|
242
|
+
if (this.type === 'sub')
|
|
243
|
+
return pos - this.value;
|
|
244
|
+
|
|
245
|
+
if (this.type === 'add')
|
|
246
|
+
return pos + this.value;
|
|
247
|
+
|
|
248
|
+
throw new Error('cannot calculate for type ' + this.type);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default class Ease {
|
|
2
|
+
constructor(prop) {
|
|
3
|
+
// parse prop
|
|
4
|
+
if (prop !== null && typeof prop !== 'function')
|
|
5
|
+
throw new Error('ease needs to be a function');
|
|
6
|
+
|
|
7
|
+
this.fn = prop;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
apply(t) {
|
|
11
|
+
if (this.fn === null)
|
|
12
|
+
return t;
|
|
13
|
+
|
|
14
|
+
return this.fn(t);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Adapted from https://github.com/sveltejs/svelte
|
|
3
|
+
Distributed under MIT License https://github.com/sveltejs/svelte/blob/main/LICENSE.md
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import bezierEasing from 'bezier-easing';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {number} t
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
export function linear(t) {
|
|
13
|
+
return t;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {number} t
|
|
18
|
+
* @returns {number}
|
|
19
|
+
*/
|
|
20
|
+
export function backInOut(t) {
|
|
21
|
+
const s = 1.70158 * 1.525;
|
|
22
|
+
if ((t *= 2) < 1) return 0.5 * (t * t * ((s + 1) * t - s));
|
|
23
|
+
return 0.5 * ((t -= 2) * t * ((s + 1) * t + s) + 2);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {number} t
|
|
28
|
+
* @returns {number}
|
|
29
|
+
*/
|
|
30
|
+
export function backIn(t) {
|
|
31
|
+
const s = 1.70158;
|
|
32
|
+
return t * t * ((s + 1) * t - s);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {number} t
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
export function backOut(t) {
|
|
40
|
+
const s = 1.70158;
|
|
41
|
+
return --t * t * ((s + 1) * t + s) + 1;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {number} t
|
|
46
|
+
* @returns {number}
|
|
47
|
+
*/
|
|
48
|
+
export function bounceOut(t) {
|
|
49
|
+
const a = 4.0 / 11.0;
|
|
50
|
+
const b = 8.0 / 11.0;
|
|
51
|
+
const c = 9.0 / 10.0;
|
|
52
|
+
const ca = 4356.0 / 361.0;
|
|
53
|
+
const cb = 35442.0 / 1805.0;
|
|
54
|
+
const cc = 16061.0 / 1805.0;
|
|
55
|
+
const t2 = t * t;
|
|
56
|
+
return t < a
|
|
57
|
+
? 7.5625 * t2
|
|
58
|
+
: t < b
|
|
59
|
+
? 9.075 * t2 - 9.9 * t + 3.4
|
|
60
|
+
: t < c
|
|
61
|
+
? ca * t2 - cb * t + cc
|
|
62
|
+
: 10.8 * t * t - 20.52 * t + 10.72;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {number} t
|
|
67
|
+
* @returns {number}
|
|
68
|
+
*/
|
|
69
|
+
export function bounceInOut(t) {
|
|
70
|
+
return t < 0.5 ? 0.5 * (1.0 - bounceOut(1.0 - t * 2.0)) : 0.5 * bounceOut(t * 2.0 - 1.0) + 0.5;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {number} t
|
|
75
|
+
* @returns {number}
|
|
76
|
+
*/
|
|
77
|
+
export function bounceIn(t) {
|
|
78
|
+
return 1.0 - bounceOut(1.0 - t);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {number} t
|
|
83
|
+
* @returns {number}
|
|
84
|
+
*/
|
|
85
|
+
export function circInOut(t) {
|
|
86
|
+
if ((t *= 2) < 1) return -0.5 * (Math.sqrt(1 - t * t) - 1);
|
|
87
|
+
return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @param {number} t
|
|
92
|
+
* @returns {number}
|
|
93
|
+
*/
|
|
94
|
+
export function circIn(t) {
|
|
95
|
+
return 1.0 - Math.sqrt(1.0 - t * t);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {number} t
|
|
100
|
+
* @returns {number}
|
|
101
|
+
*/
|
|
102
|
+
export function circOut(t) {
|
|
103
|
+
return Math.sqrt(1 - --t * t);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {number} t
|
|
108
|
+
* @returns {number}
|
|
109
|
+
*/
|
|
110
|
+
export function cubicInOut(t) {
|
|
111
|
+
return t < 0.5 ? 4.0 * t * t * t : 0.5 * Math.pow(2.0 * t - 2.0, 3.0) + 1.0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {number} t
|
|
116
|
+
* @returns {number}
|
|
117
|
+
*/
|
|
118
|
+
export function cubicIn(t) {
|
|
119
|
+
return t * t * t;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {number} t
|
|
124
|
+
* @returns {number}
|
|
125
|
+
*/
|
|
126
|
+
export function cubicOut(t) {
|
|
127
|
+
const f = t - 1.0;
|
|
128
|
+
return f * f * f + 1.0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param {number} t
|
|
133
|
+
* @returns {number}
|
|
134
|
+
*/
|
|
135
|
+
export function elasticInOut(t) {
|
|
136
|
+
return t < 0.5
|
|
137
|
+
? 0.5 * Math.sin(((+13.0 * Math.PI) / 2) * 2.0 * t) * Math.pow(2.0, 10.0 * (2.0 * t - 1.0))
|
|
138
|
+
: 0.5 *
|
|
139
|
+
Math.sin(((-13.0 * Math.PI) / 2) * (2.0 * t - 1.0 + 1.0)) *
|
|
140
|
+
Math.pow(2.0, -10.0 * (2.0 * t - 1.0)) +
|
|
141
|
+
1.0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @param {number} t
|
|
146
|
+
* @returns {number}
|
|
147
|
+
*/
|
|
148
|
+
export function elasticIn(t) {
|
|
149
|
+
return Math.sin((13.0 * t * Math.PI) / 2) * Math.pow(2.0, 10.0 * (t - 1.0));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {number} t
|
|
154
|
+
* @returns {number}
|
|
155
|
+
*/
|
|
156
|
+
export function elasticOut(t) {
|
|
157
|
+
return Math.sin((-13.0 * (t + 1.0) * Math.PI) / 2) * Math.pow(2.0, -10.0 * t) + 1.0;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {number} t
|
|
162
|
+
* @returns {number}
|
|
163
|
+
*/
|
|
164
|
+
export function expoInOut(t) {
|
|
165
|
+
return t === 0.0 || t === 1.0
|
|
166
|
+
? t
|
|
167
|
+
: t < 0.5
|
|
168
|
+
? +0.5 * Math.pow(2.0, 20.0 * t - 10.0)
|
|
169
|
+
: -0.5 * Math.pow(2.0, 10.0 - t * 20.0) + 1.0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {number} t
|
|
174
|
+
* @returns {number}
|
|
175
|
+
*/
|
|
176
|
+
export function expoIn(t) {
|
|
177
|
+
return t === 0.0 ? t : Math.pow(2.0, 10.0 * (t - 1.0));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @param {number} t
|
|
182
|
+
* @returns {number}
|
|
183
|
+
*/
|
|
184
|
+
export function expoOut(t) {
|
|
185
|
+
return t === 1.0 ? t : 1.0 - Math.pow(2.0, -10.0 * t);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @param {number} t
|
|
190
|
+
* @returns {number}
|
|
191
|
+
*/
|
|
192
|
+
export function quadInOut(t) {
|
|
193
|
+
t /= 0.5;
|
|
194
|
+
if (t < 1) return 0.5 * t * t;
|
|
195
|
+
t--;
|
|
196
|
+
return -0.5 * (t * (t - 2) - 1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @param {number} t
|
|
201
|
+
* @returns {number}
|
|
202
|
+
*/
|
|
203
|
+
export function quadIn(t) {
|
|
204
|
+
return t * t;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @param {number} t
|
|
209
|
+
* @returns {number}
|
|
210
|
+
*/
|
|
211
|
+
export function quadOut(t) {
|
|
212
|
+
return -t * (t - 2.0);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param {number} t
|
|
217
|
+
* @returns {number}
|
|
218
|
+
*/
|
|
219
|
+
export function quartInOut(t) {
|
|
220
|
+
return t < 0.5 ? +8.0 * Math.pow(t, 4.0) : -8.0 * Math.pow(t - 1.0, 4.0) + 1.0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @param {number} t
|
|
225
|
+
* @returns {number}
|
|
226
|
+
*/
|
|
227
|
+
export function quartIn(t) {
|
|
228
|
+
return Math.pow(t, 4.0);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* @param {number} t
|
|
233
|
+
* @returns {number}
|
|
234
|
+
*/
|
|
235
|
+
export function quartOut(t) {
|
|
236
|
+
return Math.pow(t - 1.0, 3.0) * (1.0 - t) + 1.0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* @param {number} t
|
|
241
|
+
* @returns {number}
|
|
242
|
+
*/
|
|
243
|
+
export function quintInOut(t) {
|
|
244
|
+
if ((t *= 2) < 1) return 0.5 * t * t * t * t * t;
|
|
245
|
+
return 0.5 * ((t -= 2) * t * t * t * t + 2);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {number} t
|
|
250
|
+
* @returns {number}
|
|
251
|
+
*/
|
|
252
|
+
export function quintIn(t) {
|
|
253
|
+
return t * t * t * t * t;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @param {number} t
|
|
258
|
+
* @returns {number}
|
|
259
|
+
*/
|
|
260
|
+
export function quintOut(t) {
|
|
261
|
+
return --t * t * t * t * t + 1;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @param {number} t
|
|
266
|
+
* @returns {number}
|
|
267
|
+
*/
|
|
268
|
+
export function sineInOut(t) {
|
|
269
|
+
return -0.5 * (Math.cos(Math.PI * t) - 1);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* @param {number} t
|
|
274
|
+
* @returns {number}
|
|
275
|
+
*/
|
|
276
|
+
export function sineIn(t) {
|
|
277
|
+
const v = Math.cos(t * Math.PI * 0.5);
|
|
278
|
+
if (Math.abs(v) < 1e-14) return 1;
|
|
279
|
+
else return 1 - v;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* @param {number} t
|
|
284
|
+
* @returns {number}
|
|
285
|
+
*/
|
|
286
|
+
export function sineOut(t) {
|
|
287
|
+
return Math.sin((t * Math.PI) / 2);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function cubicBezier(x1, y1, x2, y2) {
|
|
291
|
+
return bezierEasing(x1, y1, x2, y2);
|
|
292
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import Value from '../utils/value.js';
|
|
2
|
+
import { newTarget } from '../utils/target.js';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export default class Ticker {
|
|
6
|
+
constructor() {
|
|
7
|
+
this._listeners = new Set;
|
|
8
|
+
this._targets = new GlobalTargets;
|
|
9
|
+
|
|
10
|
+
this.running = false;
|
|
11
|
+
|
|
12
|
+
this._previousTick = null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static global() {
|
|
16
|
+
if (typeof window === 'undefined')
|
|
17
|
+
return null;
|
|
18
|
+
|
|
19
|
+
if (typeof window.chnobliTicker === 'undefined')
|
|
20
|
+
window.chnobliTicker = new Ticker;
|
|
21
|
+
return window.chnobliTicker;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
add(fn) {
|
|
25
|
+
this._listeners.add(fn);
|
|
26
|
+
|
|
27
|
+
if (!this.running) {
|
|
28
|
+
this.running = true;
|
|
29
|
+
requestAnimationFrame(a => this._tick(a));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
remove: () => {
|
|
34
|
+
this.remove(fn);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
remove(fn) {
|
|
40
|
+
this._listeners.delete(fn);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_tick(elapsed) {
|
|
44
|
+
if (this._listeners.size === 0) {
|
|
45
|
+
this.running = false;
|
|
46
|
+
this._previousTick = null;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (this._previousTick === null)
|
|
51
|
+
this._previousTick = elapsed;
|
|
52
|
+
|
|
53
|
+
let change = elapsed - this._previousTick;
|
|
54
|
+
// lagSmoothing
|
|
55
|
+
if (change > 500) {
|
|
56
|
+
console.log('ticker lagged');
|
|
57
|
+
change = 33;
|
|
58
|
+
}
|
|
59
|
+
this._previousTick = elapsed;
|
|
60
|
+
|
|
61
|
+
// const changes = new PropertyChanges;
|
|
62
|
+
|
|
63
|
+
for (const fn of this._listeners) {
|
|
64
|
+
fn(change, {
|
|
65
|
+
// changes,
|
|
66
|
+
remove: () => this.remove(fn)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this._targets.apply();
|
|
71
|
+
|
|
72
|
+
requestAnimationFrame(a => this._tick(a));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// class PropertyChanges {
|
|
77
|
+
// constructor() {
|
|
78
|
+
// this._targets = new Map;
|
|
79
|
+
// }
|
|
80
|
+
|
|
81
|
+
// // target is expected to be an html element
|
|
82
|
+
// get(target) {
|
|
83
|
+
|
|
84
|
+
// }
|
|
85
|
+
// }
|
|
86
|
+
|
|
87
|
+
// class TargetChanges {
|
|
88
|
+
// constructor() {
|
|
89
|
+
// // x, y, rotate, skew, scale
|
|
90
|
+
// this.transform = {};
|
|
91
|
+
// }
|
|
92
|
+
// }
|
|
93
|
+
|
|
94
|
+
class GlobalTargets {
|
|
95
|
+
constructor() {
|
|
96
|
+
this._targets = new Map;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
register(target) {
|
|
100
|
+
let storedTarget = this._targets.get(target);
|
|
101
|
+
if (!storedTarget) {
|
|
102
|
+
storedTarget = newTarget(target);
|
|
103
|
+
this._targets.set(target, storedTarget);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return storedTarget;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
apply() {
|
|
110
|
+
for (const target of this._targets.values()) {
|
|
111
|
+
target.apply();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|