motion 10.11.1 → 10.13.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.
@@ -56,12 +56,20 @@
56
56
  };
57
57
 
58
58
  const isNumber = (value) => typeof value === "number";
59
- const isString = (value) => typeof value === "string";
60
- const isEasingGenerator = (easing) => typeof easing === "object" &&
61
- Boolean(easing.createAnimation);
62
- const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
59
+
63
60
  const isEasingList = (easing) => Array.isArray(easing) && !isNumber(easing[0]);
64
61
 
62
+ const wrap = (min, max, v) => {
63
+ const rangeSize = max - min;
64
+ return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
65
+ };
66
+
67
+ function getEasingForSegment(easing, i) {
68
+ return isEasingList(easing)
69
+ ? easing[wrap(0, easing.length, i)]
70
+ : easing;
71
+ }
72
+
65
73
  const mix = (min, max, progress) => -progress * min + progress * max + min;
66
74
 
67
75
  const noop = () => { };
@@ -76,12 +84,44 @@
76
84
  offset.push(mix(min, 1, offsetProgress));
77
85
  }
78
86
  }
79
- function defaultOffset(length) {
87
+ function defaultOffset$1(length) {
80
88
  const offset = [0];
81
89
  fillOffset(offset, length - 1);
82
90
  return offset;
83
91
  }
84
92
 
93
+ function interpolate(output, input = defaultOffset$1(output.length), easing = noopReturn) {
94
+ const length = output.length;
95
+ /**
96
+ * If the input length is lower than the output we
97
+ * fill the input to match. This currently assumes the input
98
+ * is an animation progress value so is a good candidate for
99
+ * moving outside the function.
100
+ */
101
+ const remainder = length - input.length;
102
+ remainder > 0 && fillOffset(input, remainder);
103
+ return (t) => {
104
+ let i = 0;
105
+ for (; i < length - 2; i++) {
106
+ if (t < input[i + 1])
107
+ break;
108
+ }
109
+ let progressInRange = clamp(0, 1, progress(input[i], input[i + 1], t));
110
+ const segmentEasing = getEasingForSegment(easing, i);
111
+ progressInRange = segmentEasing(progressInRange);
112
+ return mix(output[i], output[i + 1], progressInRange);
113
+ };
114
+ }
115
+
116
+ const isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
117
+
118
+ const isEasingGenerator = (easing) => typeof easing === "object" &&
119
+ Boolean(easing.createAnimation);
120
+
121
+ const isFunction = (value) => typeof value === "function";
122
+
123
+ const isString = (value) => typeof value === "string";
124
+
85
125
  const time = {
86
126
  ms: (seconds) => seconds * 1000,
87
127
  s: (milliseconds) => milliseconds / 1000,
@@ -97,11 +137,6 @@
97
137
  return frameDuration ? velocity * (1000 / frameDuration) : 0;
98
138
  }
99
139
 
100
- const wrap = (min, max, v) => {
101
- const rangeSize = max - min;
102
- return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
103
- };
104
-
105
140
  /**
106
141
  * A list of all transformable axes. We'll use this list to generated a version
107
142
  * of each axes for each transform.
@@ -264,7 +299,7 @@
264
299
  const functionArgsRegex = /\((.*?)\)/;
265
300
  function getEasingFunction(definition) {
266
301
  // If already an easing function, return
267
- if (typeof definition === "function")
302
+ if (isFunction(definition))
268
303
  return definition;
269
304
  // If an easing curve definition, return bezier function
270
305
  if (Array.isArray(definition))
@@ -282,67 +317,46 @@
282
317
  }
283
318
  return noopReturn;
284
319
  }
285
- function getEasingForSegment(easing, i) {
286
- return isEasingList(easing)
287
- ? easing[wrap(0, easing.length, i)]
288
- : easing;
289
- }
290
-
291
- const clampProgress = (p) => Math.min(1, Math.max(p, 0));
292
- function interpolate(output, input = defaultOffset(output.length), easing = noopReturn) {
293
- const length = output.length;
294
- /**
295
- * If the input length is lower than the output we
296
- * fill the input to match. This currently assumes the input
297
- * is an animation progress value so is a good candidate for
298
- * moving outside the function.
299
- */
300
- const remainder = length - input.length;
301
- remainder > 0 && fillOffset(input, remainder);
302
- return (t) => {
303
- let i = 0;
304
- for (; i < length - 2; i++) {
305
- if (t < input[i + 1])
306
- break;
307
- }
308
- let progressInRange = clampProgress(progress(input[i], input[i + 1], t));
309
- const segmentEasing = getEasingForSegment(easing, i);
310
- progressInRange = segmentEasing(progressInRange);
311
- return mix(output[i], output[i + 1], progressInRange);
312
- };
313
- }
314
320
 
