@freestylejs/ani-core 1.1.0 → 1.2.0

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/dist/index.cjs CHANGED
@@ -21,31 +21,60 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
23
  AnimationClock: () => AnimationClock,
24
- AnimationNode: () => AnimationNode,
25
- CompositionNode: () => CompositionNode,
24
+ BezierTimingFunction: () => BezierTimingFunction,
26
25
  EventManager: () => EventManager,
27
26
  LinearTimingFunction: () => LinearTimingFunction,
28
- ParallelNode: () => ParallelNode,
29
- SegmentNode: () => SegmentNode,
30
- SequenceNode: () => SequenceNode,
31
- StaggerNode: () => StaggerNode,
27
+ RafAniTimeline: () => RafAniTimeline,
32
28
  T: () => T,
33
- Timeline: () => Timeline,
29
+ TimelineBase: () => TimelineBase,
34
30
  TimingFunction: () => TimingFunction,
31
+ WebAniTimeline: () => WebAniTimeline,
35
32
  a: () => a,
36
- ani: () => ani,
33
+ calculateSegmentState: () => calculateSegmentState,
34
+ compileToKeyframes: () => compileToKeyframes,
37
35
  createStates: () => createStates,
38
36
  createStyleSheet: () => createStyleSheet,
39
- delay: () => delay,
40
- loop: () => loop,
41
- parallel: () => parallel,
42
- sequence: () => sequence,
43
- stagger: () => stagger,
44
- timeline: () => timeline
37
+ rafTimeline: () => rafTimeline,
38
+ webTimeline: () => webTimeline
45
39
  });
46
40
  module.exports = __toCommonJS(src_exports);
47
41
 
