@freestylejs/ani-core 1.1.0 → 1.2.1

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,196 +798,89 @@ 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
- this.reset(false);
882
+ const isPlaying = this._status === "PLAYING";
883
+ this.reset(false, !isPlaying);
743
884
  this._repeatCount = savedRepeatCount;
744
885
  if (isRepeating && this._repeatCount >= config.repeat) {
745
886
  this._repeatCount = 0;
@@ -753,8 +894,8 @@ var Timeline = class {
753
894
  config.keyframes,
754
895
  config.durations
755
896
  );
756
- const { keyMap: keys, values } = this._resolveGroup(config.from);
757
- this._propertyKeyMap = keys;
897
+ const { keyMap, values } = resolveGroup(config.from);
898
+ this._propertyKeyMap = keyMap;
758
899
  this._state = values;
759
900
  this._initialState = values;
760
901
  this._status = "PLAYING";
@@ -770,7 +911,7 @@ var Timeline = class {
770
911
  this._status = "PLAYING";
771
912
  this._clock.subscribe(this);
772
913
  }
773
- reset(notify = true) {
914
+ reset(notify = true, unsubscribeClock = true) {
774
915
  this._status = "IDLE";
775
916
  this._currentConfig = null;
776
917
  this._masterTime = 0;
@@ -778,13 +919,12 @@ var Timeline = class {
778
919
  this._state = [];
779
920
  this._initialState = [];
780
921
  this._propertyKeyMap = null;
781
- this._segmentStartStates.clear();
782
922
  this._currentExecutionPlan = null;
783
- this._clock.unsubscribe(this);
784
- this._repeatCount = 0;
785
- if (notify) {
786
- this.notify();
923
+ if (unsubscribeClock) {
924
+ this._clock.unsubscribe(this);
787
925
  }
926
+ this._repeatCount = 0;
927
+ if (notify) this.notify();
788
928
  }
789
929
  seek(targetTime) {
790
930
  if (this._status === "PLAYING" || this._status === "ENDED") {
@@ -795,87 +935,50 @@ var Timeline = class {
795
935
  this._state = this._calculateStateAtTime(seekTime, 0);
796
936
  this.notify();
797
937
  }
798
- getCurrentValue() {
799
- if (this._state.length === 0) return null;
800
- return this._resolveStateToGroup(this._state);
801
- }
938
+ /**
939
+ * When timeline updates, subscribes on update callback.
940
+ * @param callback Subscription callback.
941
+ * @returns Unsubscribe.
942
+ */
802
943
  onUpdate(callback) {
803
944
  this._onUpdateCallbacks.add(callback);
804
945
  return () => {
805
946
  this._onUpdateCallbacks.delete(callback);
806
947
  };
807
948
  }
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
949
  };
845
- function timeline(rootNode, clock) {
846
- return new Timeline(rootNode, clock);
950
+ function rafTimeline(rootNode, clock) {
951
+ return new RafAniTimeline(rootNode, clock);
847
952
  }
848
953
 
849
- // src/ani/states.ts
954
+ // src/ani/raf/states.ts
850
955
  function createStates(config) {
851
956
  let State = config.initial;
852
- let Timeline2 = timeline(
957
+ let Timeline = rafTimeline(
853
958
  config.states[State],
854
959
  config.clock
855
960
  );
856
961
  const subs = /* @__PURE__ */ new Set();
857
- const notify = (timeline2) => {
962
+ const notify = (timeline) => {
858
963
  for (const Sub of subs) {
859
- Sub(timeline2);
964
+ Sub(timeline);
860
965
  }
861
966
  };
862
967
  return {
863
- timeline: () => Timeline2,
968
+ timeline: () => Timeline,
969
+ state: () => State,
864
970
  onTimelineChange(callback) {
865
971
  subs.add(callback);
866
972
  return () => subs.delete(callback);
867
973
  },
868
974
  transitionTo(newState, timelineConfig, canBeIntercepted) {
869
- if (!config.states[newState] || State === newState) {
870
- return;
871
- }
872
975
  const from = timelineConfig?.from ?? // 1. config
873
- Timeline2.getCurrentValue() ?? // 2. last value
976
+ Timeline.getCurrentValue() ?? // 2. last value
874
977
  config.initialFrom;
875
978
  State = newState;
876
- Timeline2 = timeline(config.states[State], config.clock);
877
- notify(Timeline2);
878
- Timeline2.play(
979
+ Timeline = rafTimeline(config.states[State], config.clock);
980
+ notify(Timeline);
981
+ Timeline.play(
879
982
  {
880
983
  ...timelineConfig,
881
984
  from
@@ -886,77 +989,6 @@ function createStates(config) {
886
989
  };
887
990
  }
888
991
 
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
992
  // src/style/create_sheet.ts
961
993
  var TransformFunctionMap = {
962
994
  // deg
@@ -1044,41 +1076,286 @@ function createStyleSheet(animeStyleValue, resolver) {
1044
1076
  return styleAccumulator;
1045
1077
  }
1046
1078
 
1079
+ // src/ani/waapi/compiler/resolver.ts
1080
+ function resolveStateAt(plan, initialFrom, targetTime, dt) {
1081
+ const { keyMap, values: initialValues } = resolveGroup(initialFrom);
1082
+ const rawResultState = resolvePlanState(
1083
+ plan,
1084
+ initialValues,
1085
+ keyMap,
1086
+ targetTime,
1087
+ dt
1088
+ );
1089
+ return resolveStateToGroup(rawResultState, keyMap);
1090
+ }
1091
+
1092
+ // src/ani/waapi/compiler/timing_compiler.ts
1093
+ function compileTiming(timing) {
1094
+ if (!timing) {
1095
+ return "linear";
1096
+ }
1097
+ if (timing instanceof LinearTimingFunction) {
1098
+ return "linear";
1099
+ }
1100
+ if (timing instanceof BezierTimingFunction) {
1101
+ const { p2, p3 } = timing.opt;
1102
+ return `cubic-bezier(${p2.x}, ${p2.y}, ${p3.x}, ${p3.y})`;
1103
+ }
1104
+ return null;
1105
+ }
1106
+
1107
+ // src/ani/waapi/compiler/keyframe_compiler.ts
1108
+ function compileToKeyframes(plan, initialFrom) {
1109
+ if (plan.length === 0) {
1110
+ return [];
1111
+ }
1112
+ const FPS = 60;
1113
+ const SAMPLE_RATE = 1 / FPS;
1114
+ const duration = Math.max(...plan.map((s) => s.endTime));
1115
+ if (duration === 0) {
1116
+ const state = resolveStateAt(plan, initialFrom, 0, SAMPLE_RATE);
1117
+ const style = createStyleSheet(state);
1118
+ return [
1119
+ { offset: 0, ...style },
1120
+ { offset: 1, ...style }
1121
+ ];
1122
+ }
1123
+ const timePoints = /* @__PURE__ */ new Set([0, duration]);
1124
+ for (const seg of plan) {
1125
+ timePoints.add(seg.startTime);
1126
+ timePoints.add(seg.endTime);
1127
+ }
1128
+ const sortedTimes = Array.from(timePoints).sort((a2, b) => a2 - b);
1129
+ const keyframes = [];
1130
+ const getEasingForInterval = (t, nextT) => {
1131
+ const activeSegments = plan.filter(
1132
+ (s) => s.startTime <= t && s.endTime >= nextT
1133
+ );
1134
+ if (activeSegments.length === 0) return "linear";
1135
+ const timings = activeSegments.map((s) => s.node.props.timing).filter((t2) => t2 !== void 0);
1136
+ if (timings.length === 0) return "linear";
1137
+ const firstTiming = timings[0];
1138
+ const allSame = timings.every((t2) => t2 === firstTiming);
1139
+ if (allSame && firstTiming instanceof TimingFunction) {
1140
+ return compileTiming(firstTiming);
1141
+ }
1142
+ return null;
1143
+ };
1144
+ for (let i = 0; i < sortedTimes.length; i++) {
1145
+ const currT = sortedTimes[i];
1146
+ const state = resolveStateAt(plan, initialFrom, currT, SAMPLE_RATE);
1147
+ const style = createStyleSheet(state);
1148
+ const keyframe = {
1149
+ offset: currT / duration,
1150
+ ...style
1151
+ };
1152
+ keyframes.push(keyframe);
1153
+ if (i < sortedTimes.length - 1) {
1154
+ const nextT = sortedTimes[i + 1];
1155
+ const easing = getEasingForInterval(currT, nextT);
1156
+ if (easing === null) {
1157
+ let sampleT = currT + SAMPLE_RATE;
1158
+ while (sampleT < nextT) {
1159
+ const sampleState = resolveStateAt(
1160
+ plan,
1161
+ initialFrom,
1162
+ sampleT,
1163
+ SAMPLE_RATE
1164
+ );
1165
+ const sampleStyle = createStyleSheet(
1166
+ sampleState
1167
+ );
1168
+ keyframes.push({
1169
+ offset: sampleT / duration,
1170
+ ...sampleStyle,
1171
+ easing: "linear"
1172
+ });
1173
+ sampleT += SAMPLE_RATE;
1174
+ }
1175
+ keyframe.easing = "linear";
1176
+ } else {
1177
+ keyframe.easing = easing;
1178
+ }
1179
+ }
1180
+ }
1181
+ return keyframes;
1182
+ }
1183
+
1184
+ // src/ani/waapi/timeline.ts
1185
+ var WebAniTimeline = class extends TimelineBase {
1186
+ constructor(rootNode) {
1187
+ super(rootNode);
1188
+ this._animation = null;
1189
+ this._keyframes = [];
1190
+ }
1191
+ /**
1192
+ * Plays animation.
1193
+ * @param target Target element.
1194
+ * @param config {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API Web Animations API} based config.
1195
+ */
1196
+ play(target, config) {
1197
+ if (this._animation) {
1198
+ this._animation.cancel();
1199
+ }
1200
+ this._currentExecutionPlan = this._resolveExecutionPlan(
1201
+ config.keyframes,
1202
+ config.durations
1203
+ );
1204
+ this._keyframes = compileToKeyframes(
1205
+ this._currentExecutionPlan,
1206
+ config.from
1207
+ );
1208
+ if (this._keyframes.length === 0) {
1209
+ return null;
1210
+ }
1211
+ const totalDurationMs = this._currentExecutionPlan.reduce(
1212
+ (max, seg) => Math.max(max, seg.endTime),
1213
+ 0
1214
+ ) * 1e3;
1215
+ const effect = new KeyframeEffect(target, this._keyframes, {
1216
+ duration: totalDurationMs,
1217
+ iterations: config.repeat ?? 1,
1218
+ delay: config.delay ?? 0,
1219
+ fill: "forwards"
1220
+ });
1221
+ this._animation = new Animation(effect, document.timeline);
1222
+ this._animation.play();
1223
+ return this._animation;
1224
+ }
1225
+ pause() {
1226
+ this._animation?.pause();
1227
+ }
1228
+ resume() {
1229
+ this._animation?.play();
1230
+ }
1231
+ reset() {
1232
+ this._animation?.cancel();
1233
+ this._animation = null;
1234
+ }
1235
+ seek(targetTime) {
1236
+ if (this._animation) {
1237
+ this._animation.currentTime = targetTime * 1e3;
1238
+ }
1239
+ }
1240
+ /**
1241
+ * Native animation object.
1242
+ *
1243
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Animation Animation}.
1244
+ */
1245
+ get nativeAnimation() {
1246
+ return this._animation;
1247
+ }
1248
+ };
1249
+ function webTimeline(rootNode) {
1250
+ return new WebAniTimeline(rootNode);
1251
+ }
1252
+
1253
+ // src/event/manager.ts
1254
+ var EventManager = class _EventManager {
1255
+ constructor(supportedEvents) {
1256
+ this.supportedEvents = supportedEvents;
1257
+ this._element = null;
1258
+ this._animeGetter = null;
1259
+ this.setAnimeGetter = (animeGetter) => {
1260
+ this._animeGetter = animeGetter;
1261
+ };
1262
+ this.eventMap = /* @__PURE__ */ new Map();
1263
+ this.withAnimeValue = (listener) => {
1264
+ const withAnime = (e) => {
1265
+ listener(this.animeGetter(), e);
1266
+ };
1267
+ return withAnime;
1268
+ };
1269
+ this.add = (eventName, listener, options) => {
1270
+ const withAnime = this.withAnimeValue(listener);
1271
+ this.eventMap.set(eventName, withAnime);
1272
+ this.targetElement.addEventListener(
1273
+ eventName,
1274
+ this.eventMap.get(eventName),
1275
+ options
1276
+ );
1277
+ };
1278
+ this.cleanupOne = (eventName) => {
1279
+ const removeListener = this.eventMap.get(eventName);
1280
+ if (!removeListener) return false;
1281
+ this.targetElement.removeEventListener(eventName, removeListener);
1282
+ return true;
1283
+ };
1284
+ this.cleanupAll = () => {
1285
+ const clearResponse = [];
1286
+ for (const evtName of this.eventMap.keys()) {
1287
+ const res = this.cleanupOne(evtName);
1288
+ clearResponse.push(res);
1289
+ }
1290
+ return clearResponse.some((t) => t === false) === false;
1291
+ };
1292
+ this.attach = (handlers) => {
1293
+ Object.entries(handlers).forEach(([eventKey, handler]) => {
1294
+ this.add(
1295
+ _EventManager.getEvtKey(eventKey),
1296
+ handler
1297
+ );
1298
+ });
1299
+ };
1300
+ }
1301
+ get targetElement() {
1302
+ if (!this._element) throw new Error("EventManger, bind element first");
1303
+ return this._element;
1304
+ }
1305
+ get animeGetter() {
1306
+ if (!this._animeGetter)
1307
+ throw new Error("EventManager, animeGetter should be provided");
1308
+ return this._animeGetter;
1309
+ }
1310
+ /**
1311
+ * get pure `{event_name}`
1312
+ * @param key onX`{event_name}`
1313
+ */
1314
+ static getEvtKey(key) {
1315
+ const removed = key.substring(2, key.length);
1316
+ const Capitalized = `${removed[0].toLowerCase()}${removed.substring(1, key.length)}`;
1317
+ return Capitalized;
1318
+ }
1319
+ bind(element) {
1320
+ this._element = element;
1321
+ }
1322
+ };
1323
+
1047
1324
  // src/index.ts
1048
1325
  var a = {
1049
1326
  timing: T,
1327
+ dynamicTimeline: rafTimeline,
1328
+ timeline: webTimeline,
1329
+ /**
1330
+ * Create animation segment.
1331
+ */
1050
1332
  ani,
1051
- createStates,
1333
+ /**
1334
+ * Add delay
1335
+ */
1052
1336
  delay,
1053
1337
  loop,
1054
1338
  parallel,
1055
1339
  sequence,
1056
1340
  stagger,
1057
- timeline
1341
+ createStates
1058
1342
  };
1059
1343
  // Annotate the CommonJS export names for ESM import in node:
1060
1344
  0 && (module.exports = {
1061
1345
  AnimationClock,
1062
- AnimationNode,
1063
- CompositionNode,
1346
+ BezierTimingFunction,
1064
1347
  EventManager,
1065
1348
  LinearTimingFunction,
1066
- ParallelNode,
1067
- SegmentNode,
1068
- SequenceNode,
1069
- StaggerNode,
1349
+ RafAniTimeline,
1070
1350
  T,
1071
- Timeline,
1351
+ TimelineBase,
1072
1352
  TimingFunction,
1353
+ WebAniTimeline,
1073
1354
  a,
1074
- ani,
1355
+ calculateSegmentState,
1356
+ compileToKeyframes,
1075
1357
  createStates,
1076
1358
  createStyleSheet,
1077
- delay,
1078
- loop,
1079
- parallel,
1080
- sequence,
1081
- stagger,
1082
- timeline
1359
+ rafTimeline,
1360
+ webTimeline
1083
1361
  });
1084
- //# sourceMappingURL=index.cjs.map