@x1a0ma17x/zeppos-fx 2.0.3

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.
Files changed (46) hide show
  1. package/.z18n.config.json +11 -0
  2. package/License +21 -0
  3. package/README.md +190 -0
  4. package/README_zh-CN.md +196 -0
  5. package/example/app-side/i18n/en-US.po +2 -0
  6. package/example/app-side/index.js +13 -0
  7. package/example/app.js +10 -0
  8. package/example/app.json +52 -0
  9. package/example/assets/default.b/icon.png +0 -0
  10. package/example/assets/default.r/icon.png +0 -0
  11. package/example/assets/default.s/icon.png +0 -0
  12. package/example/global.d.ts +1 -0
  13. package/example/jsconfig.json +9 -0
  14. package/example/package.json +14 -0
  15. package/example/page/i18n/en-US.po +2 -0
  16. package/example/page/i18n/fr-FR.po +4 -0
  17. package/example/page/i18n/ru-RU.po +4 -0
  18. package/example/page/i18n/zh-CN.po +2 -0
  19. package/example/page/i18n/zh-TW.po +4 -0
  20. package/example/page/index.anim.js +37 -0
  21. package/example/page/index.js +19 -0
  22. package/example/page/index.r.layout.js +6 -0
  23. package/example/page/index.style.js +13 -0
  24. package/example/setting/i18n/en-US.po +2 -0
  25. package/example/setting/index.js +7 -0
  26. package/fx.js +623 -0
  27. package/fx.js.png +0 -0
  28. package/index.js +1 -0
  29. package/old/v1.0/fx.js +706 -0
  30. package/old/v1.0/smoothTimer.js +92 -0
  31. package/old/v2.0/fx.js +761 -0
  32. package/old/v2.0/zeppos_timer.js +64 -0
  33. package/package.json +25 -0
  34. package/src/example/app.js +10 -0
  35. package/src/example/app.json +46 -0
  36. package/src/example/assets/default.b/icon.png +0 -0
  37. package/src/example/assets/default.r/icon.png +0 -0
  38. package/src/example/assets/default.s/icon.png +0 -0
  39. package/src/example/global.d.ts +1 -0
  40. package/src/example/jsconfig.json +9 -0
  41. package/src/example/libs/fx.js +325 -0
  42. package/src/example/package.json +14 -0
  43. package/src/example/page/anim.js +60 -0
  44. package/src/example/page/i18n/en-US.po +2 -0
  45. package/src/example/page/index.js +13 -0
  46. package/src/example/page/index.r.layout.js +6 -0