48
- // src/ani/nodes/base.ts
42
+ // src/utils/time/is_end.ts
43
+ function isEndOfAnimation(currentT, duration, tolerance = 1e-3) {
44
+ return currentT === duration || currentT - duration >= tolerance;
45
+ }
46
+
47
+ // src/ani/core/engine.ts
48
+ function calculateSegmentState(localTime, segmentDef, dt = 0) {
49
+ const t = Math.max(0, Math.min(localTime, segmentDef.duration));
50
+ const animeValues = [];
51
+ let allComplete = true;
52
+ const isMultipleTiming = Array.isArray(segmentDef.timing);
53
+ if (isMultipleTiming && segmentDef.timing.length !== segmentDef.from.length) {
54
+ throw new TypeError(
55
+ `[calculateSegmentState] timing does not correctly set. It requires multiple timing for ${segmentDef.from}, but received ${segmentDef.timing}`
56
+ );
57
+ }
58
+ for (let i = 0; i < segmentDef.from.length; i++) {
59
+ const timingFunction = isMultipleTiming ? segmentDef.timing[i] : segmentDef.timing;
60
+ const animeResponse = timingFunction.step(t, {
61
+ dt,
62
+ from: segmentDef.from[i],
63
+ to: segmentDef.to[i],
64
+ duration: segmentDef.duration
65
+ });
66
+ animeValues.push(animeResponse.value);
67
+ if (!animeResponse.endOfAnimation) {
68
+ allComplete = false;
69
+ }
70
+ }
71
+ return {
72
+ values: animeValues,
73
+ isComplete: allComplete || isEndOfAnimation(t, segmentDef.duration)
74
+ };
75
+ }
76
+
77
+ // src/nodes/base.ts
49
78
  var AnimationNode = class {
50
79
  constructor(id) {
51
80
  if (id) {
@@ -75,42 +104,122 @@ var TimingFunction = class _TimingFunction {
75
104
  }
76
105
  };
77
106
 
78
- // src/timing/linear.ts
79
- var LinearTimingFunction = class extends TimingFunction {
80
- step(time, context) {
81
- const progress = context.duration === 0 ? 1 : Math.max(0, Math.min(time / context.duration, 1));
82
- const value = context.from + (context.to - context.from) * progress;
83
- return { value, endOfAnimation: time >= context.duration };
84
- }
85
- };
86
-
87
107
  // src/timing/bezier.ts
108
+ var NEWTON_ITERATIONS = 4;
109
+ var NEWTON_MIN_SLOPE = 1e-3;
110
+ var SUBDIVISION_PRECISION = 1e-7;
111
+ var SUBDIVISION_MAX_ITERATIONS = 10;
112
+ var SAMPLE_TABLE_SIZE = 11;
113
+ var SAMPLE_STEP_SIZE = 1 / (SAMPLE_TABLE_SIZE - 1);
88
114
  var BezierTimingFunction = class extends TimingFunction {
89
115
  constructor(opt) {
90
116
  super();
91
117
  this.opt = opt;
92
- this.p1 = {
93
- x: 0,
94
- y: 0
95
- };
96
- this.p4 = {
97
- x: 1,
98
- y: 1
99
- };
118
+ this.sampleValues = null;
119
+ if (this.opt.p2.x !== this.opt.p2.y || this.opt.p3.x !== this.opt.p3.y) {
120
+ this.sampleValues = new Float32Array(SAMPLE_TABLE_SIZE);
121
+ for (let i = 0; i < SAMPLE_TABLE_SIZE; ++i) {
122
+ this.sampleValues[i] = this.calcBezier(
123
+ i * SAMPLE_STEP_SIZE,
124
+ this.opt.p2.x,
125
+ this.opt.p3.x
126
+ );
127
+ }
128
+ }
100
129
  }
101
- _bezierFunction(t, duration) {
102
- const end = duration || this.p4.y;
103
- return (1 - t) ** 3 * this.p1.y + 3 * (1 - t) ** 2 * t * this.opt.p2.y + 3 * (1 - t) * t ** 2 * this.opt.p3.y + t ** 3 * end;
130
+ calcBezier(t, a1, a2) {
131
+ return ((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t * t + 3 * a1 * t;
132
+ }
133
+ getSlope(t, a1, a2) {
134
+ return 3 * (1 - 3 * a2 + 3 * a1) * t * t + 2 * (3 * a2 - 6 * a1) * t + 3 * a1;
135
+ }
136
+ getTForX(x) {
137
+ const mX1 = this.opt.p2.x;
138
+ const mX2 = this.opt.p3.x;
139
+ let intervalStart = 0;
140
+ let currentSample = 1;
141
+ const lastSample = SAMPLE_TABLE_SIZE - 1;
142
+ for (; currentSample !== lastSample && this.sampleValues[currentSample] <= x; ++currentSample) {
143
+ intervalStart += SAMPLE_STEP_SIZE;
144
+ }
145
+ --currentSample;
146
+ const dist = (x - this.sampleValues[currentSample]) / (this.sampleValues[currentSample + 1] - this.sampleValues[currentSample]);
147
+ const guessForT = intervalStart + dist * SAMPLE_STEP_SIZE;
148
+ const initialSlope = this.getSlope(guessForT, mX1, mX2);
149
+ if (initialSlope >= NEWTON_MIN_SLOPE) {
150
+ return this.newtonRaphsonIterate(x, guessForT, mX1, mX2);
151
+ }
152
+ if (initialSlope === 0) {
153
+ return guessForT;
154
+ }
155
+ return this.binarySubdivide(
156
+ x,
157
+ intervalStart,
158
+ intervalStart + SAMPLE_STEP_SIZE,
159
+ mX1,
160
+ mX2
161
+ );
162
+ }
163
+ binarySubdivide(aX, aA, aB, mX1, mX2) {
164
+ let currentX;
165
+ let currentT;
166
+ let i = 0;
167
+ let currentA = aA;
168
+ let currentB = aB;
169
+ do {
170
+ currentT = currentA + (currentB - currentA) / 2;
171
+ currentX = this.calcBezier(currentT, mX1, mX2) - aX;
172
+ if (currentX > 0) {
173
+ currentB = currentT;
174
+ } else {
175
+ currentA = currentT;
176
+ }
177
+ } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
178
+ return currentT;
179
+ }
180
+ newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
181
+ let guessT = aGuessT;
182
+ for (let i = 0; i < NEWTON_ITERATIONS; ++i) {
183
+ const currentSlope = this.getSlope(guessT, mX1, mX2);
184
+ if (currentSlope === 0) {
185
+ return guessT;
186
+ }
187
+ const currentX = this.calcBezier(guessT, mX1, mX2) - aX;
188
+ guessT -= currentX / currentSlope;
189
+ }
190
+ return guessT;
104
191
  }
105
192
  step(time, context) {
106
- const f = this._bezierFunction(time, context.duration);
193
+ const { duration, from, to } = context;
194
+ if (duration === 0) {
195
+ return { value: to, endOfAnimation: true };
196
+ }
197
+ const x = Math.max(0, Math.min(time / duration, 1));
198
+ let easedT = x;
199
+ if (this.opt.p2.x !== this.opt.p2.y || this.opt.p3.x !== this.opt.p3.y) {
200
+ if (!this.sampleValues) {
201
+ }
202
+ const t = this.getTForX(x);
203
+ easedT = this.calcBezier(t, this.opt.p2.y, this.opt.p3.y);
204
+ }
205
+ const value = from + (to - from) * easedT;
206
+ const endOfAnimation = time >= duration;
107
207
  return {
108
- value: f,
109
- endOfAnimation: (context.duration ? time >= context.duration : time >= this.p4.x) && f >= context.to
208
+ value,
209
+ endOfAnimation
110
210
  };
111
211
  }
112
212
  };
113
213
 
214
+ // src/timing/linear.ts
215
+ var LinearTimingFunction = class extends TimingFunction {
216
+ step(time, context) {
217
+ const progress = context.duration === 0 ? 1 : Math.max(0, Math.min(time / context.duration, 1));
218
+ const value = context.from + (context.to - context.from) * progress;
219
+ return { value, endOfAnimation: time >= context.duration };
220
+ }
221
+ };
222
+
114
223
  // src/timing/dynamic_spring.ts
115
224
  var DynamicSpringTimingFunction = class extends TimingFunction {
116
225
  constructor(opt) {
@@ -268,10 +377,38 @@ var T = {
268
377
  /**
269
378
  * Creates linear timing function instance.
270
379
  */
271
- linear: () => new LinearTimingFunction()
380
+ linear: () => new LinearTimingFunction(),
381
+ /**
382
+ * Standard CSS 'ease' timing function (0.25, 0.1, 0.25, 1.0).
383
+ */
384
+ ease: () => new BezierTimingFunction({
385
+ p2: { x: 0.25, y: 0.1 },
386
+ p3: { x: 0.25, y: 1 }
387
+ }),
388
+ /**
389
+ * Standard CSS 'ease-in' timing function (0.42, 0, 1.0, 1.0).
390
+ */
391
+ easeIn: () => new BezierTimingFunction({
392
+ p2: { x: 0.42, y: 0 },
393
+ p3: { x: 1, y: 1 }
394
+ }),
395
+ /**
396
+ * Standard CSS 'ease-out' timing function (0, 0, 0.58, 1.0).
397
+ */
398
+ easeOut: () => new BezierTimingFunction({
399
+ p2: { x: 0, y: 0 },
400
+ p3: { x: 0.58, y: 1 }
401
+ }),
402
+ /**
403
+ * Standard CSS 'ease-in-out' timing function (0.42, 0, 0.58, 1.0).
404
+ */
405
+ easeInOut: () => new BezierTimingFunction({
406
+ p2: { x: 0.42, y: 0 },
407
+ p3: { x: 0.58, y: 1 }
408
+ })
272
409
  };
273
410
 
274
- // src/ani/nodes/segment.ts
411
+ // src/nodes/segment.ts
275
412
  var SegmentNode = class extends AnimationNode {
276
413
  constructor(props, id) {
277
414
  super(id);
@@ -298,7 +435,7 @@ function ani(props, id) {
298
435
  return new SegmentNode(props, id);
299
436
  }
300
437
 
301
- // src/ani/nodes/composition.ts
438
+ // src/nodes/composition.ts
302
439
  var CompositionNode = class _CompositionNode extends AnimationNode {
303
440
  constructor(children, timing, id) {
304
441
  super(id);
@@ -327,12 +464,12 @@ var CompositionNode = class _CompositionNode extends AnimationNode {
327
464
  }
328
465
  };
329
466
 
330
- // src/ani/nodes/delay.ts
467
+ // src/nodes/delay.ts
331
468
  function delay(duration, id) {
332
469
  return new SegmentNode({ to: {}, duration }, id);
333
470
  }
334
471
 
335
- // src/ani/nodes/loop.ts
472
+ // src/nodes/loop.ts
336
473
  var LoopNode = class extends CompositionNode {
337
474
  constructor(child, loopCount, timing, id) {
338
475
  super([child], timing, id);
@@ -353,7 +490,7 @@ function loop(child, loopCount, timing, id) {
353
490
  return new LoopNode(child, loopCount, timing, id);
354
491
  }
355
492
 
356
- // src/ani/nodes/parallel.ts
493
+ // src/nodes/parallel.ts
357
494
  var ParallelNode = class extends CompositionNode {
358
495
  constructor(children, timing, id) {
359
496
  const seenProperty = /* @__PURE__ */ new Set();
@@ -403,7 +540,7 @@ function parallel(children, timing, id) {
403
540
  return new ParallelNode(children, timing, id);
404
541
  }
405
542
 
406
- // src/ani/nodes/sequence.ts
543
+ // src/nodes/sequence.ts
407
544
  var SequenceNode = class extends CompositionNode {
408
545
  constructor(children, timing, id) {
409
546
  super(children, timing, id);
@@ -422,12 +559,12 @@ function sequence(children, timing, id) {
422
559
  return new SequenceNode(children, timing, id);
423
560
  }
424
561
 
425
- // src/ani/nodes/stagger.ts
562
+ // src/nodes/stagger.ts
426
563
  var StaggerNode = class extends CompositionNode {
427
- constructor(children, props, id) {
428
- super(children, props?.timing, id);
564
+ constructor(children, offset, timing, id) {
565
+ super(children, timing, id);
429
566
  this.type = "STAGGER";
430
- this.offset = props.offset;
567
+ this.offset = offset;
431
568
  if (children.length === 0) {
432
569
  this.duration = 0;
433
570
  } else {
@@ -443,10 +580,81 @@ var StaggerNode = class extends CompositionNode {
443
580
  }
444
581
  }
445
582
  };
446
- function stagger(children, props, id) {
447
- return new StaggerNode(children, props, id);
583
+ function stagger(children, offset, timing, id) {
584
+ return new StaggerNode(children, offset, timing, id);
448
585
  }
449
586
 
587
+ // src/ani/core/interface/timeline_interface.ts
588
+ var TimelineBase = class {
589
+ constructor(rootNode) {
590
+ this.rootNode = rootNode;
591
+ this._currentExecutionPlan = null;
592
+ this.duration = rootNode.duration;
593
+ this._baseExecutionPlan = this._constructExecutionPlan(rootNode);
594
+ this.play = this.play.bind(this);
595
+ this.pause = this.pause.bind(this);
596
+ this.seek = this.seek.bind(this);
597
+ this.reset = this.reset.bind(this);
598
+ this.resume = this.resume.bind(this);
599
+ }
600
+ /**
601
+ * flatten the AST into a linear execution plan.
602
+ */
603
+ _constructExecutionPlan(rootNode) {
604
+ const plan = [];
605
+ rootNode.construct(plan, 0);
606
+ return plan;
607
+ }
608
+ /**
609
+ * Merges the base plan with runtime dynamic overrides.
610
+ */
611
+ _resolveExecutionPlan(keyframes, durations) {
612
+ if (!keyframes && !durations) {
613
+ return [...this._baseExecutionPlan];
614
+ }
615
+ const segmentNodes = this._baseExecutionPlan.filter(
616
+ (segment) => segment.node.type === "SEGMENT"
617
+ );
618
+ const segLength = segmentNodes.length;
619
+ if (keyframes && keyframes.length !== segLength) {
620
+ throw new Error(
621
+ `[Timeline] Keyframe mismatch: Expected ${segLength}, received ${keyframes.length}.`
622
+ );
623
+ }
624
+ if (durations && durations.length !== segLength) {
625
+ throw new Error(
626
+ `[Timeline] Duration mismatch: Expected ${segLength}, received ${durations.length}.`
627
+ );
628
+ }
629
+ const newPlan = [];
630
+ let keyframeIndex = 0;
631
+ for (const segment of this._baseExecutionPlan) {
632
+ if (segment.node.type === "SEGMENT") {
633
+ const dynamicTo = keyframes?.[keyframeIndex];
634
+ const dynamicDuration = durations?.[keyframeIndex];
635
+ const newSegmentProps = {
636
+ ...segment.node.props,
637
+ ...dynamicTo && dynamicTo !== "keep" && {
638
+ to: dynamicTo
639
+ },
640
+ ...dynamicDuration && dynamicDuration !== "keep" && {
641
+ duration: dynamicDuration
642
+ }
643
+ };
644
+ const newSegment = new SegmentNode(
645
+ newSegmentProps,
646
+ segment.node.id
647
+ );
648
+ newPlan.push({ ...segment, node: newSegment });
649
+ keyframeIndex++;
650
+ } else {
651
+ newPlan.push({ ...segment });
652
+ }
653
+ }
654
+ return newPlan;
655
+ }
656
+ };
657
+
450
658
  // src/loop/clock.ts
451
659
  var AnimationClock = class _AnimationClock {
452
660
  constructor(maxDeltaTime) {
@@ -502,46 +710,86 @@ var AnimationClock = class _AnimationClock {
502
710
  }
503
711
  };
504
712
 
505
- // src/utils/time/is_end.ts
506
- function isEndOfAnimation(currentT, duration, tolerance = 1e-3) {
507
- return currentT === duration || currentT - duration >= tolerance;
713
+ // src/ani/core/resolver.ts
714
+ function resolveGroup(group) {
715
+ if (Array.isArray(group)) {
716
+ return { keyMap: null, values: group };
717
+ }
718
+ const typedGroup = group;
719
+ const keys = Object.keys(typedGroup);
720
+ const keyMap = new Map(keys.map((key, i) => [key, i]));
721
+ const values = keys.map((key) => typedGroup[key]);
722
+ return { keyMap, values };
508
723
  }
509
-
510
- // src/ani/engine.ts
511
- function calculateSegmentState(localTime, segmentDef, dt = 0) {
512
- const t = Math.max(0, Math.min(localTime, segmentDef.duration));
513
- const animeValues = [];
514
- let allComplete = true;
515
- const isMultipleTiming = Array.isArray(segmentDef.timing);
516
- if (isMultipleTiming && segmentDef.timing.length !== segmentDef.from.length) {
517
- throw new TypeError(
518
- `[calculateSegmentState] timing does not correctly set. It requires multiple timing for ${segmentDef.from}, but received ${segmentDef.timing}`
519
- );
724
+ function resolveStateToGroup(state, keyMap) {
725
+ if (!keyMap) {
726
+ return state;
520
727
  }
521
- for (let i = 0; i < segmentDef.from.length; i++) {
522
- const timingFunction = isMultipleTiming ? segmentDef.timing[i] : segmentDef.timing;
523
- const animeResponse = timingFunction.step(t, {
524
- dt,
525
- from: segmentDef.from[i],
526
- to: segmentDef.to[i],
527
- duration: segmentDef.duration
528
- });
529
- animeValues.push(animeResponse.value);
530
- if (!animeResponse.endOfAnimation) {
531
- allComplete = false;
728
+ const group = {};
729
+ for (const [key, index] of keyMap.entries()) {
730
+ group[key] = state[index];
731
+ }
732
+ return group;
733
+ }
734
+ function resolvePlanState(plan, initialValues, keyMap, targetTime, dt = 0) {
735
+ const nextState = [...initialValues];
736
+ let stateAtLastStartTime = [...initialValues];
737
+ for (const segment of plan) {
738
+ if (targetTime < segment.startTime) {
739
+ continue;
740
+ }
741
+ stateAtLastStartTime = [...nextState];
742
+ const { keyMap: segKeyMap, values: toValues } = resolveGroup(
743
+ segment.node.props.to
744
+ );
745
+ const isRecordAni = keyMap !== null;
746
+ let fromValues = [];
747
+ const timings = [];
748
+ const t = segment.node.props.timing;
749
+ const isRecordTiming = t && !(t instanceof TimingFunction);
750
+ if (isRecordAni) {
751
+ for (const key of segKeyMap.keys()) {
752
+ const index = keyMap.get(key);
753
+ fromValues.push(stateAtLastStartTime[index]);
754
+ if (isRecordTiming) {
755
+ timings.push(t[key]);
756
+ }
757
+ }
758
+ } else {
759
+ fromValues = stateAtLastStartTime;
760
+ }
761
+ const localTime = targetTime - segment.startTime;
762
+ const segmentDef = {
763
+ from: fromValues,
764
+ to: toValues,
765
+ duration: segment.node.duration,
766
+ // default fallback = linear
767
+ timing: isRecordAni && isRecordTiming ? timings : t ?? T.linear()
768
+ };
769
+ const result = calculateSegmentState(localTime, segmentDef, dt);
770
+ const finalValues = result.isComplete ? toValues : result.values;
771
+ if (isRecordAni) {
772
+ let i = 0;
773
+ for (const key of segKeyMap.keys()) {
774
+ const stateIndex = keyMap.get(key);
775
+ if (stateIndex !== void 0 && stateIndex !== -1) {
776
+ nextState[stateIndex] = finalValues[i];
777
+ }
778
+ i++;
779
+ }
780
+ } else {
781
+ for (let i = 0; i < finalValues.length; i++) {
782
+ nextState[i] = finalValues[i];
783
+ }
532
784
  }
533
785
  }
534
- return {
535
- values: animeValues,
536
- isComplete: allComplete || isEndOfAnimation(t, segmentDef.duration)
537
- };
786
+ return nextState;
538
787
  }
539
788
 
540
- // src/ani/timeline.ts
541
- var Timeline = class {
789
+ // src/ani/raf/timeline.ts
790
+ var RafAniTimeline = class extends TimelineBase {
542
791
  constructor(rootNode, clock) {
543
- this.rootNode = rootNode;
544
- this._currentExecutionPlan = null;
792
+ super(rootNode);
545
793
  this._masterTime = 0;
546
794
  this._delay = 0;
547
795
  this._status = "IDLE";
@@ -550,194 +798,86 @@ var Timeline = class {
550
798
  this._initialState = [];
551
799
  this._repeatCount = 0;
552
800
  this._propertyKeyMap = null;
553
- this._segmentStartStates = /* @__PURE__ */ new Map();
554
801
  this._onUpdateCallbacks = /* @__PURE__ */ new Set();
555
- this.duration = rootNode.duration;
556
- this._baseExecutionPlan = this._constructExecutionPlan(rootNode);
557
802
  this._clock = clock ?? AnimationClock.create();
558
- this.play.bind(this);
559
- this.pause.bind(this);
560
- this.seek.bind(this);
561
- this.resume.bind(this);
562
- this.reset.bind(this);
803
+ this.play = this.play.bind(this);
804
+ this.pause = this.pause.bind(this);
805
+ this.seek = this.seek.bind(this);
806
+ this.resume = this.resume.bind(this);
807
+ this.reset = this.reset.bind(this);
563
808
  }
564
- /**
565
- * Current animation running config.
566
- */
567
809
  get currentConfig() {
568
810
  return this._currentConfig;
569
811
  }
570
- /**
571
- * Resolves a Group (like {x, y}) into keys and values.
572
- */
573
- _resolveGroup(group) {
574
- if (Array.isArray(group)) {
575
- return { keyMap: null, values: group };
576
- }
577
- const keyMap = new Map(Object.keys(group).map((key, i) => [key, i]));
578
- const values = Object.values(group);
579
- return { keyMap, values };
812
+ getCurrentValue() {
813
+ if (this._state.length === 0) return null;
814
+ return resolveStateToGroup(
815
+ this._state,
816
+ this._propertyKeyMap
817
+ );
580
818
  }
581
- /**
582
- * Resolves the internal state (a number array) back into Group.
583
- */
584
- _resolveStateToGroup(state) {
585
- if (!this._propertyKeyMap) {
586
- return state;
587
- }
588
- const group = {};
589
- let i = 0;
590
- for (const key of this._propertyKeyMap.keys()) {
591
- group[key] = state[i];
592
- i++;
819
+ _calculateStateAtTime(targetTime, dt = 0) {
820
+ if (this._initialState.length === 0 || !this._currentExecutionPlan) {
821
+ return [];
593
822
  }
594
- return group;
823
+ return resolvePlanState(
824
+ this._currentExecutionPlan,
825
+ this._initialState,
826
+ this._propertyKeyMap,
827
+ // Using the class property directly
828
+ targetTime,
829
+ dt
830
+ );
595
831
  }
596
- /**
597
- * Compile animation execution plan
598
- */
599
- _constructExecutionPlan(rootNode) {
600
- const plan = [];
601
- rootNode.construct(plan, 0);
602
- return plan;
832
+ notify() {
833
+ for (const subscriber of this._onUpdateCallbacks) {
834
+ subscriber({
835
+ state: resolveStateToGroup(
836
+ this._state,
837
+ this._propertyKeyMap
838
+ ),
839
+ status: this._status
840
+ });
841
+ }
603
842
  }
604
843
  /**
605
- * Calculates the exact state of the animation at point.
844
+ * @private Internal clock subscription callback.
606
845
  */
607
- _calculateStateAtTime(targetTime, dt = 0) {
608
- if (this._initialState.length === 0 || !this._currentExecutionPlan) {
609
- return [];
610
- }
611
- const nextState = [...this._initialState];
612
- let stateAtLastStartTime = [...this._initialState];
613
- for (const segment of this._currentExecutionPlan) {
614
- if (targetTime < segment.startTime) {
615
- continue;
616
- }
617
- if (!segment.node.props.timing) {
618
- throw new Error(
619
- `[Timeline] timing should be provided. Please specify timing using a.timing.(...). Check target segment: ${JSON.stringify(segment, null, 2)}.`,
620
- { cause: segment }
621
- );
622
- }
623
- stateAtLastStartTime = [...nextState];
624
- const { keyMap, values: toValues } = this._resolveGroup(
625
- segment.node.props.to
626
- );
627
- const isRecordAni = this._propertyKeyMap !== null && keyMap !== null;
628
- let fromValues = [];
629
- const timings = [];
630
- const t = segment.node.props.timing;
631
- const isRecordTiming = t && !(t instanceof TimingFunction);
632
- if (isRecordAni) {
633
- for (const key of keyMap.keys()) {
634
- const index = this._propertyKeyMap.get(key);
635
- fromValues.push(stateAtLastStartTime[index]);
636
- if (isRecordTiming) {
637
- timings.push(
638
- t[key]
639
- );
640
- }
641
- }
642
- } else {
643
- fromValues = stateAtLastStartTime;
644
- }
645
- let finalAnimeValues = [];
646
- const localTime = targetTime - segment.startTime;
647
- const segmentDef = {
648
- from: fromValues,
649
- to: toValues,
650
- duration: segment.node.duration,
651
- timing: isRecordAni && isRecordTiming ? timings : t
652
- };
653
- const segmentState = calculateSegmentState(
654
- localTime,
655
- segmentDef,
656
- dt
657
- );
658
- if (segmentState.isComplete) {
659
- finalAnimeValues = toValues;
846
+ update(dt) {
847
+ if (this._status !== "PLAYING") return;
848
+ if (this._delay > 0) {
849
+ this._delay -= dt;
850
+ if (this._delay < 0) {
851
+ dt = -this._delay;
852
+ this._delay = 0;
660
853
  } else {
661
- finalAnimeValues = segmentState.values;
854
+ return;
662
855
  }
663
- if (isRecordAni) {
664
- let i = 0;
665
- for (const key of keyMap.keys()) {
666
- const stateIndex = this._propertyKeyMap.get(key);
667
- if (stateIndex === -1) {
668
- continue;
669
- }
670
- nextState[stateIndex] = finalAnimeValues[i];
671
- i++;
672
- }
856
+ }
857
+ this._masterTime += dt;
858
+ if (this._masterTime >= this.duration) this._masterTime = this.duration;
859
+ this._state = this._calculateStateAtTime(this._masterTime, dt);
860
+ this.notify();
861
+ if (isEndOfAnimation(this._masterTime, this.duration)) {
862
+ this._repeatCount += 1;
863
+ const noRepeat = (this._currentConfig.repeat ?? 0) === 0;
864
+ if (noRepeat) {
865
+ this._status = "ENDED";
866
+ this._clock.unsubscribe(this);
867
+ this.notify();
673
868
  } else {
674
- for (let i = 0; i < finalAnimeValues.length; i++) {
675
- nextState[i] = finalAnimeValues[i];
676
- }
869
+ this.play(this._currentConfig);
677
870
  }
678
871
  }
679
- return nextState;
680
- }
681
- _resolveExecutionPlan(keyframes, durations) {
682
- if (!keyframes && !durations) {
683
- return [...this._baseExecutionPlan];
684
- }
685
- const segmentNodes = this._baseExecutionPlan.filter(
686
- (segment) => segment.node.type === "SEGMENT"
687
- );
688
- const segLength = segmentNodes.length;
689
- if (keyframes && keyframes.length !== segLength) {
690
- throw new Error(
691
- `Timeline keyframe mismatch: Expected ${segLength} keyframes, but received ${keyframes.length}.`
692
- );
693
- }
694
- if (durations && durations.length !== segLength) {
695
- throw new Error(
696
- `Timeline keyframe mismatch: Expected ${segLength} durations, but received ${durations.length}.`
697
- );
698
- }
699
- const newPlan = [];
700
- let keyframeIndex = 0;
701
- for (const segment of this._baseExecutionPlan) {
702
- if (segment.node.type === "SEGMENT") {
703
- const dynamicTo = keyframes?.[keyframeIndex];
704
- const dynamicDuration = durations?.[keyframeIndex];
705
- const newSegmentProps = {
706
- ...segment.node.props,
707
- // >> dynamic to
708
- ...dynamicTo && {
709
- to: dynamicTo === "keep" ? segment.node.props.to : dynamicTo
710
- },
711
- // >> dynamic duration
712
- ...dynamicDuration && {
713
- duration: dynamicDuration === "keep" ? segment.node.props.duration : dynamicDuration
714
- }
715
- };
716
- const newSegment = new SegmentNode(
717
- newSegmentProps,
718
- segment.node.id
719
- );
720
- newPlan.push({ ...segment, node: newSegment });
721
- keyframeIndex++;
722
- } else {
723
- newPlan.push({ ...segment });
724
- }
725
- }
726
- return newPlan;
727
- }
728
- notify() {
729
- for (const subscriber of this._onUpdateCallbacks) {
730
- subscriber({
731
- state: this._resolveStateToGroup(this._state),
732
- status: this._status
733
- });
734
- }
735
872
  }
873
+ /**
874
+ * Plays animation.
875
+ * @param config {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame RequestAnimationFrame API} based config.
876
+ * @param canBeIntercepted if `true` animation can be intercepted even if already animation started.
877
+ */
736
878
  play(config, canBeIntercepted = true) {
737
- if (this._status === "PLAYING" && !canBeIntercepted) {
738
- return;
739
- }
740
- const isRepeating = this._currentConfig?.repeat && this._currentConfig?.repeat >= 1;
879
+ if (this._status === "PLAYING" && !canBeIntercepted) return;
880
+ const isRepeating = (this._currentConfig?.repeat ?? 0) >= 1;
741
881
  const savedRepeatCount = isRepeating ? this._repeatCount : 0;
742
882
  this.reset(false);
743
883
  this._repeatCount = savedRepeatCount;
@@ -753,8 +893,8 @@ var Timeline = class {
753
893
  config.keyframes,
754
894
  config.durations
755
895
  );
756
- const { keyMap: keys, values } = this._resolveGroup(config.from);
757
- this._propertyKeyMap = keys;
896
+ const { keyMap, values } = resolveGroup(config.from);
897
+ this._propertyKeyMap = keyMap;
758
898
  this._state = values;
759
899
  this._initialState = values;
760
900
  this._status = "PLAYING";
@@ -778,13 +918,10 @@ var Timeline = class {
778
918
  this._state = [];
779
919
  this._initialState = [];
780
920
  this._propertyKeyMap = null;
781
- this._segmentStartStates.clear();
782
921
  this._currentExecutionPlan = null;
783
922
  this._clock.unsubscribe(this);
784
923
  this._repeatCount = 0;
785
- if (notify) {
786
- this.notify();
787
- }
924
+ if (notify) this.notify();
788
925
  }
789
926
  seek(targetTime) {
790
927
  if (this._status === "PLAYING" || this._status === "ENDED") {
@@ -795,87 +932,50 @@ var Timeline = class {
795
932
  this._state = this._calculateStateAtTime(seekTime, 0);
796
933
  this.notify();
797
934
  }
798
- getCurrentValue() {
799
- if (this._state.length === 0) return null;
800
- return this._resolveStateToGroup(this._state);
801
- }
935
+ /**
936
+ * When timeline updates, subscribes on update callback.
937
+ * @param callback Subscription callback.
938
+ * @returns Unsubscribe.
939
+ */
802
940
  onUpdate(callback) {
803
941
  this._onUpdateCallbacks.add(callback);
804
942
  return () => {
805
943
  this._onUpdateCallbacks.delete(callback);
806
944
  };
807
945
  }
808
- update(dt) {
809
- if (this._status !== "PLAYING") {
810
- return;
811
- }
812
- if (this._delay > 0) {
813
- this._delay -= dt;
814
- if (this._delay < 0) {
815
- dt = -this._delay;
816
- this._delay = 0;
817
- } else {
818
- return;
819
- }
820
- }
821
- this._masterTime += dt;
822
- if (this._masterTime >= this.duration) {
823
- this._masterTime = this.duration;
824
- }
825
- this._state = this._calculateStateAtTime(this._masterTime, dt);
826
- this.notify();
827
- if (isEndOfAnimation(this._masterTime, this.duration)) {
828
- this._repeatCount += 1;
829
- if (!this._currentConfig) {
830
- throw new Error(
831
- `[Timeline] currentConfig can not be null when update(dt)`
832
- );
833
- }
834
- const noRepeat = (this._currentConfig.repeat ?? 0) === 0;
835
- if (noRepeat) {
836
- this._status = "ENDED";
837
- this._clock.unsubscribe(this);
838
- this.notify();
839
- } else {
840
- this.play(this._currentConfig);
841
- }
842
- }
843
- }
844
946
  };
845
- function timeline(rootNode, clock) {
846
- return new Timeline(rootNode, clock);
947
+ function rafTimeline(rootNode, clock) {
948
+ return new RafAniTimeline(rootNode, clock);
847
949
  }
848
950
 
849
- // src/ani/states.ts
951
+ // src/ani/raf/states.ts
850
952
  function createStates(config) {
851
953
  let State = config.initial;
852
- let Timeline2 = timeline(
954
+ let Timeline = rafTimeline(
853
955
  config.states[State],
854
956
  config.clock
855
957
  );
856
958
  const subs = /* @__PURE__ */ new Set();
857
- const notify = (timeline2) => {
959
+ const notify = (timeline) => {
858
960
  for (const Sub of subs) {
859
- Sub(timeline2);
961
+ Sub(timeline);
860
962
  }
861
963
  };
862
964
  return {
863
- timeline: () => Timeline2,
965
+ timeline: () => Timeline,
966
+ state: () => State,
864
967
  onTimelineChange(callback) {
865
968
  subs.add(callback);
866
969
  return () => subs.delete(callback);
867
970
  },
868
971
  transitionTo(newState, timelineConfig, canBeIntercepted) {
869
- if (!config.states[newState] || State === newState) {
870
- return;
871
- }
872
972
  const from = timelineConfig?.from ?? // 1. config
873
- Timeline2.getCurrentValue() ?? // 2. last value
973
+ Timeline.getCurrentValue() ?? // 2. last value
874
974
  config.initialFrom;
875
975
  State = newState;
876
- Timeline2 = timeline(config.states[State], config.clock);
877
- notify(Timeline2);
878
- Timeline2.play(
976
+ Timeline = rafTimeline(config.states[State], config.clock);
977
+ notify(Timeline);
978
+ Timeline.play(
879
979
  {
880
980
  ...timelineConfig,
881
981
  from
@@ -886,77 +986,6 @@ function createStates(config) {
886
986
  };
887
987
  }
888
988
 
889
- // src/event/manager.ts
890
- var EventManager = class _EventManager {
891
- constructor(supportedEvents) {
892
- this.supportedEvents = supportedEvents;
893
- this._element = null;
894
- this._animeGetter = null;
895
- this.setAnimeGetter = (animeGetter) => {
896
- this._animeGetter = animeGetter;
897
- };
898
- this.eventMap = /* @__PURE__ */ new Map();
899
- this.withAnimeValue = (listener) => {
900
- const withAnime = (e) => {
901
- listener(this.animeGetter(), e);
902
- };
903
- return withAnime;
904
- };
905
- this.add = (eventName, listener, options) => {
906
- const withAnime = this.withAnimeValue(listener);
907
- this.eventMap.set(eventName, withAnime);
908
- this.targetElement.addEventListener(
909
- eventName,
910
- this.eventMap.get(eventName),
911
- options
912
- );
913
- };
914
- this.cleanupOne = (eventName) => {
915
- const removeListener = this.eventMap.get(eventName);
916
- if (!removeListener) return false;
917
- this.targetElement.removeEventListener(eventName, removeListener);
918
- return true;
919
- };
920
- this.cleanupAll = () => {
921
- const clearResponse = [];
922
- for (const evtName of this.eventMap.keys()) {
923
- const res = this.cleanupOne(evtName);
924
- clearResponse.push(res);
925
- }
926
- return clearResponse.some((t) => t === false) === false;
927
- };
928
- this.attach = (handlers) => {
929
- Object.entries(handlers).forEach(([eventKey, handler]) => {
930
- this.add(
931
- _EventManager.getEvtKey(eventKey),
932
- handler
933
- );
934
- });
935
- };
936
- }
937
- get targetElement() {
938
- if (!this._element) throw new Error("EventManger, bind element first");
939
- return this._element;
940
- }
941
- get animeGetter() {
942
- if (!this._animeGetter)
943
- throw new Error("EventManager, animeGetter should be provided");
944
- return this._animeGetter;
945
- }
946
- /**
947
- * get pure `{event_name}`
948
- * @param key onX`{event_name}`
949
- */
950
- static getEvtKey(key) {
951
- const removed = key.substring(2, key.length);
952
- const Capitalized = `${removed[0].toLowerCase()}${removed.substring(1, key.length)}`;
953
- return Capitalized;
954
- }
955
- bind(element) {
956
- this._element = element;
957
- }
958
- };
959
-
960
989
  // src/style/create_sheet.ts
961
990
  var TransformFunctionMap = {
962
991
  // deg
@@ -1044,41 +1073,286 @@ function createStyleSheet(animeStyleValue, resolver) {
1044
1073
  return styleAccumulator;
1045
1074
  }
1046
1075
 
1076
+ // src/ani/waapi/compiler/resolver.ts
1077
+ function resolveStateAt(plan, initialFrom, targetTime, dt) {
1078
+ const { keyMap, values: initialValues } = resolveGroup(initialFrom);
1079
+ const rawResultState = resolvePlanState(
1080
+ plan,
1081
+ initialValues,
1082
+ keyMap,
1083
+ targetTime,
1084
+ dt
1085
+ );
1086
+ return resolveStateToGroup(rawResultState, keyMap);
1087
+ }
1088
+
1089
+ // src/ani/waapi/compiler/timing_compiler.ts
1090
+ function compileTiming(timing) {
1091
+ if (!timing) {
1092
+ return "linear";
1093
+ }
1094
+ if (timing instanceof LinearTimingFunction) {
1095
+ return "linear";
1096
+ }
1097
+ if (timing instanceof BezierTimingFunction) {
1098
+ const { p2, p3 } = timing.opt;
1099
+ return `cubic-bezier(${p2.x}, ${p2.y}, ${p3.x}, ${p3.y})`;
1100
+ }
1101
+ return null;
1102
+ }
1103
+
1104
+ // src/ani/waapi/compiler/keyframe_compiler.ts
1105
+ function compileToKeyframes(plan, initialFrom) {
1106
+ if (plan.length === 0) {
1107
+ return [];
1108
+ }
1109
+ const FPS = 60;
1110
+ const SAMPLE_RATE = 1 / FPS;
1111
+ const duration = Math.max(...plan.map((s) => s.endTime));
1112
+ if (duration === 0) {
1113
+ const state = resolveStateAt(plan, initialFrom, 0, SAMPLE_RATE);
1114
+ const style = createStyleSheet(state);
1115
+ return [
1116
+ { offset: 0, ...style },
1117
+ { offset: 1, ...style }
1118
+ ];
1119
+ }
1120
+ const timePoints = /* @__PURE__ */ new Set([0, duration]);
1121
+ for (const seg of plan) {
1122
+ timePoints.add(seg.startTime);
1123
+ timePoints.add(seg.endTime);
1124
+ }
1125
+ const sortedTimes = Array.from(timePoints).sort((a2, b) => a2 - b);
1126
+ const keyframes = [];
1127
+ const getEasingForInterval = (t, nextT) => {
1128
+ const activeSegments = plan.filter(
1129
+ (s) => s.startTime <= t && s.endTime >= nextT
1130
+ );
1131
+ if (activeSegments.length === 0) return "linear";
1132
+ const timings = activeSegments.map((s) => s.node.props.timing).filter((t2) => t2 !== void 0);
1133
+ if (timings.length === 0) return "linear";
1134
+ const firstTiming = timings[0];
1135
+ const allSame = timings.every((t2) => t2 === firstTiming);
1136
+ if (allSame && firstTiming instanceof TimingFunction) {
1137
+ return compileTiming(firstTiming);
1138
+ }
1139
+ return null;
1140
+ };
1141
+ for (let i = 0; i < sortedTimes.length; i++) {
1142
+ const currT = sortedTimes[i];
1143
+ const state = resolveStateAt(plan, initialFrom, currT, SAMPLE_RATE);
1144
+ const style = createStyleSheet(state);
1145
+ const keyframe = {
1146
+ offset: currT / duration,
1147
+ ...style
1148
+ };
1149
+ keyframes.push(keyframe);
1150
+ if (i < sortedTimes.length - 1) {
1151
+ const nextT = sortedTimes[i + 1];
1152
+ const easing = getEasingForInterval(currT, nextT);
1153
+ if (easing === null) {
1154
+ let sampleT = currT + SAMPLE_RATE;
1155
+ while (sampleT < nextT) {
1156
+ const sampleState = resolveStateAt(
1157
+ plan,
1158
+ initialFrom,
1159
+ sampleT,
1160
+ SAMPLE_RATE
1161
+ );
1162
+ const sampleStyle = createStyleSheet(
1163
+ sampleState
1164
+ );
1165
+ keyframes.push({
1166
+ offset: sampleT / duration,
1167
+ ...sampleStyle,
1168
+ easing: "linear"
1169
+ });
1170
+ sampleT += SAMPLE_RATE;
1171
+ }
1172
+ keyframe.easing = "linear";
1173
+ } else {
1174
+ keyframe.easing = easing;
1175
+ }
1176
+ }
1177
+ }
1178
+ return keyframes;
1179
+ }
1180
+
1181
+ // src/ani/waapi/timeline.ts
1182
+ var WebAniTimeline = class extends TimelineBase {
1183
+ constructor(rootNode) {
1184
+ super(rootNode);
1185
+ this._animation = null;
1186
+ this._keyframes = [];
1187
+ }
1188
+ /**
1189
+ * Plays animation.
1190
+ * @param target Target element.
1191
+ * @param config {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API Web Animations API} based config.
1192
+ */
1193
+ play(target, config) {
1194
+ if (this._animation) {
1195
+ this._animation.cancel();
1196
+ }
1197
+ this._currentExecutionPlan = this._resolveExecutionPlan(
1198
+ config.keyframes,
1199
+ config.durations
1200
+ );
1201
+ this._keyframes = compileToKeyframes(
1202
+ this._currentExecutionPlan,
1203
+ config.from
1204
+ );
1205
+ if (this._keyframes.length === 0) {
1206
+ return null;
1207
+ }
1208
+ const totalDurationMs = this._currentExecutionPlan.reduce(
1209
+ (max, seg) => Math.max(max, seg.endTime),
1210
+ 0
1211
+ ) * 1e3;
1212
+ const effect = new KeyframeEffect(target, this._keyframes, {
1213
+ duration: totalDurationMs,
1214
+ iterations: config.repeat ?? 1,
1215
+ delay: config.delay ?? 0,
1216
+ fill: "forwards"
1217
+ });
1218
+ this._animation = new Animation(effect, document.timeline);
1219
+ this._animation.play();
1220
+ return this._animation;
1221
+ }
1222
+ pause() {
1223
+ this._animation?.pause();
1224
+ }
1225
+ resume() {
1226
+ this._animation?.play();
1227
+ }
1228
+ reset() {
1229
+ this._animation?.cancel();
1230
+ this._animation = null;
1231
+ }
1232
+ seek(targetTime) {
1233
+ if (this._animation) {
1234
+ this._animation.currentTime = targetTime * 1e3;
1235
+ }
1236
+ }
1237
+ /**
1238
+ * Native animation object.
1239
+ *
1240
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Animation Animation}.
1241
+ */
1242
+ get nativeAnimation() {
1243
+ return this._animation;
1244
+ }
1245
+ };
1246
+ function webTimeline(rootNode) {
1247
+ return new WebAniTimeline(rootNode);
1248
+ }
1249
+
1250
+ // src/event/manager.ts
1251
+ var EventManager = class _EventManager {
1252
+ constructor(supportedEvents) {
1253
+ this.supportedEvents = supportedEvents;
1254
+ this._element = null;
1255
+ this._animeGetter = null;
1256
+ this.setAnimeGetter = (animeGetter) => {
1257
+ this._animeGetter = animeGetter;
1258
+ };
1259
+ this.eventMap = /* @__PURE__ */ new Map();
1260
+ this.withAnimeValue = (listener) => {
1261
+ const withAnime = (e) => {
1262
+ listener(this.animeGetter(), e);
1263
+ };
1264
+ return withAnime;
1265
+ };
1266
+ this.add = (eventName, listener, options) => {
1267
+ const withAnime = this.withAnimeValue(listener);
1268
+ this.eventMap.set(eventName, withAnime);
1269
+ this.targetElement.addEventListener(
1270
+ eventName,
1271
+ this.eventMap.get(eventName),
1272
+ options
1273
+ );
1274
+ };
1275
+ this.cleanupOne = (eventName) => {
1276
+ const removeListener = this.eventMap.get(eventName);
1277
+ if (!removeListener) return false;
1278
+ this.targetElement.removeEventListener(eventName, removeListener);
1279
+ return true;
1280
+ };
1281
+ this.cleanupAll = () => {
1282
+ const clearResponse = [];
1283
+ for (const evtName of this.eventMap.keys()) {
1284
+ const res = this.cleanupOne(evtName);
1285
+ clearResponse.push(res);
1286
+ }
1287
+ return clearResponse.some((t) => t === false) === false;
1288
+ };
1289
+ this.attach = (handlers) => {
1290
+ Object.entries(handlers).forEach(([eventKey, handler]) => {
1291
+ this.add(
1292
+ _EventManager.getEvtKey(eventKey),
1293
+ handler
1294
+ );
1295
+ });
1296
+ };
1297
+ }
1298
+ get targetElement() {
1299
+ if (!this._element) throw new Error("EventManger, bind element first");
1300
+ return this._element;
1301
+ }
1302
+ get animeGetter() {
1303
+ if (!this._animeGetter)
1304
+ throw new Error("EventManager, animeGetter should be provided");
1305
+ return this._animeGetter;
1306
+ }
1307
+ /**
1308
+ * get pure `{event_name}`
1309
+ * @param key onX`{event_name}`
1310
+ */
1311
+ static getEvtKey(key) {
1312
+ const removed = key.substring(2, key.length);
1313
+ const Capitalized = `${removed[0].toLowerCase()}${removed.substring(1, key.length)}`;
1314
+ return Capitalized;
1315
+ }
1316
+ bind(element) {
1317
+ this._element = element;
1318
+ }
1319
+ };
1320
+
1047
1321
  // src/index.ts
1048
1322
  var a = {
1049
1323
  timing: T,
1324
+ dynamicTimeline: rafTimeline,
1325
+ timeline: webTimeline,
1326
+ /**
1327
+ * Create animation segment.
1328
+ */
1050
1329
  ani,
1051
- createStates,
1330
+ /**
1331
+ * Add delay
1332
+ */
1052
1333
  delay,
1053
1334
  loop,
1054
1335
  parallel,
1055
1336
  sequence,
1056
1337
  stagger,
1057
- timeline
1338
+ createStates
1058
1339
  };
1059
1340
  // Annotate the CommonJS export names for ESM import in node:
1060
1341
  0 && (module.exports = {
1061
1342
  AnimationClock,
1062
- AnimationNode,
1063
- CompositionNode,
1343
+ BezierTimingFunction,
1064
1344
  EventManager,
1065
1345
  LinearTimingFunction,
1066
- ParallelNode,
1067
- SegmentNode,
1068
- SequenceNode,
1069
- StaggerNode,
1346
+ RafAniTimeline,
1070
1347
  T,
1071
- Timeline,
1348
+ TimelineBase,
1072
1349
  TimingFunction,
1350
+ WebAniTimeline,
1073
1351
  a,
1074
- ani,
1352
+ calculateSegmentState,
1353
+ compileToKeyframes,
1075
1354
  createStates,
1076
1355
  createStyleSheet,
1077
- delay,
1078
- loop,
1079
- parallel,
1080
- sequence,
1081
- stagger,
1082
- timeline
1356
+ rafTimeline,
1357
+ webTimeline
1083
1358
  });
1084
- //# sourceMappingURL=index.cjs.map