315
321
  class Animation {
316
- constructor(output, keyframes = [0, 1], { easing = defaults$1.easing, duration = defaults$1.duration, delay = defaults$1.delay, endDelay = defaults$1.endDelay, repeat = defaults$1.repeat, offset, direction = "normal", } = {}) {
322
+ constructor(output, keyframes = [0, 1], { easing, duration: initialDuration = defaults$1.duration, delay = defaults$1.delay, endDelay = defaults$1.endDelay, repeat = defaults$1.repeat, offset, direction = "normal", } = {}) {
317
323
  this.startTime = null;
318
324
  this.rate = 1;
319
325
  this.t = 0;
320
326
  this.cancelTimestamp = null;
327
+ this.easing = noopReturn;
328
+ this.duration = 0;
329
+ this.totalDuration = 0;
330
+ this.repeat = 0;
321
331
  this.playState = "idle";
322
332
  this.finished = new Promise((resolve, reject) => {
323
333
  this.resolve = resolve;
324
334
  this.reject = reject;
325
335
  });
336
+ easing = easing || defaults$1.easing;
326
337
  if (isEasingGenerator(easing)) {
327
338
  const custom = easing.createAnimation(keyframes, () => "0", true);
328
339
  easing = custom.easing;
329
340
  if (custom.keyframes !== undefined)
330
341
  keyframes = custom.keyframes;
331
342
  if (custom.duration !== undefined)
332
- duration = custom.duration;
343
+ initialDuration = custom.duration;
333
344
  }
334
- const animationEasing = isEasingList(easing)
335
- ? noopReturn
336
- : getEasingFunction(easing);
337
- const totalDuration = duration * (repeat + 1);
345
+ this.repeat = repeat;
346
+ this.easing = isEasingList(easing) ? noopReturn : getEasingFunction(easing);
347
+ this.updateDuration(initialDuration);
338
348
  const interpolate$1 = interpolate(keyframes, offset, isEasingList(easing) ? easing.map(getEasingFunction) : noopReturn);
339
349
  this.tick = (timestamp) => {
340
350
  var _a;
341
351
  // TODO: Temporary fix for OptionsResolver typing
342
352
  delay = delay;
343
- if (this.pauseTime)
344
- timestamp = this.pauseTime;
345
- let t = (timestamp - this.startTime) * this.rate;
353
+ let t = 0;
354
+ if (this.pauseTime !== undefined) {
355
+ t = this.pauseTime;
356
+ }
357
+ else {
358
+ t = (timestamp - this.startTime) * this.rate;
359
+ }
346
360
  this.t = t;
347
361
  // Convert to seconds
348
362
  t /= 1000;
@@ -352,14 +366,15 @@
352
366
  * If this animation has finished, set the current time
353
367
  * to the total duration.
354
368
  */
355
- if (this.playState === "finished")
356
- t = totalDuration;
369
+ if (this.playState === "finished" && this.pauseTime === undefined) {
370
+ t = this.totalDuration;
371
+ }
357
372
  /**
358
373
  * Get the current progress (0-1) of the animation. If t is >
359
374
  * than duration we'll get values like 2.5 (midway through the
360
375
  * third iteration)
361
376
  */
362
- const progress = t / duration;
377
+ const progress = t / this.duration;
363
378
  // TODO progress += iterationStart
364
379
  /**
365
380
  * Get the current iteration (0 indexed). For instance the floor of
@@ -388,10 +403,11 @@
388
403
  (direction === "alternate-reverse" && !iterationIsOdd)) {
389
404
  iterationProgress = 1 - iterationProgress;
390
405
  }
391
- const p = t >= totalDuration ? 1 : Math.min(iterationProgress, 1);
392
- const latest = interpolate$1(animationEasing(p));
406
+ const p = t >= this.totalDuration ? 1 : Math.min(iterationProgress, 1);
407
+ const latest = interpolate$1(this.easing(p));
393
408
  output(latest);
394
- const isAnimationFinished = this.playState === "finished" || t >= totalDuration + endDelay;
409
+ const isAnimationFinished = this.pauseTime === undefined &&
410
+ (this.playState === "finished" || t >= this.totalDuration + endDelay);
395
411
  if (isAnimationFinished) {
396
412
  this.playState = "finished";
397
413
  (_a = this.resolve) === null || _a === void 0 ? void 0 : _a.call(this, latest);
@@ -403,22 +419,21 @@
403
419
  this.play();
404
420
  }
405
421
  play() {
406
- var _a;
407
422
  const now = performance.now();
408
423
  this.playState = "running";
409
- if (this.pauseTime) {
410
- this.startTime = now - (this.pauseTime - ((_a = this.startTime) !== null && _a !== void 0 ? _a : 0));
424
+ if (this.pauseTime !== undefined) {
425
+ this.startTime = now - this.pauseTime;
411
426
  }
412
427
  else if (!this.startTime) {
413
428
  this.startTime = now;
414
429
  }
415
430
  this.cancelTimestamp = this.startTime;
416
431
  this.pauseTime = undefined;
417
- requestAnimationFrame(this.tick);
432
+ this.frameRequestId = requestAnimationFrame(this.tick);
418
433
  }
419
434
  pause() {
420
435
  this.playState = "paused";
421
- this.pauseTime = performance.now();
436
+ this.pauseTime = this.t;
422
437
  }
423
438
  finish() {
424
439
  this.playState = "finished";
@@ -440,11 +455,15 @@
440
455
  this.rate *= -1;
441
456
  }
442
457
  commitStyles() { }
458
+ updateDuration(duration) {
459
+ this.duration = duration;
460
+ this.totalDuration = duration * (this.repeat + 1);
461
+ }
443
462
  get currentTime() {
444
463
  return this.t;
445
464
  }
446
465
  set currentTime(t) {
447
- if (this.pauseTime || this.rate === 0) {
466
+ if (this.pauseTime !== undefined || this.rate === 0) {
448
467
  this.pauseTime = t;
449
468
  }
450
469
  else {
@@ -459,10 +478,7 @@
459
478
  }
460
479
  }
461
480
 
462
- const convertEasing = (easing) => isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
463
- const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
464
-
465
- const testAnimation = (keyframes) => document.createElement("div").animate(keyframes, { duration: 0.001 });
481
+ const testAnimation = (keyframes, options) => document.createElement("div").animate(keyframes, options);
466
482
  const featureTests = {
467
483
  cssRegisterProperty: () => typeof CSS !== "undefined" &&
468
484
  Object.hasOwnProperty.call(CSS, "registerProperty"),
@@ -476,7 +492,16 @@
476
492
  }
477
493
  return true;
478
494
  },
479
- finished: () => Boolean(testAnimation({ opacity: [0, 1] }).finished),
495
+ finished: () => Boolean(testAnimation({ opacity: [0, 1] }, { duration: 0.001 }).finished),
496
+ linearEasing: () => {
497
+ try {
498
+ testAnimation({ opacity: 0 }, { easing: "linear(0, 1)" });
499
+ }
500
+ catch (e) {
501
+ return false;
502
+ }
503
+ return true;
504
+ },
480
505
  };
481
506
  const results = {};
482
507
  const supports = {};
@@ -488,6 +513,28 @@
488
513
  };
489
514
  }
490
515
 
516
+ // Create a linear easing point for every x second
517
+ const resolution = 0.015;
518
+ const generateLinearEasingPoints = (easing, duration) => {
519
+ let points = "";
520
+ const numPoints = Math.round(duration / resolution);
521
+ for (let i = 0; i < numPoints; i++) {
522
+ points += easing(progress(0, numPoints - 1, i)) + ", ";
523
+ }
524
+ return points.substring(0, points.length - 2);
525
+ };
526
+ const convertEasing = (easing, duration) => {
527
+ if (isFunction(easing)) {
528
+ return supports.linearEasing()
529
+ ? `linear(${generateLinearEasingPoints(easing, duration)})`
530
+ : defaults$1.easing;
531
+ }
532
+ else {
533
+ return isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
534
+ }
535
+ };
536
+ const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
537
+
491
538
  function hydrateKeyframes(keyframes, readInitialValue) {
492
539
  for (let i = 0; i < keyframes.length; i++) {
493
540
  if (keyframes[i] === null) {
@@ -553,8 +600,8 @@
553
600
  let animation;
554
601
  let { duration = defaults$1.duration, delay = defaults$1.delay, endDelay = defaults$1.endDelay, repeat = defaults$1.repeat, easing = defaults$1.easing, direction, offset, allowWebkitAcceleration = false, } = options;
555
602
  const data = getAnimationData(element);
556
- let canAnimateNatively = supports.waapi();
557
603
  const valueIsTransform = isTransform(key);
604
+ let canAnimateNatively = supports.waapi();
558
605
  /**
559
606
  * If this is an individual transform, we need to map its
560
607
  * key to a CSS variable and update the element's transform style
@@ -607,8 +654,16 @@
607
654
  }
608
655
  }
609
656
  /**
610
- * If we can animate this value with WAAPI, do so. Currently this only
611
- * feature detects CSS.registerProperty but could check WAAPI too.
657
+ * If we've been passed a custom easing function, and this browser
658
+ * does **not** support linear() easing, and the value is a transform
659
+ * (and thus a pure number) we can still support the custom easing
660
+ * by falling back to the animation polyfill.
661
+ */
662
+ if (isFunction(easing) && !supports.linearEasing() && valueIsTransform) {
663
+ canAnimateNatively = false;
664
+ }
665
+ /**
666
+ * If we can animate this value with WAAPI, do so.
612
667
  */
613
668
  if (canAnimateNatively) {
614
669
  /**
@@ -630,7 +685,9 @@
630
685
  delay: time.ms(delay),
631
686
  duration: time.ms(duration),
632
687
  endDelay: time.ms(endDelay),
633
- easing: !isEasingList(easing) ? convertEasing(easing) : undefined,
688
+ easing: !isEasingList(easing)
689
+ ? convertEasing(easing, duration)
690
+ : undefined,
634
691
  direction,
635
692
  iterations: repeat + 1,
636
693
  fill: "both",
@@ -638,7 +695,9 @@
638
695
  animation = element.animate({
639
696
  [name]: keyframes,
640
697
  offset,
641
- easing: isEasingList(easing) ? easing.map(convertEasing) : undefined,
698
+ easing: isEasingList(easing)
699
+ ? easing.map((thisEasing) => convertEasing(thisEasing, duration))
700
+ : undefined,
642
701
  }, animationOptions);
643
702
  /**
644
703
  * Polyfill finished Promise in browsers that don't support it
@@ -744,10 +803,13 @@
744
803
  }
745
804
 
746
805
  const createAnimation = (factory) => factory();
747
- const wrapAnimationWithControls = (animationFactory, duration = defaults$1.duration) => new Proxy({
748
- animations: animationFactory.map(createAnimation).filter(Boolean),
749
- duration,
750
- }, controls);
806
+ const withControls = (animationFactory, options, duration = defaults$1.duration) => {
807
+ return new Proxy({
808
+ animations: animationFactory.map(createAnimation).filter(Boolean),
809
+ duration,
810
+ options,
811
+ }, controls);
812
+ };
751
813
  /**
752
814
  * TODO:
753
815
  * Currently this returns the first animation, ideally it would return
@@ -761,8 +823,7 @@
761
823
  case "duration":
762
824
  return target.duration;
763
825
  case "currentTime":
764
- let time = (activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) || 0;
765
- return time ? time / 1000 : 0;
826
+ return time.s((activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) || 0);
766
827
  case "playbackRate":
767
828
  case "playState":
768
829
  return activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key];
@@ -772,7 +833,17 @@
772
833
  }
773
834
  return target.finished;
774
835
  case "stop":
775
- return () => target.animations.forEach((animation) => stopAnimation(animation));
836
+ return () => {
837
+ target.animations.forEach((animation) => stopAnimation(animation));
838
+ };
839
+ case "forEachNative":
840
+ /**
841
+ * This is for internal use only, fire a callback for each
842
+ * underlying animation.
843
+ */
844
+ return (callback) => {
845
+ target.animations.forEach((animation) => callback(animation, target));
846
+ };
776
847
  default:
777
848
  return typeof (activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) === "undefined"
778
849
  ? undefined
@@ -818,9 +889,7 @@
818
889
  }
819
890
  }
820
891
  function resolveOption(option, i, total) {
821
- return typeof option === "function"
822
- ? option(i, total)
823
- : option;
892
+ return isFunction(option) ? option(i, total) : option;
824
893
  }
825
894
 
826
895
  function animate$1(elements, keyframes, options = {}) {
@@ -839,7 +908,7 @@
839
908
  animationFactories.push(animation);
840
909
  }
841
910
  }
842
- return wrapAnimationWithControls(animationFactories,
911
+ return withControls(animationFactories, options,
843
912
  /**
844
913
  * TODO:
845
914
  * If easing is set to spring or glide, duration will be dynamically
@@ -948,7 +1017,7 @@
948
1017
  const animationFactories = animationDefinitions
949
1018
  .map((definition) => animateStyle(...definition))
950
1019
  .filter(Boolean);
951
- return wrapAnimationWithControls(animationFactories,
1020
+ return withControls(animationFactories, options,
952
1021
  // Get the duration from the first animation definition
953
1022
  (_a = animationDefinitions[0]) === null || _a === void 0 ? void 0 : _a[3].duration);
954
1023
  }
@@ -1025,7 +1094,7 @@
1025
1094
  /**
1026
1095
  *
1027
1096
  */
1028
- let { offset = defaultOffset(valueKeyframes.length) } = valueOptions;
1097
+ let { offset = defaultOffset$1(valueKeyframes.length) } = valueOptions;
1029
1098
  /**
1030
1099
  * If there's only one offset of 0, fill in a second with length 1
1031
1100
  *
@@ -1373,24 +1442,11 @@
1373
1442
 
1374
1443
  const glide = createGeneratorEasing(glide$1);
1375
1444
 
1376
- let supportsDocumentRoot;
1377
- function getDefaultRoot() {
1378
- if (supportsDocumentRoot === undefined) {
1379
- try {
1380
- new IntersectionObserver(noop, { root: document });
1381
- supportsDocumentRoot = true;
1382
- }
1383
- catch (e) {
1384
- supportsDocumentRoot = false;
1385
- }
1386
- }
1387
- return supportsDocumentRoot ? document : undefined;
1388
- }
1389
1445
  const thresholds = {
1390
1446
  any: 0,
1391
1447
  all: 1,
1392
1448
  };
1393
- function inView(elements, onStart, { root, margin: rootMargin, amount = "any" } = {}) {
1449
+ function inView$1(elementOrSelector, onStart, { root, margin: rootMargin, amount = "any" } = {}) {
1394
1450
  /**
1395
1451
  * If this browser doesn't support IntersectionObserver, return a dummy stop function.
1396
1452
  * Default triggering of onStart is tricky - it could be used for starting/stopping
@@ -1400,7 +1456,7 @@
1400
1456
  if (typeof IntersectionObserver === "undefined") {
1401
1457
  return () => { };
1402
1458
  }
1403
- const resolvedElements = resolveElements(elements);
1459
+ const elements = resolveElements(elementOrSelector);
1404
1460
  const activeIntersections = new WeakMap();
1405
1461
  const onIntersectionChange = (entries) => {
1406
1462
  entries.forEach((entry) => {
@@ -1413,7 +1469,7 @@
1413
1469
  return;
1414
1470
  if (entry.isIntersecting) {
1415
1471
  const newOnEnd = onStart(entry);
1416
- if (typeof newOnEnd === "function") {
1472
+ if (isFunction(newOnEnd)) {
1417
1473
  activeIntersections.set(entry.target, newOnEnd);
1418
1474
  }
1419
1475
  else {
@@ -1427,36 +1483,820 @@
1427
1483
  });
1428
1484
  };
1429
1485
  const observer = new IntersectionObserver(onIntersectionChange, {
1430
- root: root || getDefaultRoot(),
1486
+ root,
1431
1487
  rootMargin,
1432
1488
  threshold: typeof amount === "number" ? amount : thresholds[amount],
1433
1489
  });
1434
- resolvedElements.forEach((element) => observer.observe(element));
1490
+ elements.forEach((element) => observer.observe(element));
1435
1491
  return () => observer.disconnect();
1436
1492
  }
1437
1493
 
1438
- function animateProgress(target, options) {
1439
- return wrapAnimationWithControls([
1494
+ const resizeHandlers = new WeakMap();
1495
+ let observer;
1496
+ function getElementSize(target, borderBoxSize) {
1497
+ if (borderBoxSize) {
1498
+ const { inlineSize, blockSize } = borderBoxSize[0];
1499
+ return { width: inlineSize, height: blockSize };
1500
+ }
1501
+ else if (target instanceof SVGElement && "getBBox" in target) {
1502
+ return target.getBBox();
1503
+ }
1504
+ else {
1505
+ return {
1506
+ width: target.offsetWidth,
1507
+ height: target.offsetHeight,
1508
+ };
1509
+ }
1510
+ }
1511
+ function notifyTarget({ target, contentRect, borderBoxSize, }) {
1512
+ var _a;
1513
+ (_a = resizeHandlers.get(target)) === null || _a === void 0 ? void 0 : _a.forEach((handler) => {
1514
+ handler({
1515
+ target,
1516
+ contentSize: contentRect,
1517
+ get size() {
1518
+ return getElementSize(target, borderBoxSize);
1519
+ },
1520
+ });
1521
+ });
1522
+ }
1523
+ function notifyAll(entries) {
1524
+ entries.forEach(notifyTarget);
1525
+ }
1526
+ function createResizeObserver() {
1527
+ if (typeof ResizeObserver === "undefined")
1528
+ return;
1529
+ observer = new ResizeObserver(notifyAll);
1530
+ }
1531
+ function resizeElement(target, handler) {
1532
+ if (!observer)
1533
+ createResizeObserver();
1534
+ const elements = resolveElements(target);
1535
+ elements.forEach((element) => {
1536
+ let elementHandlers = resizeHandlers.get(element);
1537
+ if (!elementHandlers) {
1538
+ elementHandlers = new Set();
1539
+ resizeHandlers.set(element, elementHandlers);
1540
+ }
1541
+ elementHandlers.add(handler);
1542
+ observer === null || observer === void 0 ? void 0 : observer.observe(element);
1543
+ });
1544
+ return () => {
1545
+ elements.forEach((element) => {
1546
+ const elementHandlers = resizeHandlers.get(element);
1547
+ elementHandlers === null || elementHandlers === void 0 ? void 0 : elementHandlers.delete(handler);
1548
+ if (!(elementHandlers === null || elementHandlers === void 0 ? void 0 : elementHandlers.size)) {
1549
+ observer === null || observer === void 0 ? void 0 : observer.unobserve(element);
1550
+ }
1551
+ });
1552
+ };
1553
+ }
1554
+
1555
+ const windowCallbacks = new Set();
1556
+ let windowResizeHandler;
1557
+ function createWindowResizeHandler() {
1558
+ windowResizeHandler = () => {
1559
+ const size = {
1560
+ width: window.innerWidth,
1561
+ height: window.innerHeight,
1562
+ };
1563
+ const info = {
1564
+ target: window,
1565
+ size,
1566
+ contentSize: size,
1567
+ };
1568
+ windowCallbacks.forEach((callback) => callback(info));
1569
+ };
1570
+ window.addEventListener("resize", windowResizeHandler);
1571
+ }
1572
+ function resizeWindow(callback) {
1573
+ windowCallbacks.add(callback);
1574
+ if (!windowResizeHandler)
1575
+ createWindowResizeHandler();
1576
+ return () => {
1577
+ windowCallbacks.delete(callback);
1578
+ if (!windowCallbacks.size && windowResizeHandler) {
1579
+ windowResizeHandler = undefined;
1580
+ }
1581
+ };
1582
+ }
1583
+
1584
+ function resize(a, b) {
1585
+ return isFunction(a) ? resizeWindow(a) : resizeElement(a, b);
1586
+ }
1587
+
1588
+ /**
1589
+ * A time in milliseconds, beyond which we consider the scroll velocity to be 0.
1590
+ */
1591
+ const maxElapsed = 50;
1592
+ const createAxisInfo = () => ({
1593
+ current: 0,
1594
+ offset: [],
1595
+ progress: 0,
1596
+ scrollLength: 0,
1597
+ targetOffset: 0,
1598
+ targetLength: 0,
1599
+ containerLength: 0,
1600
+ velocity: 0,
1601
+ });
1602
+ const createScrollInfo = () => ({
1603
+ time: 0,
1604
+ x: createAxisInfo(),
1605
+ y: createAxisInfo(),
1606
+ });
1607
+ const keys = {
1608
+ x: {
1609
+ length: "Width",
1610
+ position: "Left",
1611
+ },
1612
+ y: {
1613
+ length: "Height",
1614
+ position: "Top",
1615
+ },
1616
+ };
1617
+ function updateAxisInfo(element, axisName, info, time) {
1618
+ const axis = info[axisName];
1619
+ const { length, position } = keys[axisName];
1620
+ const prev = axis.current;
1621
+ const prevTime = info.time;
1622
+ axis.current = element["scroll" + position];
1623
+ axis.scrollLength = element["scroll" + length] - element["client" + length];
1624
+ axis.offset.length = 0;
1625
+ axis.offset[0] = 0;
1626
+ axis.offset[1] = axis.scrollLength;
1627
+ axis.progress = progress(0, axis.scrollLength, axis.current);
1628
+ const elapsed = time - prevTime;
1629
+ axis.velocity =
1630
+ elapsed > maxElapsed ? 0 : velocityPerSecond(axis.current - prev, elapsed);
1631
+ }
1632
+ function updateScrollInfo(element, info, time) {
1633
+ updateAxisInfo(element, "x", info, time);
1634
+ updateAxisInfo(element, "y", info, time);
1635
+ info.time = time;
1636
+ }
1637
+
1638
+ function calcInset(element, container) {
1639
+ let inset = { x: 0, y: 0 };
1640
+ let current = element;
1641
+ while (current && current !== container) {
1642
+ if (current instanceof HTMLElement) {
1643
+ inset.x += current.offsetLeft;
1644
+ inset.y += current.offsetTop;
1645
+ current = current.offsetParent;
1646
+ }
1647
+ else if (current instanceof SVGGraphicsElement && "getBBox" in current) {
1648
+ const { top, left } = current.getBBox();
1649
+ inset.x += left;
1650
+ inset.y += top;
1651
+ /**
1652
+ * Assign the next parent element as the <svg /> tag.
1653
+ */
1654
+ while (current && current.tagName !== "svg") {
1655
+ current = current.parentNode;
1656
+ }
1657
+ }
1658
+ }
1659
+ return inset;
1660
+ }
1661
+
1662
+ const ScrollOffset = {
1663
+ Enter: [
1664
+ [0, 1],
1665
+ [1, 1],
1666
+ ],
1667
+ Exit: [
1668
+ [0, 0],
1669
+ [1, 0],
1670
+ ],
1671
+ Any: [
1672
+ [1, 0],
1673
+ [0, 1],
1674
+ ],
1675
+ All: [
1676
+ [0, 0],
1677
+ [1, 1],
1678
+ ],
1679
+ };
1680
+
1681
+ const namedEdges = {
1682
+ start: 0,
1683
+ center: 0.5,
1684
+ end: 1,
1685
+ };
1686
+ function resolveEdge(edge, length, inset = 0) {
1687
+ let delta = 0;
1688
+ /**
1689
+ * If we have this edge defined as a preset, replace the definition
1690
+ * with the numerical value.
1691
+ */
1692
+ if (namedEdges[edge] !== undefined) {
1693
+ edge = namedEdges[edge];
1694
+ }
1695
+ /**
1696
+ * Handle unit values
1697
+ */
1698
+ if (isString(edge)) {
1699
+ const asNumber = parseFloat(edge);
1700
+ if (edge.endsWith("px")) {
1701
+ delta = asNumber;
1702
+ }
1703
+ else if (edge.endsWith("%")) {
1704
+ edge = asNumber / 100;
1705
+ }
1706
+ else if (edge.endsWith("vw")) {
1707
+ delta = (asNumber / 100) * document.documentElement.clientWidth;
1708
+ }
1709
+ else if (edge.endsWith("vh")) {
1710
+ delta = (asNumber / 100) * document.documentElement.clientHeight;
1711
+ }
1712
+ else {
1713
+ edge = asNumber;
1714
+ }
1715
+ }
1716
+ /**
1717
+ * If the edge is defined as a number, handle as a progress value.
1718
+ */
1719
+ if (isNumber(edge)) {
1720
+ delta = length * edge;
1721
+ }
1722
+ return inset + delta;
1723
+ }
1724
+
1725
+ const defaultOffset = [0, 0];
1726
+ function resolveOffset(offset, containerLength, targetLength, targetInset) {
1727
+ let offsetDefinition = Array.isArray(offset) ? offset : defaultOffset;
1728
+ let targetPoint = 0;
1729
+ let containerPoint = 0;
1730
+ if (isNumber(offset)) {
1731
+ /**
1732
+ * If we're provided offset: [0, 0.5, 1] then each number x should become
1733
+ * [x, x], so we default to the behaviour of mapping 0 => 0 of both target
1734
+ * and container etc.
1735
+ */
1736
+ offsetDefinition = [offset, offset];
1737
+ }
1738
+ else if (isString(offset)) {
1739
+ offset = offset.trim();
1740
+ if (offset.includes(" ")) {
1741
+ offsetDefinition = offset.split(" ");
1742
+ }
1743
+ else {
1744
+ /**
1745
+ * If we're provided a definition like "100px" then we want to apply
1746
+ * that only to the top of the target point, leaving the container at 0.
1747
+ * Whereas a named offset like "end" should be applied to both.
1748
+ */
1749
+ offsetDefinition = [offset, namedEdges[offset] ? offset : `0`];
1750
+ }
1751
+ }
1752
+ targetPoint = resolveEdge(offsetDefinition[0], targetLength, targetInset);
1753
+ containerPoint = resolveEdge(offsetDefinition[1], containerLength);
1754
+ return targetPoint - containerPoint;
1755
+ }
1756
+
1757
+ const point = { x: 0, y: 0 };
1758
+ function resolveOffsets(container, info, options) {
1759
+ let { offset: offsetDefinition = ScrollOffset.All } = options;
1760
+ const { target = container, axis = "y" } = options;
1761
+ const lengthLabel = axis === "y" ? "height" : "width";
1762
+ const inset = target !== container ? calcInset(target, container) : point;
1763
+ /**
1764
+ * Measure the target and container. If they're the same thing then we
1765
+ * use the container's scrollWidth/Height as the target, from there
1766
+ * all other calculations can remain the same.
1767
+ */
1768
+ const targetSize = target === container
1769
+ ? { width: container.scrollWidth, height: container.scrollHeight }
1770
+ : { width: target.clientWidth, height: target.clientHeight };
1771
+ const containerSize = {
1772
+ width: container.clientWidth,
1773
+ height: container.clientHeight,
1774
+ };
1775
+ /**
1776
+ * Reset the length of the resolved offset array rather than creating a new one.
1777
+ * TODO: More reusable data structures for targetSize/containerSize would also be good.
1778
+ */
1779
+ info[axis].offset.length = 0;
1780
+ /**
1781
+ * Populate the offset array by resolving the user's offset definition into
1782
+ * a list of pixel scroll offets.
1783
+ */
1784
+ let hasChanged = !info[axis].interpolate;
1785
+ const numOffsets = offsetDefinition.length;
1786
+ for (let i = 0; i < numOffsets; i++) {
1787
+ const offset = resolveOffset(offsetDefinition[i], containerSize[lengthLabel], targetSize[lengthLabel], inset[axis]);
1788
+ if (!hasChanged && offset !== info[axis].interpolatorOffsets[i]) {
1789
+ hasChanged = true;
1790
+ }
1791
+ info[axis].offset[i] = offset;
1792
+ }
1793
+ /**
1794
+ * If the pixel scroll offsets have changed, create a new interpolator function
1795
+ * to map scroll value into a progress.
1796
+ */
1797
+ if (hasChanged) {
1798
+ info[axis].interpolate = interpolate(defaultOffset$1(numOffsets), info[axis].offset);
1799
+ info[axis].interpolatorOffsets = [...info[axis].offset];
1800
+ }
1801
+ info[axis].progress = info[axis].interpolate(info[axis].current);
1802
+ }
1803
+
1804
+ function measure(container, target = container, info) {
1805
+ /**
1806
+ * Find inset of target within scrollable container
1807
+ */
1808
+ info.x.targetOffset = 0;
1809
+ info.y.targetOffset = 0;
1810
+ if (target !== container) {
1811
+ let node = target;
1812
+ while (node && node != container) {
1813
+ info.x.targetOffset += node.offsetLeft;
1814
+ info.y.targetOffset += node.offsetTop;
1815
+ node = node.offsetParent;
1816
+ }
1817
+ }
1818
+ info.x.targetLength =
1819
+ target === container ? target.scrollWidth : target.clientWidth;
1820
+ info.y.targetLength =
1821
+ target === container ? target.scrollHeight : target.clientHeight;
1822
+ info.x.containerLength = container.clientWidth;
1823
+ info.y.containerLength = container.clientHeight;
1824
+ }
1825
+ function createOnScrollHandler(element, onScroll, info, options = {}) {
1826
+ const axis = options.axis || "y";
1827
+ return {
1828
+ measure: () => measure(element, options.target, info),
1829
+ update: (time) => {
1830
+ updateScrollInfo(element, info, time);
1831
+ if (options.offset || options.target) {
1832
+ resolveOffsets(element, info, options);
1833
+ }
1834
+ },
1835
+ notify: isFunction(onScroll)
1836
+ ? () => onScroll(info)
1837
+ : scrubAnimation(onScroll, info[axis]),
1838
+ };
1839
+ }
1840
+ function scrubAnimation(controls, axisInfo) {
1841
+ controls.pause();
1842
+ controls.forEachNative((animation, { easing }) => {
1843
+ var _a, _b;
1844
+ if (animation.updateDuration) {
1845
+ if (!easing)
1846
+ animation.easing = noopReturn;
1847
+ animation.updateDuration(1);
1848
+ }
1849
+ else {
1850
+ const timingOptions = { duration: 1000 };
1851
+ if (!easing)
1852
+ timingOptions.easing = "linear";
1853
+ (_b = (_a = animation.effect) === null || _a === void 0 ? void 0 : _a.updateTiming) === null || _b === void 0 ? void 0 : _b.call(_a, timingOptions);
1854
+ }
1855
+ });
1856
+ return () => {
1857
+ controls.currentTime = axisInfo.progress;
1858
+ };
1859
+ }
1860
+
1861
+ const scrollListeners = new WeakMap();
1862
+ const resizeListeners = new WeakMap();
1863
+ const onScrollHandlers = new WeakMap();
1864
+ const getEventTarget = (element) => element === document.documentElement ? window : element;
1865
+ function scroll(onScroll, _a = {}) {
1866
+ var { container = document.documentElement } = _a, options = __rest(_a, ["container"]);
1867
+ let containerHandlers = onScrollHandlers.get(container);
1868
+ /**
1869
+ * Get the onScroll handlers for this container.
1870
+ * If one isn't found, create a new one.
1871
+ */
1872
+ if (!containerHandlers) {
1873
+ containerHandlers = new Set();
1874
+ onScrollHandlers.set(container, containerHandlers);
1875
+ }
1876
+ /**
1877
+ * Create a new onScroll handler for the provided callback.
1878
+ */
1879
+ const info = createScrollInfo();
1880
+ const containerHandler = createOnScrollHandler(container, onScroll, info, options);
1881
+ containerHandlers.add(containerHandler);
1882
+ /**
1883
+ * Check if there's a scroll event listener for this container.
1884
+ * If not, create one.
1885
+ */
1886
+ if (!scrollListeners.has(container)) {
1887
+ const listener = () => {
1888
+ const time = performance.now();
1889
+ for (const handler of containerHandlers)
1890
+ handler.measure();
1891
+ for (const handler of containerHandlers)
1892
+ handler.update(time);
1893
+ for (const handler of containerHandlers)
1894
+ handler.notify();
1895
+ };
1896
+ scrollListeners.set(container, listener);
1897
+ const target = getEventTarget(container);
1898
+ window.addEventListener("resize", listener, { passive: true });
1899
+ if (container !== document.documentElement) {
1900
+ resizeListeners.set(container, resize(container, listener));
1901
+ }
1902
+ target.addEventListener("scroll", listener, { passive: true });
1903
+ }
1904
+ const listener = scrollListeners.get(container);
1905
+ const onLoadProcesss = requestAnimationFrame(listener);
1906
+ return () => {
1907
+ var _a;
1908
+ if (typeof onScroll !== "function")
1909
+ onScroll.stop();
1910
+ cancelAnimationFrame(onLoadProcesss);
1911
+ /**
1912
+ * Check if we even have any handlers for this container.
1913
+ */
1914
+ const containerHandlers = onScrollHandlers.get(container);
1915
+ if (!containerHandlers)
1916
+ return;
1917
+ containerHandlers.delete(containerHandler);
1918
+ if (containerHandlers.size)
1919
+ return;
1920
+ /**
1921
+ * If no more handlers, remove the scroll listener too.
1922
+ */
1923
+ const listener = scrollListeners.get(container);
1924
+ scrollListeners.delete(container);
1925
+ if (listener) {
1926
+ getEventTarget(container).removeEventListener("scroll", listener);
1927
+ (_a = resizeListeners.get(container)) === null || _a === void 0 ? void 0 : _a();
1928
+ window.removeEventListener("resize", listener);
1929
+ }
1930
+ };
1931
+ }
1932
+
1933
+ function hasChanged(a, b) {
1934
+ if (typeof a !== typeof b)
1935
+ return true;
1936
+ if (Array.isArray(a) && Array.isArray(b))
1937
+ return !shallowCompare(a, b);
1938
+ return a !== b;
1939
+ }
1940
+ function shallowCompare(next, prev) {
1941
+ const prevLength = prev.length;
1942
+ if (prevLength !== next.length)
1943
+ return false;
1944
+ for (let i = 0; i < prevLength; i++) {
1945
+ if (prev[i] !== next[i])
1946
+ return false;
1947
+ }
1948
+ return true;
1949
+ }
1950
+
1951
+ function isVariant(definition) {
1952
+ return typeof definition === "object";
1953
+ }
1954
+
1955
+ function resolveVariant(definition, variants) {
1956
+ if (isVariant(definition)) {
1957
+ return definition;
1958
+ }
1959
+ else if (definition && variants) {
1960
+ return variants[definition];
1961
+ }
1962
+ }
1963
+
1964
+ let scheduled = undefined;
1965
+ function processScheduledAnimations() {
1966
+ if (!scheduled)
1967
+ return;
1968
+ const generators = scheduled.sort(compareByDepth).map(fireAnimateUpdates);
1969
+ generators.forEach(fireNext);
1970
+ generators.forEach(fireNext);
1971
+ scheduled = undefined;
1972
+ }
1973
+ function scheduleAnimation(state) {
1974
+ if (!scheduled) {
1975
+ scheduled = [state];
1976
+ requestAnimationFrame(processScheduledAnimations);
1977
+ }
1978
+ else {
1979
+ addUniqueItem(scheduled, state);
1980
+ }
1981
+ }
1982
+ function unscheduleAnimation(state) {
1983
+ scheduled && removeItem(scheduled, state);
1984
+ }
1985
+ const compareByDepth = (a, b) => a.getDepth() - b.getDepth();
1986
+ const fireAnimateUpdates = (state) => state.animateUpdates();
1987
+ const fireNext = (iterator) => iterator.next();
1988
+
1989
+ const motionEvent = (name, target) => new CustomEvent(name, { detail: { target } });
1990
+ function dispatchPointerEvent(element, name, event) {
1991
+ element.dispatchEvent(new CustomEvent(name, { detail: { originalEvent: event } }));
1992
+ }
1993
+ function dispatchViewEvent(element, name, entry) {
1994
+ element.dispatchEvent(new CustomEvent(name, { detail: { originalEntry: entry } }));
1995
+ }
1996
+
1997
+ const inView = {
1998
+ isActive: (options) => Boolean(options.inView),
1999
+ subscribe: (element, { enable, disable }, { inViewOptions = {} }) => {
2000
+ const { once } = inViewOptions, viewOptions = __rest(inViewOptions, ["once"]);
2001
+ return inView$1(element, (enterEntry) => {
2002
+ enable();
2003
+ dispatchViewEvent(element, "viewenter", enterEntry);
2004
+ if (!once) {
2005
+ return (leaveEntry) => {
2006
+ disable();
2007
+ dispatchViewEvent(element, "viewleave", leaveEntry);
2008
+ };
2009
+ }
2010
+ }, viewOptions);
2011
+ },
2012
+ };
2013
+
2014
+ const mouseEvent = (element, name, action) => (event) => {
2015
+ if (event.pointerType && event.pointerType !== "mouse")
2016
+ return;
2017
+ action();
2018
+ dispatchPointerEvent(element, name, event);
2019
+ };
2020
+ const hover = {
2021
+ isActive: (options) => Boolean(options.hover),
2022
+ subscribe: (element, { enable, disable }) => {
2023
+ const onEnter = mouseEvent(element, "hoverstart", enable);
2024
+ const onLeave = mouseEvent(element, "hoverend", disable);
2025
+ element.addEventListener("pointerenter", onEnter);
2026
+ element.addEventListener("pointerleave", onLeave);
2027
+ return () => {
2028
+ element.removeEventListener("pointerenter", onEnter);
2029
+ element.removeEventListener("pointerleave", onLeave);
2030
+ };
2031
+ },
2032
+ };
2033
+
2034
+ const press = {
2035
+ isActive: (options) => Boolean(options.press),
2036
+ subscribe: (element, { enable, disable }) => {
2037
+ const onPointerUp = (event) => {
2038
+ disable();
2039
+ dispatchPointerEvent(element, "pressend", event);
2040
+ window.removeEventListener("pointerup", onPointerUp);
2041
+ };
2042
+ const onPointerDown = (event) => {
2043
+ enable();
2044
+ dispatchPointerEvent(element, "pressstart", event);
2045
+ window.addEventListener("pointerup", onPointerUp);
2046
+ };
2047
+ element.addEventListener("pointerdown", onPointerDown);
2048
+ return () => {
2049
+ element.removeEventListener("pointerdown", onPointerDown);
2050
+ window.removeEventListener("pointerup", onPointerUp);
2051
+ };
2052
+ },
2053
+ };
2054
+
2055
+ const gestures = { inView, hover, press };
2056
+ /**
2057
+ * A list of state types, in priority order. If a value is defined in
2058
+ * a righter-most type, it will override any definition in a lefter-most.
2059
+ */
2060
+ const stateTypes = ["initial", "animate", ...Object.keys(gestures), "exit"];
2061
+ /**
2062
+ * A global store of all generated motion states. This can be used to lookup
2063
+ * a motion state for a given Element.
2064
+ */
2065
+ const mountedStates = new WeakMap();
2066
+ function createMotionState(options = {}, parent) {
2067
+ /**
2068
+ * The element represented by the motion state. This is an empty reference
2069
+ * when we create the state to support SSR and allow for later mounting
2070
+ * in view libraries.
2071
+ *
2072
+ * @ts-ignore
2073
+ */
2074
+ let element;
2075
+ /**
2076
+ * Calculate a depth that we can use to order motion states by tree depth.
2077
+ */
2078
+ let depth = parent ? parent.getDepth() + 1 : 0;
2079
+ /**
2080
+ * Track which states are currently active.
2081
+ */
2082
+ const activeStates = { initial: true, animate: true };
2083
+ /**
2084
+ * A map of functions that, when called, will remove event listeners for
2085
+ * a given gesture.
2086
+ */
2087
+ const gestureSubscriptions = {};
2088
+ /**
2089
+ * Initialise a context to share through motion states. This
2090
+ * will be populated by variant names (if any).
2091
+ */
2092
+ const context = {};
2093
+ for (const name of stateTypes) {
2094
+ context[name] =
2095
+ typeof options[name] === "string"
2096
+ ? options[name]
2097
+ : parent === null || parent === void 0 ? void 0 : parent.getContext()[name];
2098
+ }
2099
+ /**
2100
+ * If initial is set to false we use the animate prop as the initial
2101
+ * animation state.
2102
+ */
2103
+ const initialVariantSource = options.initial === false ? "animate" : "initial";
2104
+ /**
2105
+ * Destructure an initial target out from the resolved initial variant.
2106
+ */
2107
+ let _a = resolveVariant(options[initialVariantSource] || context[initialVariantSource], options.variants) || {}, target = __rest(_a, ["transition"]);
2108
+ /**
2109
+ * The base target is a cached map of values that we'll use to animate
2110
+ * back to if a value is removed from all active state types. This
2111
+ * is usually the initial value as read from the DOM, for instance if
2112
+ * it hasn't been defined in initial.
2113
+ */
2114
+ const baseTarget = Object.assign({}, target);
2115
+ /**
2116
+ * A generator that will be processed by the global animation scheduler.
2117
+ * This yeilds when it switches from reading the DOM to writing to it
2118
+ * to prevent layout thrashing.
2119
+ */
2120
+ function* animateUpdates() {
2121
+ var _a, _b;
2122
+ const prevTarget = target;
2123
+ target = {};
2124
+ const animationOptions = {};
2125
+ for (const name of stateTypes) {
2126
+ if (!activeStates[name])
2127
+ continue;
2128
+ const variant = resolveVariant(options[name]);
2129
+ if (!variant)
2130
+ continue;
2131
+ for (const key in variant) {
2132
+ if (key === "transition")
2133
+ continue;
2134
+ target[key] = variant[key];
2135
+ animationOptions[key] = getOptions((_b = (_a = variant.transition) !== null && _a !== void 0 ? _a : options.transition) !== null && _b !== void 0 ? _b : {}, key);
2136
+ }
2137
+ }
2138
+ const allTargetKeys = new Set([
2139
+ ...Object.keys(target),
2140
+ ...Object.keys(prevTarget),
2141
+ ]);
2142
+ const animationFactories = [];
2143
+ allTargetKeys.forEach((key) => {
2144
+ var _a;
2145
+ if (target[key] === undefined) {
2146
+ target[key] = baseTarget[key];
2147
+ }
2148
+ if (hasChanged(prevTarget[key], target[key])) {
2149
+ (_a = baseTarget[key]) !== null && _a !== void 0 ? _a : (baseTarget[key] = style.get(element, key));
2150
+ animationFactories.push(animateStyle(element, key, target[key], animationOptions[key]));
2151
+ }
2152
+ });
2153
+ // Wait for all animation states to read from the DOM
2154
+ yield;
2155
+ const animations = animationFactories
2156
+ .map((factory) => factory())
2157
+ .filter(Boolean);
2158
+ if (!animations.length)
2159
+ return;
2160
+ const animationTarget = target;
2161
+ element.dispatchEvent(motionEvent("motionstart", animationTarget));
2162
+ Promise.all(animations.map((animation) => animation.finished))
2163
+ .then(() => {
2164
+ element.dispatchEvent(motionEvent("motioncomplete", animationTarget));
2165
+ })
2166
+ .catch(noop);
2167
+ }
2168
+ const setGesture = (name, isActive) => () => {
2169
+ activeStates[name] = isActive;
2170
+ scheduleAnimation(state);
2171
+ };
2172
+ const updateGestureSubscriptions = () => {
2173
+ for (const name in gestures) {
2174
+ const isGestureActive = gestures[name].isActive(options);
2175
+ const remove = gestureSubscriptions[name];
2176
+ if (isGestureActive && !remove) {
2177
+ gestureSubscriptions[name] = gestures[name].subscribe(element, {
2178
+ enable: setGesture(name, true),
2179
+ disable: setGesture(name, false),
2180
+ }, options);
2181
+ }
2182
+ else if (!isGestureActive && remove) {
2183
+ remove();
2184
+ delete gestureSubscriptions[name];
2185
+ }
2186
+ }
2187
+ };
2188
+ const state = {
2189
+ update: (newOptions) => {
2190
+ if (!element)
2191
+ return;
2192
+ options = newOptions;
2193
+ updateGestureSubscriptions();
2194
+ scheduleAnimation(state);
2195
+ },
2196
+ setActive: (name, isActive) => {
2197
+ if (!element)
2198
+ return;
2199
+ activeStates[name] = isActive;
2200
+ scheduleAnimation(state);
2201
+ },
2202
+ animateUpdates,
2203
+ getDepth: () => depth,
2204
+ getTarget: () => target,
2205
+ getOptions: () => options,
2206
+ getContext: () => context,
2207
+ mount: (newElement) => {
2208
+ invariant(Boolean(newElement), "Animation state must be mounted with valid Element");
2209
+ element = newElement;
2210
+ mountedStates.set(element, state);
2211
+ updateGestureSubscriptions();
2212
+ return () => {
2213
+ mountedStates.delete(element);
2214
+ unscheduleAnimation(state);
2215
+ for (const key in gestureSubscriptions) {
2216
+ gestureSubscriptions[key]();
2217
+ }
2218
+ };
2219
+ },
2220
+ isMounted: () => Boolean(element),
2221
+ };
2222
+ return state;
2223
+ }
2224
+
2225
+ function createStyles(keyframes) {
2226
+ const initialKeyframes = {};
2227
+ const transformKeys = [];
2228
+ for (let key in keyframes) {
2229
+ const value = keyframes[key];
2230
+ if (isTransform(key)) {
2231
+ if (transformAlias[key])
2232
+ key = transformAlias[key];
2233
+ transformKeys.push(key);
2234
+ key = asTransformCssVar(key);
2235
+ }
2236
+ let initialKeyframe = Array.isArray(value) ? value[0] : value;
2237
+ /**
2238
+ * If this is a number and we have a default value type, convert the number
2239
+ * to this type.
2240
+ */
2241
+ const definition = transformDefinitions.get(key);
2242
+ if (definition) {
2243
+ initialKeyframe = isNumber(value)
2244
+ ? definition.toDefaultUnit(value)
2245
+ : value;
2246
+ }
2247
+ initialKeyframes[key] = initialKeyframe;
2248
+ }
2249
+ if (transformKeys.length) {
2250
+ initialKeyframes.transform = buildTransformTemplate(transformKeys);
2251
+ }
2252
+ return initialKeyframes;
2253
+ }
2254
+
2255
+ const camelLetterToPipeLetter = (letter) => `-${letter.toLowerCase()}`;
2256
+ const camelToPipeCase = (str) => str.replace(/[A-Z]/g, camelLetterToPipeLetter);
2257
+ function createStyleString(target = {}) {
2258
+ const styles = createStyles(target);
2259
+ let style = "";
2260
+ for (const key in styles) {
2261
+ style += key.startsWith("--") ? key : camelToPipeCase(key);
2262
+ style += `: ${styles[key]}; `;
2263
+ }
2264
+ return style;
2265
+ }
2266
+
2267
+ function animateProgress(target, options = {}) {
2268
+ return withControls([
1440
2269
  () => {
1441
2270
  const animation = new Animation(target, [0, 1], options);
1442
2271
  animation.finished.catch(() => { });
1443
2272
  return animation;
1444
2273
  },
1445
- ], options === null || options === void 0 ? void 0 : options.duration);
2274
+ ], options, options.duration);
1446
2275
  }
1447
2276
  function animate(target, keyframesOrOptions, options) {
1448
- const animationFunction = typeof target === "function" ? animateProgress : animate$1;
1449
- return animationFunction(target, keyframesOrOptions, options);
2277
+ const factory = isFunction(target) ? animateProgress : animate$1;
2278
+ return factory(target, keyframesOrOptions, options);
1450
2279
  }
1451
2280
 
1452
2281
  exports.MotionValue = MotionValue;
2282
+ exports.ScrollOffset = ScrollOffset;
1453
2283
  exports.animate = animate;
2284
+ exports.animateStyle = animateStyle;
2285
+ exports.createMotionState = createMotionState;
2286
+ exports.createStyleString = createStyleString;
2287
+ exports.createStyles = createStyles;
2288
+ exports.getAnimationData = getAnimationData;
2289
+ exports.getStyleName = getStyleName;
1454
2290
  exports.glide = glide;
1455
- exports.inView = inView;
2291
+ exports.inView = inView$1;
2292
+ exports.mountedStates = mountedStates;
2293
+ exports.resize = resize;
2294
+ exports.scroll = scroll;
1456
2295
  exports.spring = spring;
1457
2296
  exports.stagger = stagger;
1458
2297
  exports.style = style;
1459
2298
  exports.timeline = timeline;
2299
+ exports.withControls = withControls;
1460
2300
 
1461
2301
  Object.defineProperty(exports, '__esModule', { value: true });
1462
2302