package/fx.js ADDED
@@ -0,0 +1,623 @@
1
+ /**
2
+ * fx.js
3
+ * @description 一个用于在ZeppOS中提供简单动画的库
4
+ * @author XiaomaiTX
5
+ * @license MIT
6
+ * @repository https://github.com/XiaomaiTX/zeppos-fx
7
+ */
8
+
9
+ /**
10
+ * 弹跳函数辅助计算
11
+ * @param {number} x 输入值 [0,1]
12
+ * @returns {number} 计算结果
13
+ * @private
14
+ */
15
+ const bounceOut = function (x) {
16
+ const n1 = 7.5625;
17
+ const d1 = 2.75;
18
+
19
+ if (x < 1 / d1) {
20
+ return n1 * x * x;
21
+ } else if (x < 2 / d1) {
22
+ return n1 * (x -= 1.5 / d1) * x + 0.75;
23
+ } else if (x < 2.5 / d1) {
24
+ return n1 * (x -= 2.25 / d1) * x + 0.9375;
25
+ } else {
26
+ return n1 * (x -= 2.625 / d1) * x + 0.984375;
27
+ }
28
+ };
29
+
30
+ /**
31
+ * 动画类
32
+ */
33
+ export class Fx {
34
+ /**
35
+ * 创建动画实例
36
+ * @param {Object} options 配置选项
37
+ * @param {number} [options.delay=0] 延迟执行时间(毫秒)
38
+ * @param {number} [options.begin=0] 初始函数值
39
+ * @param {number} [options.end=100] 目标函数值
40
+ * @param {number} [options.x_start] 自定义函数的开始x坐标
41
+ * @param {number} [options.x_end] 自定义函数的结束x坐标
42
+ * @param {number} [options.time=1] 执行总时间(秒)
43
+ * @param {Function} [options.fx] 自定义x=>y动画函数
44
+ * @param {Function} options.func 每帧执行的回调函数,参数为当前值
45
+ * @param {number} [options.fps=60] 动画帧率
46
+ * @param {boolean} [options.enabled=true] 是否启用
47
+ * @param {number} [options.style=0] 内置预设类型,使用Fx.Styles中的值
48
+ * @param {Function} [options.onStop] 动画结束后的回调函数
49
+ */
50
+ constructor({
51
+ delay = 0,
52
+ begin = 0,
53
+ end = 100,
54
+ x_start,
55
+ x_end,
56
+ time = 1,
57
+ fx,
58
+ func,
59
+ fps = 60,
60
+ enabled = false,
61
+ style = 0,
62
+ onStop,
63
+ } = {}) {
64
+ this.begin = begin;
65
+ this.end = end;
66
+ this.fps = fps;
67
+ this.time = time;
68
+ this.per_clock = 1000 / fps;
69
+ this.delay = delay;
70
+ this.func = func;
71
+ this.onStop = onStop;
72
+ this.enabled = enabled;
73
+ this.timer = null;
74
+
75
+ if (fx) {
76
+ // 使用自定义函数
77
+ this.x_start = x_start != null ? x_start * 1.0 : 0;
78
+ this.x_end = x_end != null ? x_end * 1.0 : 1;
79
+ this.fx = fx;
80
+ this.speed = (this.x_end - this.x_start) / (time * fps);
81
+ } else {
82
+ // 使用预设样式
83
+ const styleName = this._getStyleName(style);
84
+ this.fx = (x) => Fx.Easing[styleName](x, begin, end, fps * time);
85
+ this.x_start = 0;
86
+ this.x_end = fps * time;
87
+ this.speed = 1;
88
+ }
89
+
90
+ this.x_now = this.x_start;
91
+
92
+ if (enabled) {
93
+ this.registerTimer();
94
+ }
95
+ }
96
+
97
+ /**
98
+ * 获取样式名称
99
+ * @param {number} styleValue 样式枚举值
100
+ * @returns {string} 样式名称
101
+ * @private
102
+ */
103
+ _getStyleName(styleValue) {
104
+ for (const key in Fx.Styles) {
105
+ if (Fx.Styles[key] === styleValue) {
106
+ return key;
107
+ }
108
+ }
109
+ return "LINEAR";
110
+ }
111
+ start() {
112
+ if (this.timer) {
113
+ this.timer.stop();
114
+ this.timer = null;
115
+ }
116
+ this.setEnable(true);
117
+ this.registerTimer();
118
+ }
119
+ stop() {
120
+ this.x_now = this.x_start;
121
+ if (this.timer) {
122
+ this.timer.stop();
123
+ this.timer = null;
124
+ }
125
+ this.setEnable(false);
126
+ }
127
+ pause() {
128
+ if (this.timer) {
129
+ this.timer.stop();
130
+ this.timer = null;
131
+ }
132
+ this.setEnable(false);
133
+ }
134
+ /**
135
+ * 重新开始动画
136
+ */
137
+ restart() {
138
+ this.x_now = this.x_start;
139
+ if (this.timer) {
140
+ this.timer.stop();
141
+ this.timer = null;
142
+ }
143
+ this.setEnable(true);
144
+ this.registerTimer();
145
+ }
146
+
147
+ /**
148
+ * 设置动画是否启用
149
+ * @param {boolean} enabled 是否启用
150
+ */
151
+ setEnable(enabled) {
152
+ if (this.enabled === enabled) return;
153
+
154
+ this.enabled = enabled;
155
+ if (enabled) {
156
+ this.registerTimer();
157
+ } else if (this.timer) {
158
+ this.timer.stop();
159
+ this.timer = null;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * 注册定时器
165
+ * @private
166
+ */
167
+ registerTimer() {
168
+ if (this.timer) {
169
+ this.timer.stop();
170
+ }
171
+
172
+ this.timer = new ZeppTimer(() => {
173
+ // 更新位置
174
+ this.x_now += this.speed;
175
+
176
+ // 检查是否完成
177
+ if (this.x_now >= this.x_end) {
178
+ this.x_now = this.x_end;
179
+ this.func(this.fx(this.x_end));
180
+
181
+ this.timer.stop();
182
+ this.timer = null;
183
+ this.enabled = false;
184
+ if (typeof this.onStop === "function") {
185
+ this.onStop();
186
+ }
187
+ return;
188
+ }
189
+
190
+ // 执行动画回调
191
+ this.func(this.fx(this.x_now));
192
+ }, this.per_clock);
193
+
194
+ this.timer.start();
195
+ }
196
+
197
+ /**
198
+ * 获取两个颜色的混合色
199
+ * @param {number} color1 初始颜色1 (6位十六进制)
200
+ * @param {number} color2 初始颜色2 (6位十六进制)
201
+ * @param {number} percentage 混合百分比 [0,1],越小越接近color1
202
+ * @returns {number} 混合后的颜色
203
+ */
204
+ static getMixColor(color1, color2, percentage) {
205
+ // 提取RGB分量
206
+ const r1 = (color1 >> 16) & 0xff;
207
+ const g1 = (color1 >> 8) & 0xff;
208
+ const b1 = color1 & 0xff;
209
+
210
+ const r2 = (color2 >> 16) & 0xff;
211
+ const g2 = (color2 >> 8) & 0xff;
212
+ const b2 = color2 & 0xff;
213
+
214
+ // 计算混合色
215
+ const r = Math.floor(r1 + (r2 - r1) * percentage);
216
+ const g = Math.floor(g1 + (g2 - g1) * percentage);
217
+ const b = Math.floor(b1 + (b2 - b1) * percentage);
218
+
219
+ return (r << 16) | (g << 8) | b;
220
+ }
221
+
222
+ static getRainbowColor(percentage) {
223
+ const colors = [
224
+ 0xff0000, // 红色
225
+ 0xffff00, // 黄色
226
+ 0x00ff00, // 绿色
227
+ 0x00ffff, // 青色
228
+ 0x0000ff, // 蓝色
229
+ 0xff00ff, // 紫色
230
+ 0xff0000, // 回到红色,形成循环
231
+ ];
232
+ // 根据value值计算当前颜色段
233
+ const segment = percentage * (colors.length - 1);
234
+ const colorIndex = Math.floor(segment);
235
+ const blendRatio = segment - colorIndex;
236
+
237
+ // 获取当前颜色段的两个颜色并进行混合
238
+ const currentColor = this.getMixColor(
239
+ colors[colorIndex],
240
+ colors[colorIndex + 1],
241
+ blendRatio
242
+ );
243
+ return currentColor;
244
+ }
245
+
246
+ /**
247
+ * 获取两个边框的混合值
248
+ * @param {{x?:number, y?:number, w?:number, h?:number, radius?:number}} border1 边框1
249
+ * @param {{x?:number, y?:number, w?:number, h?:number, radius?:number}} border2 边框2
250
+ * @param {number} percentage 混合百分比 [0,1]
251
+ * @returns {{x:number, y:number, w:number, h:number, radius:number}} 混合后的边框
252
+ */
253
+ static getMixBorder(border1, border2, percentage) {
254
+ return {
255
+ x: border1.x + (border2.x - border1.x) * percentage,
256
+ y: border1.y + (border2.y - border1.y) * percentage,
257
+ w: border1.w + (border2.w - border1.w) * percentage,
258
+ h: border1.h + (border2.h - border1.h) * percentage,
259
+ radius:
260
+ border1.radius + (border2.radius - border1.radius) * percentage,
261
+ };
262
+ }
263
+ }
264
+
265
+ /**
266
+ * 动画样式预设常量
267
+ * @enum {number}
268
+ */
269
+ Fx.Styles = {
270
+ LINEAR: 0,
271
+ EASE_IN_SINE: 1,
272
+ EASE_OUT_SINE: 2,
273
+ EASE_IN_OUT_SINE: 3,
274
+ EASE_IN_QUAD: 4,
275
+ EASE_OUT_QUAD: 5,
276
+ EASE_IN_OUT_QUAD: 6,
277
+ EASE_IN_CUBIC: 7,
278
+ EASE_OUT_CUBIC: 8,
279
+ EASE_IN_OUT_CUBIC: 9,
280
+ EASE_IN_QUART: 10,
281
+ EASE_OUT_QUART: 11,
282
+ EASE_IN_OUT_QUART: 12,
283
+ EASE_IN_QUINT: 13,
284
+ EASE_OUT_QUINT: 14,
285
+ EASE_IN_OUT_QUINT: 15,
286
+ EASE_IN_EXPO: 16,
287
+ EASE_OUT_EXPO: 17,
288
+ EASE_IN_OUT_EXPO: 18,
289
+ EASE_IN_CIRC: 19,
290
+ EASE_OUT_CIRC: 20,
291
+ EASE_IN_OUT_CIRC: 21,
292
+ EASE_IN_BACK: 22,
293
+ EASE_OUT_BACK: 23,
294
+ EASE_IN_OUT_BACK: 24,
295
+ EASE_IN_ELASTIC: 25,
296
+ EASE_OUT_ELASTIC: 26,
297
+ EASE_IN_OUT_ELASTIC: 27,
298
+ EASE_IN_BOUNCE: 28,
299
+ EASE_OUT_BOUNCE: 29,
300
+ EASE_IN_OUT_BOUNCE: 31,
301
+ };
302
+
303
+ /**
304
+ * 缓动函数集合
305
+ * @see https://easings.net/
306
+ */
307
+ Fx.Easing = {
308
+ LINEAR: function (now_x, begin, end, max_x) {
309
+ const x = now_x / max_x;
310
+ return begin + (end - begin) * x;
311
+ },
312
+
313
+ EASE_IN_SINE: function (now_x, begin, end, max_x) {
314
+ const x = now_x / max_x;
315
+ return begin + (end - begin) * (1 - Math.cos((x * Math.PI) / 2));
316
+ },
317
+
318
+ EASE_OUT_SINE: function (now_x, begin, end, max_x) {
319
+ const x = now_x / max_x;
320
+ return begin + (end - begin) * Math.sin((x * Math.PI) / 2);
321
+ },
322
+
323
+ EASE_IN_OUT_SINE: function (now_x, begin, end, max_x) {
324
+ const x = now_x / max_x;
325
+ return begin + (end - begin) * (-(Math.cos(Math.PI * x) - 1) / 2);
326
+ },
327
+
328
+ EASE_IN_QUAD: function (now_x, begin, end, max_x) {
329
+ const x = now_x / max_x;
330
+ return begin + (end - begin) * (x * x);
331
+ },
332
+
333
+ EASE_OUT_QUAD: function (now_x, begin, end, max_x) {
334
+ const x = now_x / max_x;
335
+ return begin + (end - begin) * (1 - (1 - x) * (1 - x));
336
+ },
337
+
338
+ EASE_IN_OUT_QUAD: function (now_x, begin, end, max_x) {
339
+ const x = now_x / max_x;
340
+ return (
341
+ begin +
342
+ (end - begin) *
343
+ (x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2)
344
+ );
345
+ },
346
+
347
+ EASE_IN_CUBIC: function (now_x, begin, end, max_x) {
348
+ const x = now_x / max_x;
349
+ return begin + (end - begin) * (x * x * x);
350
+ },
351
+
352
+ EASE_OUT_CUBIC: function (now_x, begin, end, max_x) {
353
+ const x = now_x / max_x;
354
+ return begin + (end - begin) * (1 - Math.pow(1 - x, 3));
355
+ },
356
+
357
+ EASE_IN_OUT_CUBIC: function (now_x, begin, end, max_x) {
358
+ const x = now_x / max_x;
359
+ return (
360
+ begin +
361
+ (end - begin) *
362
+ (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2)
363
+ );
364
+ },
365
+
366
+ EASE_IN_QUART: function (now_x, begin, end, max_x) {
367
+ const x = now_x / max_x;
368
+ return begin + (end - begin) * (x * x * x * x);
369
+ },
370
+
371
+ EASE_OUT_QUART: function (now_x, begin, end, max_x) {
372
+ const x = now_x / max_x;
373
+ return begin + (end - begin) * (1 - Math.pow(1 - x, 4));
374
+ },
375
+
376
+ EASE_IN_OUT_QUART: function (now_x, begin, end, max_x) {
377
+ const x = now_x / max_x;
378
+ return (
379
+ begin +
380
+ (end - begin) *
381
+ (x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2)
382
+ );
383
+ },
384
+
385
+ EASE_IN_QUINT: function (now_x, begin, end, max_x) {
386
+ const x = now_x / max_x;
387
+ return begin + (end - begin) * (x * x * x * x * x);
388
+ },
389
+
390
+ EASE_OUT_QUINT: function (now_x, begin, end, max_x) {
391
+ const x = now_x / max_x;
392
+ return begin + (end - begin) * (1 - Math.pow(1 - x, 5));
393
+ },
394
+
395
+ EASE_IN_OUT_QUINT: function (now_x, begin, end, max_x) {
396
+ const x = now_x / max_x;
397
+ return (
398
+ begin +
399
+ (end - begin) *
400
+ (x < 0.5
401
+ ? 16 * x * x * x * x * x
402
+ : 1 - Math.pow(-2 * x + 2, 5) / 2)
403
+ );
404
+ },
405
+
406
+ EASE_IN_EXPO: function (now_x, begin, end, max_x) {
407
+ const x = now_x / max_x;
408
+ return begin + (end - begin) * (x === 0 ? 0 : Math.pow(2, 10 * x - 10));
409
+ },
410
+
411
+ EASE_OUT_EXPO: function (now_x, begin, end, max_x) {
412
+ const x = now_x / max_x;
413
+ return begin + (end - begin) * (x === 1 ? 1 : 1 - Math.pow(2, -10 * x));
414
+ },
415
+
416
+ EASE_IN_OUT_EXPO: function (now_x, begin, end, max_x) {
417
+ const x = now_x / max_x;
418
+ return (
419
+ begin +
420
+ (end - begin) *
421
+ (x === 0
422
+ ? 0
423
+ : x === 1
424
+ ? 1
425
+ : x < 0.5
426
+ ? Math.pow(2, 20 * x - 10) / 2
427
+ : (2 - Math.pow(2, -20 * x + 10)) / 2)
428
+ );
429
+ },
430
+
431
+ EASE_IN_CIRC: function (now_x, begin, end, max_x) {
432
+ const x = now_x / max_x;
433
+ return begin + (end - begin) * (1 - Math.sqrt(1 - Math.pow(x, 2)));
434
+ },
435
+
436
+ EASE_OUT_CIRC: function (now_x, begin, end, max_x) {
437
+ const x = now_x / max_x;
438
+ return begin + (end - begin) * Math.sqrt(1 - Math.pow(x - 1, 2));
439
+ },
440
+
441
+ EASE_IN_OUT_CIRC: function (now_x, begin, end, max_x) {
442
+ const x = now_x / max_x;
443
+ return (
444
+ begin +
445
+ (end - begin) *
446
+ (x < 0.5
447
+ ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2
448
+ : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2)
449
+ );
450
+ },
451
+
452
+ EASE_IN_BACK: function (now_x, begin, end, max_x) {
453
+ const x = now_x / max_x;
454
+ const c1 = 1.70158;
455
+ return begin + (end - begin) * (c1 * x * x * x - c1 * x * x);
456
+ },
457
+
458
+ EASE_OUT_BACK: function (now_x, begin, end, max_x) {
459
+ const x = now_x / max_x;
460
+ const c1 = 1.70158;
461
+ return (
462
+ begin +
463
+ (end - begin) *
464
+ (1 + c1 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2))
465
+ );
466
+ },
467
+
468
+ EASE_IN_OUT_BACK: function (now_x, begin, end, max_x) {
469
+ const x = now_x / max_x;
470
+ const c1 = 1.70158;
471
+ const c2 = c1 * 1.525;
472
+
473
+ return (
474
+ begin +
475
+ (end - begin) *
476
+ (x < 0.5
477
+ ? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
478
+ : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) +
479
+ 2) /
480
+ 2)
481
+ );
482
+ },
483
+
484
+ EASE_IN_ELASTIC: function (now_x, begin, end, max_x) {
485
+ const x = now_x / max_x;
486
+ const c4 = (2 * Math.PI) / 3;
487
+
488
+ return (
489
+ begin +
490
+ (end - begin) *
491
+ (x === 0
492
+ ? 0
493
+ : x === 1
494
+ ? 1
495
+ : -Math.pow(2, 10 * x - 10) *
496
+ Math.sin((x * 10 - 10.75) * c4))
497
+ );
498
+ },
499
+
500
+ EASE_OUT_ELASTIC: function (now_x, begin, end, max_x) {
501
+ const x = now_x / max_x;
502
+ const c4 = (2 * Math.PI) / 3;
503
+
504
+ return (
505
+ begin +
506
+ (end - begin) *
507
+ (x === 0
508
+ ? 0
509
+ : x === 1
510
+ ? 1
511
+ : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1)
512
+ );
513
+ },
514
+
515
+ EASE_IN_OUT_ELASTIC: function (now_x, begin, end, max_x) {
516
+ const x = now_x / max_x;
517
+ const c5 = (2 * Math.PI) / 4.5;
518
+
519
+ return (
520
+ begin +
521
+ (end - begin) *
522
+ (x === 0
523
+ ? 0
524
+ : x === 1
525
+ ? 1
526
+ : x < 0.5
527
+ ? -(
528
+ Math.pow(2, 20 * x - 10) *
529
+ Math.sin((20 * x - 11.125) * c5)
530
+ ) / 2
531
+ : (Math.pow(2, -20 * x + 10) *
532
+ Math.sin((20 * x - 11.125) * c5)) /
533
+ 2 +
534
+ 1)
535
+ );
536
+ },
537
+
538
+ EASE_IN_BOUNCE: function (now_x, begin, end, max_x) {
539
+ const x = now_x / max_x;
540
+ return begin + (end - begin) * (1 - bounceOut(1 - x));
541
+ },
542
+
543
+ EASE_OUT_BOUNCE: function (now_x, begin, end, max_x) {
544
+ const x = now_x / max_x;
545
+ return begin + (end - begin) * bounceOut(x);
546
+ },
547
+
548
+ EASE_IN_OUT_BOUNCE: function (now_x, begin, end, max_x) {
549
+ const x = now_x / max_x;
550
+ return (
551
+ begin +
552
+ (end - begin) *
553
+ (x < 0.5
554
+ ? (1 - bounceOut(1 - 2 * x)) / 2
555
+ : (1 + bounceOut(2 * x - 1)) / 2)
556
+ );
557
+ },
558
+ };
559
+
560
+ /**
561
+ * zeppos-timer.js
562
+ * @description An accurate timer for ZeppOS. 一个适用于ZeppOS的准确的计时器
563
+ * @version 1.0.0
564
+ * @date 2023/04/07
565
+ * @author XiaomaiTX
566
+ * @license MIT
567
+ * https://github.com/XiaomaiTX/zeppos-timer
568
+ *
569
+ * */
570
+ import { Time } from "@zos/sensor";
571
+
572
+ class ZeppTimer {
573
+ constructor(callback, interval) {
574
+ this.callback = callback;
575
+ this.interval = interval;
576
+ this.timerId = null;
577
+ this.startTime = null;
578
+ this.nextTick = null;
579
+ this.time = new Time();
580
+ this.stopped = false;
581
+ }
582
+
583
+ start(delay = 0) {
584
+ this.startTime = this.time.getTime() + delay;
585
+ this.nextTick = this.startTime + this.interval;
586
+ this.scheduleTick();
587
+ }
588
+
589
+ stop() {
590
+ this.stopped = true;
591
+ this.timerId && clearTimeout(this.timerId);
592
+ }
593
+
594
+ scheduleTick() {
595
+ if (this.stopped) return;
596
+ const currentTime = this.time.getTime();
597
+ const delay = Math.max(0, this.nextTick - currentTime);
598
+ this.timerId = setTimeout(() => {
599
+ this.tick();
600
+ }, delay);
601
+ }
602
+
603
+ tick() {
604
+ const currentTime = this.time.getTime();
605
+
606
+ // 计算误差,确保计时器的准确性
607
+ const error = currentTime - this.nextTick;
608
+
609
+ if (error > this.interval) {
610
+ // 如果误差大于一个间隔时间,则将 nextTick 更新为当前时间
611
+ this.nextTick = currentTime;
612
+ } else {
613
+ // 否则将 nextTick 加上一个间隔时间
614
+ this.nextTick += this.interval;
615
+ }
616
+
617
+ // 调用回调函数
618
+ this.callback();
619
+
620
+ // 继续调度下一个 tick
621
+ this.scheduleTick();
622
+ }
623
+ }
package/fx.js.png ADDED
Binary file
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export { Fx } from './fx.js';