@studiometa/js-toolkit 3.5.0 → 3.6.0-beta.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.
Files changed (92) hide show
  1. package/Base/Base.d.ts +2 -2
  2. package/Base/managers/AbstractManager.d.ts +2 -2
  3. package/Base/utils.d.ts +1 -1
  4. package/Base/utils.js +1 -2
  5. package/Base/utils.js.map +2 -2
  6. package/helpers/createApp.js +5 -0
  7. package/helpers/createApp.js.map +2 -2
  8. package/helpers/index.d.ts +1 -0
  9. package/helpers/index.js +1 -0
  10. package/helpers/index.js.map +2 -2
  11. package/helpers/logTree.d.ts +17 -0
  12. package/helpers/logTree.js +59 -0
  13. package/helpers/logTree.js.map +7 -0
  14. package/helpers/queryComponent.js +9 -10
  15. package/helpers/queryComponent.js.map +2 -2
  16. package/index.d.ts +1 -1
  17. package/index.js +1 -1
  18. package/index.js.map +1 -1
  19. package/package.json +1 -1
  20. package/services/AbstractService.d.ts +1 -1
  21. package/services/AbstractService.js +1 -1
  22. package/services/AbstractService.js.map +2 -2
  23. package/services/DragService.d.ts +5 -5
  24. package/services/RafService.d.ts +1 -1
  25. package/services/RafService.js +13 -7
  26. package/services/RafService.js.map +2 -2
  27. package/services/ScrollService.d.ts +21 -3
  28. package/services/ScrollService.js +55 -7
  29. package/services/ScrollService.js.map +2 -2
  30. package/utils/collide/boundingRectToCircle.d.ts +2 -2
  31. package/utils/css/animate.js +166 -96
  32. package/utils/css/animate.js.map +2 -2
  33. package/utils/css/transform.js +12 -13
  34. package/utils/css/transform.js.map +2 -2
  35. package/utils/index.d.ts +1 -0
  36. package/utils/index.js +1 -0
  37. package/utils/index.js.map +2 -2
  38. package/utils/math/smoothTo.d.ts +24 -6
  39. package/utils/memoize.d.ts +1 -1
  40. package/utils/object/getAllProperties.js +4 -2
  41. package/utils/object/getAllProperties.js.map +2 -2
  42. package/utils/scheduler.d.ts +1 -1
  43. package/utils/storage/createLocalStorageProvider.d.ts +2 -0
  44. package/utils/storage/createLocalStorageProvider.js +32 -0
  45. package/utils/storage/createLocalStorageProvider.js.map +7 -0
  46. package/utils/storage/createMemoryStorageProvider.d.ts +2 -0
  47. package/utils/storage/createMemoryStorageProvider.js +27 -0
  48. package/utils/storage/createMemoryStorageProvider.js.map +7 -0
  49. package/utils/storage/createNoopProvider.d.ts +2 -0
  50. package/utils/storage/createNoopProvider.js +23 -0
  51. package/utils/storage/createNoopProvider.js.map +7 -0
  52. package/utils/storage/createSessionStorageProvider.d.ts +2 -0
  53. package/utils/storage/createSessionStorageProvider.js +31 -0
  54. package/utils/storage/createSessionStorageProvider.js.map +7 -0
  55. package/utils/storage/createStorage.d.ts +2 -0
  56. package/utils/storage/createStorage.js +100 -0
  57. package/utils/storage/createStorage.js.map +7 -0
  58. package/utils/storage/createUrlSearchParamsInHashProvider.d.ts +2 -0
  59. package/utils/storage/createUrlSearchParamsInHashProvider.js +57 -0
  60. package/utils/storage/createUrlSearchParamsInHashProvider.js.map +7 -0
  61. package/utils/storage/createUrlSearchParamsProvider.d.ts +2 -0
  62. package/utils/storage/createUrlSearchParamsProvider.js +41 -0
  63. package/utils/storage/createUrlSearchParamsProvider.js.map +7 -0
  64. package/utils/storage/getBrowserContext.d.ts +1 -0
  65. package/utils/storage/getBrowserContext.js +17 -0
  66. package/utils/storage/getBrowserContext.js.map +7 -0
  67. package/utils/storage/getGlobalStorage.d.ts +1 -0
  68. package/utils/storage/getGlobalStorage.js +7 -0
  69. package/utils/storage/getGlobalStorage.js.map +7 -0
  70. package/utils/storage/getStorageKeys.d.ts +1 -0
  71. package/utils/storage/getStorageKeys.js +12 -0
  72. package/utils/storage/getStorageKeys.js.map +7 -0
  73. package/utils/storage/index.d.ts +8 -0
  74. package/utils/storage/index.js +62 -0
  75. package/utils/storage/index.js.map +7 -0
  76. package/utils/storage/providers.d.ts +11 -0
  77. package/utils/storage/providers.js +30 -0
  78. package/utils/storage/providers.js.map +7 -0
  79. package/utils/storage/serializers.d.ts +2 -0
  80. package/utils/storage/serializers.js +14 -0
  81. package/utils/storage/serializers.js.map +7 -0
  82. package/utils/storage/types.d.ts +33 -0
  83. package/utils/storage/types.js +1 -0
  84. package/utils/storage/types.js.map +7 -0
  85. package/utils/storage.d.ts +1 -0
  86. package/utils/storage.js +2 -0
  87. package/utils/storage.js.map +7 -0
  88. package/utils/string/changeCase.js +1 -1
  89. package/utils/string/changeCase.js.map +2 -2
  90. package/utils/tween.js +5 -5
  91. package/utils/tween.js.map +2 -2
  92. package/tsconfig.build.tsbuildinfo +0 -1
@@ -3,7 +3,21 @@ import { debounce } from "../utils/debounce.js";
3
3
  import { PASSIVE_CAPTURE_EVENT_OPTIONS } from "./utils.js";
4
4
  import { nextTick } from "../utils/nextTick.js";
5
5
  class ScrollService extends AbstractService {
6
- static config = [[() => document, [["scroll", PASSIVE_CAPTURE_EVENT_OPTIONS]]]];
6
+ static config = [
7
+ [() => document, [["scroll", PASSIVE_CAPTURE_EVENT_OPTIONS]]],
8
+ [() => window, [["resize", PASSIVE_CAPTURE_EVENT_OPTIONS]]]
9
+ ];
10
+ /**
11
+ * Cached scroll max values, updated on resize and first scroll.
12
+ * @private
13
+ */
14
+ __maxX = null;
15
+ __maxY = null;
16
+ /**
17
+ * Observe scroll container size changes that do not trigger window resize.
18
+ * @private
19
+ */
20
+ __resizeObserver = null;
7
21
  props = {
8
22
  x: window.scrollX,
9
23
  y: window.scrollY,
@@ -58,8 +72,11 @@ class ScrollService extends AbstractService {
58
72
  props.last.y = props.lastY = yLast;
59
73
  props.delta.x = props.deltaX = props.x - xLast;
60
74
  props.delta.y = props.deltaY = props.y - yLast;
61
- props.max.x = props.maxX = document.scrollingElement.scrollWidth - window.innerWidth;
62
- props.max.y = props.maxY = document.scrollingElement.scrollHeight - window.innerHeight;
75
+ if (this.__maxX === null || this.__maxY === null) {
76
+ this.__updateMaxValues();
77
+ }
78
+ props.max.x = props.maxX = this.__maxX;
79
+ props.max.y = props.maxY = this.__maxY;
63
80
  props.progress.x = props.progressX = props.max.x === 0 ? 1 : props.x / props.max.x;
64
81
  props.progress.y = props.progressY = props.max.y === 0 ? 1 : props.y / props.max.y;
65
82
  props.isUp = props.y < yLast;
@@ -70,19 +87,50 @@ class ScrollService extends AbstractService {
70
87
  props.direction.y = props.isDown ? "DOWN" : props.isUp ? "UP" : "NONE";
71
88
  return props;
72
89
  }
73
- update() {
74
- nextTick(() => this.updateProps()).then(() => this.trigger(this.props));
90
+ update(trigger = true) {
91
+ nextTick(() => this.updateProps()).then(() => {
92
+ if (trigger) {
93
+ this.trigger(this.props);
94
+ }
95
+ });
75
96
  }
76
97
  onScrollDebounced = debounce(() => {
77
98
  this.update();
78
99
  }, 100);
79
100
  /**
80
- * Scroll handler.
101
+ * Update cached max scroll values on resize.
102
+ * @private
81
103
  */
82
- handleEvent() {
104
+ __updateMaxValues() {
105
+ this.__maxX = document.scrollingElement.scrollWidth - window.innerWidth;
106
+ this.__maxY = document.scrollingElement.scrollHeight - window.innerHeight;
107
+ }
108
+ /**
109
+ * Scroll and resize handler.
110
+ */
111
+ handleEvent(event) {
112
+ if (event.type === "resize") {
113
+ this.__updateMaxValues();
114
+ this.update(false);
115
+ return;
116
+ }
83
117
  this.update();
84
118
  this.onScrollDebounced();
85
119
  }
120
+ init() {
121
+ super.init();
122
+ if (typeof ResizeObserver === "function" && document.scrollingElement) {
123
+ this.__resizeObserver = new ResizeObserver(() => {
124
+ this.__updateMaxValues();
125
+ });
126
+ this.__resizeObserver.observe(document.scrollingElement);
127
+ }
128
+ }
129
+ kill() {
130
+ this.__resizeObserver?.disconnect();
131
+ this.__resizeObserver = null;
132
+ super.kill();
133
+ }
86
134
  }
87
135
  function useScroll() {
88
136
  return ScrollService.getInstance();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/services/ScrollService.ts"],
4
- "sourcesContent": ["import type { ServiceConfig, ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { debounce } from '../utils/debounce.js';\nimport { PASSIVE_CAPTURE_EVENT_OPTIONS } from './utils.js';\nimport { nextTick } from '../utils/nextTick.js';\n\nexport interface ScrollServiceProps {\n x: number;\n y: number;\n changed: { x: boolean; y: boolean };\n changedX: boolean;\n changedY: boolean;\n last: { x: number; y: number };\n lastX: number;\n lastY: number;\n delta: { x: number; y: number };\n deltaX: number;\n deltaY: number;\n progress: { x: number; y: number };\n progressX: number;\n progressY: number;\n max: { x: number; y: number };\n maxX: number;\n maxY: number;\n direction: { x: 'LEFT' | 'RIGHT' | 'NONE'; y: 'UP' | 'DOWN' | 'NONE' };\n isUp: boolean;\n isRight: boolean;\n isDown: boolean;\n isLeft: boolean;\n}\n\nexport type ScrollServiceInterface = ServiceInterface<ScrollServiceProps>;\n\nexport class ScrollService extends AbstractService<ScrollServiceProps> {\n static config: ServiceConfig = [[() => document, [['scroll', PASSIVE_CAPTURE_EVENT_OPTIONS]]]];\n\n props: ScrollServiceProps = {\n x: window.scrollX,\n y: window.scrollY,\n changed: {\n x: false,\n y: false,\n },\n changedX: false,\n changedY: false,\n last: {\n x: window.scrollX,\n y: window.scrollY,\n },\n lastX: window.scrollX,\n lastY: window.scrollY,\n delta: {\n x: 0,\n y: 0,\n },\n deltaX: 0,\n deltaY: 0,\n max: {\n x: document.scrollingElement.scrollWidth - window.innerWidth,\n y: document.scrollingElement.scrollHeight - window.innerHeight,\n },\n maxX: document.scrollingElement.scrollWidth - window.innerWidth,\n maxY: document.scrollingElement.scrollHeight - window.innerHeight,\n progress: {\n x: 0,\n y: 0,\n },\n progressX: 0,\n progressY: 0,\n direction: {\n x: 'NONE',\n y: 'NONE',\n },\n isUp: false,\n isRight: false,\n isDown: false,\n isLeft: false,\n };\n\n updateProps(): ScrollServiceProps {\n const { props } = this;\n const yLast = props.y;\n const xLast = props.x;\n\n props.y = window.scrollY;\n props.x = window.scrollX;\n props.changed.x = props.changedX = props.x !== xLast;\n props.changed.y = props.changedY = props.y !== yLast;\n props.last.x = props.lastX = xLast;\n props.last.y = props.lastY = yLast;\n props.delta.x = props.deltaX = props.x - xLast;\n props.delta.y = props.deltaY = props.y - yLast;\n props.max.x = props.maxX = document.scrollingElement.scrollWidth - window.innerWidth;\n props.max.y = props.maxY = document.scrollingElement.scrollHeight - window.innerHeight;\n props.progress.x = props.progressX = props.max.x === 0 ? 1 : props.x / props.max.x;\n props.progress.y = props.progressY = props.max.y === 0 ? 1 : props.y / props.max.y;\n props.isUp = props.y < yLast;\n props.isRight = props.x > xLast;\n props.isDown = props.y > yLast;\n props.isLeft = props.x < xLast;\n /* eslint-disable no-nested-ternary */\n props.direction.x = props.isRight ? 'RIGHT' : props.isLeft ? 'LEFT' : 'NONE';\n props.direction.y = props.isDown ? 'DOWN' : props.isUp ? 'UP' : 'NONE';\n /* eslint-enable no-nested-ternary */\n\n return props;\n }\n\n update() {\n nextTick(() => this.updateProps()).then(() => this.trigger(this.props));\n }\n\n onScrollDebounced = debounce(() => {\n this.update();\n }, 100);\n\n /**\n * Scroll handler.\n */\n handleEvent() {\n this.update();\n this.onScrollDebounced();\n }\n}\n\n/**\n * Use the scroll service.\n *\n * ```js\n * import { useScroll } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useScroll();\n * add(key, (props) => {});\n * remove(key);\n * props();\n * ```\n * @link https://js-toolkit.studiometa.dev/api/services/useScroll.html\n*/\nexport function useScroll(): ScrollServiceInterface {\n return ScrollService.getInstance();\n}\n"],
5
- "mappings": "AACA,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,qCAAqC;AAC9C,SAAS,gBAAgB;AA6BlB,MAAM,sBAAsB,gBAAoC;AAAA,EACrE,OAAO,SAAwB,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,UAAU,6BAA6B,CAAC,CAAC,CAAC;AAAA,EAE7F,QAA4B;AAAA,IAC1B,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,IACV,SAAS;AAAA,MACP,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,MACJ,GAAG,OAAO;AAAA,MACV,GAAG,OAAO;AAAA,IACZ;AAAA,IACA,OAAO,OAAO;AAAA,IACd,OAAO,OAAO;AAAA,IACd,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,KAAK;AAAA,MACH,GAAG,SAAS,iBAAiB,cAAc,OAAO;AAAA,MAClD,GAAG,SAAS,iBAAiB,eAAe,OAAO;AAAA,IACrD;AAAA,IACA,MAAM,SAAS,iBAAiB,cAAc,OAAO;AAAA,IACrD,MAAM,SAAS,iBAAiB,eAAe,OAAO;AAAA,IACtD,UAAU;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,MACT,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AAAA,EAEA,cAAkC;AAChC,UAAM,EAAE,MAAM,IAAI;AAClB,UAAM,QAAQ,MAAM;AACpB,UAAM,QAAQ,MAAM;AAEpB,UAAM,IAAI,OAAO;AACjB,UAAM,IAAI,OAAO;AACjB,UAAM,QAAQ,IAAI,MAAM,WAAW,MAAM,MAAM;AAC/C,UAAM,QAAQ,IAAI,MAAM,WAAW,MAAM,MAAM;AAC/C,UAAM,KAAK,IAAI,MAAM,QAAQ;AAC7B,UAAM,KAAK,IAAI,MAAM,QAAQ;AAC7B,UAAM,MAAM,IAAI,MAAM,SAAS,MAAM,IAAI;AACzC,UAAM,MAAM,IAAI,MAAM,SAAS,MAAM,IAAI;AACzC,UAAM,IAAI,IAAI,MAAM,OAAO,SAAS,iBAAiB,cAAc,OAAO;AAC1E,UAAM,IAAI,IAAI,MAAM,OAAO,SAAS,iBAAiB,eAAe,OAAO;AAC3E,UAAM,SAAS,IAAI,MAAM,YAAY,MAAM,IAAI,MAAM,IAAI,IAAI,MAAM,IAAI,MAAM,IAAI;AACjF,UAAM,SAAS,IAAI,MAAM,YAAY,MAAM,IAAI,MAAM,IAAI,IAAI,MAAM,IAAI,MAAM,IAAI;AACjF,UAAM,OAAO,MAAM,IAAI;AACvB,UAAM,UAAU,MAAM,IAAI;AAC1B,UAAM,SAAS,MAAM,IAAI;AACzB,UAAM,SAAS,MAAM,IAAI;AAEzB,UAAM,UAAU,IAAI,MAAM,UAAU,UAAU,MAAM,SAAS,SAAS;AACtE,UAAM,UAAU,IAAI,MAAM,SAAS,SAAS,MAAM,OAAO,OAAO;AAGhE,WAAO;AAAA,EACT;AAAA,EAEA,SAAS;AACP,aAAS,MAAM,KAAK,YAAY,CAAC,EAAE,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK,CAAC;AAAA,EACxE;AAAA,EAEA,oBAAoB,SAAS,MAAM;AACjC,SAAK,OAAO;AAAA,EACd,GAAG,GAAG;AAAA;AAAA;AAAA;AAAA,EAKN,cAAc;AACZ,SAAK,OAAO;AACZ,SAAK,kBAAkB;AAAA,EACzB;AACF;AAcO,SAAS,YAAoC;AAClD,SAAO,cAAc,YAAY;AACnC;",
4
+ "sourcesContent": ["import type { ServiceConfig, ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { debounce } from '../utils/debounce.js';\nimport { PASSIVE_CAPTURE_EVENT_OPTIONS } from './utils.js';\nimport { nextTick } from '../utils/nextTick.js';\n\nexport interface ScrollServiceProps {\n x: number;\n y: number;\n changed: { x: boolean; y: boolean };\n changedX: boolean;\n changedY: boolean;\n last: { x: number; y: number };\n lastX: number;\n lastY: number;\n delta: { x: number; y: number };\n deltaX: number;\n deltaY: number;\n progress: { x: number; y: number };\n progressX: number;\n progressY: number;\n max: { x: number; y: number };\n maxX: number;\n maxY: number;\n direction: { x: 'LEFT' | 'RIGHT' | 'NONE'; y: 'UP' | 'DOWN' | 'NONE' };\n isUp: boolean;\n isRight: boolean;\n isDown: boolean;\n isLeft: boolean;\n}\n\nexport type ScrollServiceInterface = ServiceInterface<ScrollServiceProps>;\n\nexport class ScrollService extends AbstractService<ScrollServiceProps> {\n static config: ServiceConfig = [\n [() => document, [['scroll', PASSIVE_CAPTURE_EVENT_OPTIONS]]],\n [() => window, [['resize', PASSIVE_CAPTURE_EVENT_OPTIONS]]],\n ];\n\n /**\n * Cached scroll max values, updated on resize and first scroll.\n * @private\n */\n __maxX: number | null = null;\n __maxY: number | null = null;\n\n /**\n * Observe scroll container size changes that do not trigger window resize.\n * @private\n */\n __resizeObserver: ResizeObserver | null = null;\n\n props: ScrollServiceProps = {\n x: window.scrollX,\n y: window.scrollY,\n changed: {\n x: false,\n y: false,\n },\n changedX: false,\n changedY: false,\n last: {\n x: window.scrollX,\n y: window.scrollY,\n },\n lastX: window.scrollX,\n lastY: window.scrollY,\n delta: {\n x: 0,\n y: 0,\n },\n deltaX: 0,\n deltaY: 0,\n max: {\n x: document.scrollingElement.scrollWidth - window.innerWidth,\n y: document.scrollingElement.scrollHeight - window.innerHeight,\n },\n maxX: document.scrollingElement.scrollWidth - window.innerWidth,\n maxY: document.scrollingElement.scrollHeight - window.innerHeight,\n progress: {\n x: 0,\n y: 0,\n },\n progressX: 0,\n progressY: 0,\n direction: {\n x: 'NONE',\n y: 'NONE',\n },\n isUp: false,\n isRight: false,\n isDown: false,\n isLeft: false,\n };\n\n updateProps(): ScrollServiceProps {\n const { props } = this;\n const yLast = props.y;\n const xLast = props.x;\n\n props.y = window.scrollY;\n props.x = window.scrollX;\n props.changed.x = props.changedX = props.x !== xLast;\n props.changed.y = props.changedY = props.y !== yLast;\n props.last.x = props.lastX = xLast;\n props.last.y = props.lastY = yLast;\n props.delta.x = props.deltaX = props.x - xLast;\n props.delta.y = props.deltaY = props.y - yLast;\n if (this.__maxX === null || this.__maxY === null) {\n this.__updateMaxValues();\n }\n props.max.x = props.maxX = this.__maxX;\n props.max.y = props.maxY = this.__maxY;\n props.progress.x = props.progressX = props.max.x === 0 ? 1 : props.x / props.max.x;\n props.progress.y = props.progressY = props.max.y === 0 ? 1 : props.y / props.max.y;\n props.isUp = props.y < yLast;\n props.isRight = props.x > xLast;\n props.isDown = props.y > yLast;\n props.isLeft = props.x < xLast;\n /* eslint-disable no-nested-ternary */\n props.direction.x = props.isRight ? 'RIGHT' : props.isLeft ? 'LEFT' : 'NONE';\n props.direction.y = props.isDown ? 'DOWN' : props.isUp ? 'UP' : 'NONE';\n /* eslint-enable no-nested-ternary */\n\n return props;\n }\n\n update(trigger = true) {\n nextTick(() => this.updateProps()).then(() => {\n if (trigger) {\n this.trigger(this.props);\n }\n });\n }\n\n onScrollDebounced = debounce(() => {\n this.update();\n }, 100);\n\n /**\n * Update cached max scroll values on resize.\n * @private\n */\n __updateMaxValues() {\n this.__maxX = document.scrollingElement.scrollWidth - window.innerWidth;\n this.__maxY = document.scrollingElement.scrollHeight - window.innerHeight;\n }\n\n /**\n * Scroll and resize handler.\n */\n handleEvent(event: Event) {\n if (event.type === 'resize') {\n this.__updateMaxValues();\n this.update(false);\n return;\n }\n\n this.update();\n this.onScrollDebounced();\n }\n\n init() {\n super.init();\n\n if (typeof ResizeObserver === 'function' && document.scrollingElement) {\n this.__resizeObserver = new ResizeObserver(() => {\n this.__updateMaxValues();\n });\n this.__resizeObserver.observe(document.scrollingElement);\n }\n }\n\n kill() {\n this.__resizeObserver?.disconnect();\n this.__resizeObserver = null;\n super.kill();\n }\n}\n\n/**\n * Use the scroll service.\n *\n * ```js\n * import { useScroll } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useScroll();\n * add(key, (props) => {});\n * remove(key);\n * props();\n * ```\n * @link https://js-toolkit.studiometa.dev/api/services/useScroll.html\n*/\nexport function useScroll(): ScrollServiceInterface {\n return ScrollService.getInstance();\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -13,10 +13,10 @@
13
13
  * @link https://js-toolkit.studiometa.dev/utils/collision/boundingRectToCircle.html
14
14
  */
15
15
  export declare function boundingRectToCircle({ x, y, width, height }: {
16
+ height: any;
17
+ width: any;
16
18
  x: any;
17
19
  y: any;
18
- width: any;
19
- height: any;
20
20
  }, force?: boolean): {
21
21
  x: any;
22
22
  y: any;
@@ -1,6 +1,5 @@
1
- import { clamp01, lerp, map, mean } from "../math/index.js";
2
- import { isDefined, isFunction, isNumber } from "../is.js";
3
- import { transform, TRANSFORM_PROPS } from "./transform.js";
1
+ import { clamp01, lerp, map } from "../math/index.js";
2
+ import { isFunction } from "../is.js";
4
3
  import { domScheduler as scheduler } from "../scheduler.js";
5
4
  import { tween, normalizeEase } from "../tween.js";
6
5
  import { eachElements } from "./utils.js";
@@ -8,82 +7,148 @@ import { startsWith } from "../string/index.js";
8
7
  let id = 0;
9
8
  const running = /* @__PURE__ */ new WeakMap();
10
9
  const CSSUnitConverter = {
11
- "%": (value, getSizeRef) => value * getSizeRef() / 100,
10
+ "%": (value, size) => value * size / 100,
12
11
  vh: (value) => value * window.innerHeight / 100,
13
12
  vw: (value) => value * window.innerWidth / 100,
14
13
  vmin: (value) => value * Math.min(window.innerWidth, window.innerHeight) / 100,
15
14
  vmax: (value) => value * Math.max(window.innerWidth, window.innerHeight) / 100
16
15
  };
17
- function getAnimationStepValue(val, getSizeRef) {
18
- if (isNumber(val)) {
16
+ function resolveUnitValue(val, elementSize) {
17
+ if (typeof val === "number") {
19
18
  return val;
20
19
  }
21
20
  if (!val[1] || !CSSUnitConverter[val[1]]) {
22
21
  return val[0];
23
22
  }
24
- return CSSUnitConverter[val[1]](val[0], getSizeRef);
23
+ return CSSUnitConverter[val[1]](val[0], elementSize);
25
24
  }
26
- const generateTranslateRenderStrategy = (sizeRef) => (element, fromValue, toValue, progress) => lerp(
27
- getAnimationStepValue(
28
- fromValue ?? 0,
29
- /* istanbul ignore next */
30
- () => element[sizeRef]
31
- ),
32
- getAnimationStepValue(toValue ?? 0, () => element[sizeRef]),
33
- progress
34
- );
35
- const widthBasedTranslateRenderStrategy = generateTranslateRenderStrategy("offsetWidth");
36
- const heightBasedTranslateRenderStrategy = generateTranslateRenderStrategy("offsetHeight");
37
- const generateLerpRenderStrategy = (defaultValue) => (element, fromValue, toValue, progress) => lerp(fromValue ?? defaultValue, toValue ?? defaultValue, progress);
38
- const scaleRenderStrategy = generateLerpRenderStrategy(1);
39
- const degreesRenderStrategy = generateLerpRenderStrategy(0);
40
- const transformRenderStrategies = {
41
- x: widthBasedTranslateRenderStrategy,
42
- y: heightBasedTranslateRenderStrategy,
43
- z: widthBasedTranslateRenderStrategy,
44
- scale: scaleRenderStrategy,
45
- scaleX: scaleRenderStrategy,
46
- scaleY: scaleRenderStrategy,
47
- scaleZ: scaleRenderStrategy,
48
- skew: degreesRenderStrategy,
49
- skewX: degreesRenderStrategy,
50
- skewY: degreesRenderStrategy,
51
- rotate: degreesRenderStrategy,
52
- rotateX: degreesRenderStrategy,
53
- rotateY: degreesRenderStrategy,
54
- rotateZ: degreesRenderStrategy
55
- };
56
- function render(element, from, to, progress) {
57
- const stepProgress = to.easing(map(progress, from.offset, to.offset, 0, 1));
25
+ const SIMPLE_TRANSFORM_DEFS = [
26
+ ["rotate", "rotate", "deg", 0],
27
+ ["rotateX", "rotateX", "deg", 0],
28
+ ["rotateY", "rotateY", "deg", 0],
29
+ ["rotateZ", "rotateZ", "deg", 0],
30
+ ["scale", "scale", "", 1],
31
+ ["scaleX", "scaleX", "", 1],
32
+ ["scaleY", "scaleY", "", 1],
33
+ ["scaleZ", "scaleZ", "", 1],
34
+ ["skew", "skew", "deg", 0],
35
+ ["skewX", "skewX", "deg", 0],
36
+ ["skewY", "skewY", "deg", 0]
37
+ ];
38
+ const TRANSLATE_DEFS = [
39
+ ["x", 0, "offsetWidth"],
40
+ ["y", 0, "offsetHeight"],
41
+ ["z", 0, "offsetWidth"]
42
+ ];
43
+ function compileSegment(from, to) {
44
+ const transformStarts = [];
45
+ const transformDeltas = [];
46
+ const transformCssFunctions = [];
47
+ const transformUnits = [];
48
+ const dynamicTranslates = [];
49
+ let hasTranslate = false;
50
+ const translateAxisIndices = [];
51
+ for (const [prop, defaultValue, sizeRef] of TRANSLATE_DEFS) {
52
+ const propertyExists = from[prop] !== void 0 || to[prop] !== void 0;
53
+ if (propertyExists) hasTranslate = true;
54
+ const fromValue = from[prop] ?? defaultValue;
55
+ const toValue = to[prop] ?? defaultValue;
56
+ const arrayIndex = transformStarts.length;
57
+ translateAxisIndices.push(arrayIndex);
58
+ transformCssFunctions.push("");
59
+ transformUnits.push("px");
60
+ if (typeof fromValue !== "number" || typeof toValue !== "number") {
61
+ transformStarts.push(0);
62
+ transformDeltas.push(0);
63
+ dynamicTranslates.push({ index: arrayIndex, from: fromValue, to: toValue, sizeRef });
64
+ } else {
65
+ transformStarts.push(fromValue);
66
+ transformDeltas.push(toValue - fromValue);
67
+ }
68
+ }
69
+ for (const [prop, cssFunction, unit, defaultValue] of SIMPLE_TRANSFORM_DEFS) {
70
+ if (from[prop] === void 0 && to[prop] === void 0) continue;
71
+ const startValue = from[prop] ?? defaultValue;
72
+ transformCssFunctions.push(cssFunction);
73
+ transformUnits.push(unit);
74
+ transformStarts.push(startValue);
75
+ transformDeltas.push((to[prop] ?? defaultValue) - startValue);
76
+ }
77
+ const hasOpacity = from.opacity !== void 0 || to.opacity !== void 0;
78
+ const opacityStart = hasOpacity ? from.opacity ?? 1 : 0;
79
+ const opacityDelta = hasOpacity ? (to.opacity ?? 1) - opacityStart : 0;
80
+ const customPropertyNames = [];
81
+ const customPropertyStarts = [];
82
+ const customPropertyDeltas = [];
83
+ if (from.vars && to.vars) {
84
+ for (const name of from.vars) {
85
+ const startValue = from[name];
86
+ const endValue = to[name] ?? startValue;
87
+ customPropertyNames.push(name);
88
+ customPropertyStarts.push(startValue);
89
+ customPropertyDeltas.push(endValue - startValue);
90
+ }
91
+ }
92
+ return {
93
+ fromOffset: from.offset,
94
+ toOffset: to.offset,
95
+ easing: to.easing,
96
+ transformStarts,
97
+ transformDeltas,
98
+ transformCssFunctions,
99
+ transformUnits,
100
+ hasTranslate,
101
+ translateAxisIndices,
102
+ simpleTransformStart: TRANSLATE_DEFS.length,
103
+ dynamicTranslates,
104
+ hasOpacity,
105
+ opacityStart,
106
+ opacityDelta,
107
+ customPropertyNames,
108
+ customPropertyStarts,
109
+ customPropertyDeltas,
110
+ transformOrigin: to.transformOrigin !== void 0 ? to.transformOrigin : false
111
+ };
112
+ }
113
+ function renderSegment(element, segment, progress) {
114
+ const easedProgress = segment.easing(
115
+ map(progress, segment.fromOffset, segment.toOffset, 0, 1)
116
+ );
58
117
  scheduler.read(() => {
118
+ for (let i = 0; i < segment.dynamicTranslates.length; i++) {
119
+ const dynamic = segment.dynamicTranslates[i];
120
+ const elementSize = element[dynamic.sizeRef];
121
+ const startValue = resolveUnitValue(dynamic.from, elementSize);
122
+ segment.transformStarts[dynamic.index] = startValue;
123
+ segment.transformDeltas[dynamic.index] = resolveUnitValue(dynamic.to, elementSize) - startValue;
124
+ }
125
+ let transformValue = "";
126
+ if (segment.hasTranslate) {
127
+ const xIndex = segment.translateAxisIndices[0];
128
+ const yIndex = segment.translateAxisIndices[1];
129
+ const zIndex = segment.translateAxisIndices[2];
130
+ const x = segment.transformStarts[xIndex] + segment.transformDeltas[xIndex] * easedProgress;
131
+ const y = segment.transformStarts[yIndex] + segment.transformDeltas[yIndex] * easedProgress;
132
+ const z = segment.transformStarts[zIndex] + segment.transformDeltas[zIndex] * easedProgress;
133
+ transformValue += `translate3d(${x}px, ${y}px, ${z}px) `;
134
+ }
135
+ for (let i = segment.simpleTransformStart; i < segment.transformStarts.length; i++) {
136
+ const value = segment.transformStarts[i] + segment.transformDeltas[i] * easedProgress;
137
+ transformValue += `${segment.transformCssFunctions[i]}(${value}${segment.transformUnits[i]}) `;
138
+ }
59
139
  let opacity = false;
60
- if (isDefined(from.opacity) || isDefined(to.opacity)) {
61
- opacity = map(stepProgress, 0, 1, from.opacity ?? 1, to.opacity ?? 1);
140
+ if (segment.hasOpacity) {
141
+ opacity = segment.opacityStart + segment.opacityDelta * easedProgress;
62
142
  } else if (element.style.opacity) {
63
143
  opacity = "";
64
144
  }
65
145
  let transformOrigin = false;
66
- if (isDefined(to.transformOrigin)) {
67
- transformOrigin = to.transformOrigin;
146
+ if (segment.transformOrigin !== false) {
147
+ transformOrigin = segment.transformOrigin;
68
148
  } else if (element.style.transformOrigin) {
69
149
  transformOrigin = "";
70
150
  }
71
- let customProperties = false;
72
- if (isDefined(from.vars) && isDefined(to.vars)) {
73
- customProperties = [];
74
- for (const customPropertyName of from.vars) {
75
- customProperties.push([
76
- customPropertyName,
77
- lerp(from[customPropertyName], to[customPropertyName], stepProgress)
78
- ]);
79
- }
80
- }
81
- const props = {};
82
- for (const name of TRANSFORM_PROPS) {
83
- if (isDefined(from[name]) || isDefined(to[name])) {
84
- props[name] = transformRenderStrategies[name](element, from[name], to[name], stepProgress);
85
- }
86
- }
151
+ const hasCustomProperties = segment.customPropertyNames.length > 0;
87
152
  scheduler.write(() => {
88
153
  if (opacity !== false) {
89
154
  element.style.opacity = opacity;
@@ -91,12 +156,15 @@ function render(element, from, to, progress) {
91
156
  if (transformOrigin !== false) {
92
157
  element.style.transformOrigin = transformOrigin;
93
158
  }
94
- if (customProperties !== false) {
95
- for (const customProperty of customProperties) {
96
- element.style.setProperty(customProperty[0], customProperty[1].toString());
159
+ if (hasCustomProperties) {
160
+ for (let i = 0; i < segment.customPropertyNames.length; i++) {
161
+ element.style.setProperty(
162
+ segment.customPropertyNames[i],
163
+ (segment.customPropertyStarts[i] + segment.customPropertyDeltas[i] * easedProgress).toString()
164
+ );
97
165
  }
98
166
  }
99
- transform(element, props);
167
+ element.style.transform = transformValue;
100
168
  });
101
169
  });
102
170
  }
@@ -110,17 +178,21 @@ function singleAnimate(element, keyframes, options = {}) {
110
178
  vars: Object.keys(keyframe).filter((key2) => startsWith(key2, "--"))
111
179
  })
112
180
  );
181
+ const segments = [];
182
+ for (let i = 1; i < normalizedKeyframes.length; i++) {
183
+ segments.push(compileSegment(normalizedKeyframes[i - 1], normalizedKeyframes[i]));
184
+ }
113
185
  if (!running.has(element)) {
114
186
  running.set(element, /* @__PURE__ */ new Map());
115
187
  }
116
188
  const key = `animate-${id}`;
117
189
  id += 1;
118
190
  function callback(progress) {
119
- let toIndex = 0;
120
- while (normalizedKeyframes[toIndex] && normalizedKeyframes[toIndex].offset <= progress && normalizedKeyframes[toIndex].offset !== 1) {
121
- toIndex += 1;
191
+ let segmentIndex = 0;
192
+ while (segmentIndex < segments.length - 1 && segments[segmentIndex].toOffset <= progress && segments[segmentIndex].toOffset !== 1) {
193
+ segmentIndex += 1;
122
194
  }
123
- render(element, normalizedKeyframes[toIndex - 1], normalizedKeyframes[toIndex], progress);
195
+ renderSegment(element, segments[segmentIndex], progress);
124
196
  }
125
197
  const controls = tween(callback, {
126
198
  ...options,
@@ -153,56 +225,54 @@ function animate(elementOrElements, keyframes, options = {}) {
153
225
  const progresses = [];
154
226
  const timings = [];
155
227
  let duration = 0;
156
- let previousTimings = [0, 0, 0];
228
+ let progressSum = 0;
229
+ let elementCount = 0;
157
230
  const controls = eachElements(elementOrElements, (element, index) => {
158
231
  const delay = staggerIsFunction ? stagger(element, index) : stagger * index;
159
232
  const itemOptions = { ...options, delay };
160
233
  if (durationFn) {
161
234
  itemOptions.duration = durationFn(element, index);
162
- } else if (!isDefined(itemOptions.duration)) {
235
+ } else if (itemOptions.duration === void 0) {
163
236
  itemOptions.duration = 1;
164
237
  }
165
238
  timings[index] = [itemOptions.duration, delay, itemOptions.duration + delay];
166
- if (timings[index][2] > previousTimings[2]) {
239
+ if (timings[index][2] > duration) {
167
240
  duration = timings[index][2];
168
241
  }
169
- previousTimings = timings[index];
170
242
  progresses[index] = 0;
243
+ elementCount = index + 1;
171
244
  itemOptions.onProgress = (itemProgress) => {
245
+ progressSum += itemProgress - progresses[index];
172
246
  progresses[index] = itemProgress;
173
247
  if (progressFn) {
174
- progressFn(mean(progresses));
248
+ progressFn(progressSum / elementCount);
175
249
  }
176
250
  };
177
251
  return singleAnimate(element, keyframes, itemOptions);
178
252
  });
179
- const delegate = (key) => (
180
- // eslint-disable-next-line consistent-return
181
- function delegated() {
182
- if (key === "progress") {
183
- if (arguments.length === 1) {
184
- const newProgress = arguments[0];
185
- const newTime = lerp(0, duration, newProgress);
186
- for (const [index, control] of controls.entries()) {
187
- const controlProgress = clamp01(
188
- map(newTime, timings[index][1], timings[index][2], 0, 1)
189
- );
190
- control.progress(controlProgress);
191
- }
192
- }
193
- return mean(progresses);
194
- }
195
- for (const control of controls) {
196
- control[key].call(null, arguments);
253
+ function forAll(key) {
254
+ for (const control of controls) {
255
+ control[key]();
256
+ }
257
+ }
258
+ function progress(newProgress) {
259
+ if (newProgress !== void 0) {
260
+ const newTime = lerp(0, duration, newProgress);
261
+ for (let i = 0; i < controls.length; i++) {
262
+ const controlProgress = clamp01(
263
+ map(newTime, timings[i][1], timings[i][2], 0, 1)
264
+ );
265
+ controls[i].progress(controlProgress);
197
266
  }
198
267
  }
199
- );
268
+ return progressSum / elementCount;
269
+ }
200
270
  return {
201
- start: delegate("start"),
202
- pause: delegate("pause"),
203
- finish: delegate("finish"),
204
- play: delegate("play"),
205
- progress: delegate("progress")
271
+ start: () => forAll("start"),
272
+ pause: () => forAll("pause"),
273
+ finish: () => forAll("finish"),
274
+ play: () => forAll("play"),
275
+ progress
206
276
  };
207
277
  }
208
278
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/utils/css/animate.ts"],
4
- "sourcesContent": ["import { clamp01, lerp, map, mean } from '../math/index.js';\nimport { isDefined, isFunction, isNumber } from '../is.js';\nimport { transform, TRANSFORM_PROPS } from './transform.js';\nimport { domScheduler as scheduler } from '../scheduler.js';\nimport { tween, normalizeEase } from '../tween.js';\nimport { eachElements } from './utils.js';\nimport { startsWith } from '../string/index.js';\nimport type { TransformProps } from './transform.js';\nimport type { EasingFunction } from '../math/index.js';\nimport type { BezierCurve, Tween, TweenOptions } from '../tween.js';\n\nexport type CSSCustomPropertyName = `--${string}`;\n\ntype KeyframeTransforms<Type> = {\n [Property in keyof Type]: number | [number, string];\n};\n\nexport type Keyframe = Partial<\n KeyframeTransforms<TransformProps> & {\n opacity: number;\n transformOrigin: string;\n easing: EasingFunction | BezierCurve;\n offset: number;\n [key: CSSCustomPropertyName]: number;\n }\n>;\n\nexport type NormalizedKeyframe = Keyframe & {\n easing: EasingFunction;\n offset: number;\n vars: string[];\n};\n\nexport interface AnimateOptions extends Omit<TweenOptions, 'duration'> {\n /**\n * The duration of the tween, in seconds.\n * When using multiple targets, it can be a function which will be\n * called with the current target and its index and should return\n * the duration in seconds for this element.\n *\n * Defaults to `1`.\n */\n duration?: number | ((target: HTMLElement, index: number) => number);\n /**\n * Delay between the start of each target animation, in seconds.\n * When using multiple targets, it can be a function which will be called\n * with the current target and its index and should return the delay\n * in seconds for this element's tween.\n *\n * Defaults to `0`.\n */\n stagger?: number | ((target: HTMLElement, index: number) => number);\n}\n\nexport type Animate = Tween;\n\nlet id = 0;\nconst running = new WeakMap();\n\nconst CSSUnitConverter = {\n '%': (value, getSizeRef) => (value * getSizeRef()) / 100,\n vh: (value) => (value * window.innerHeight) / 100,\n vw: (value) => (value * window.innerWidth) / 100,\n vmin: (value) => (value * Math.min(window.innerWidth, window.innerHeight)) / 100,\n vmax: (value) => (value * Math.max(window.innerWidth, window.innerHeight)) / 100,\n};\n\n/**\n * Get the value from a step property.\n */\nfunction getAnimationStepValue(val: number | [number, string], getSizeRef: () => number): number {\n if (isNumber(val)) {\n return val;\n }\n\n if (!val[1] || !CSSUnitConverter[val[1]]) {\n return val[0];\n }\n\n return CSSUnitConverter[val[1]](val[0], getSizeRef);\n}\n\nconst generateTranslateRenderStrategy = (sizeRef) => (element, fromValue, toValue, progress) =>\n lerp(\n getAnimationStepValue(\n fromValue ?? 0,\n /* istanbul ignore next */\n () => element[sizeRef],\n ),\n getAnimationStepValue(toValue ?? 0, () => element[sizeRef]),\n progress,\n );\nconst widthBasedTranslateRenderStrategy = generateTranslateRenderStrategy('offsetWidth');\nconst heightBasedTranslateRenderStrategy = generateTranslateRenderStrategy('offsetHeight');\n\nconst generateLerpRenderStrategy = (defaultValue) => (element, fromValue, toValue, progress) =>\n lerp(fromValue ?? defaultValue, toValue ?? defaultValue, progress);\nconst scaleRenderStrategy = generateLerpRenderStrategy(1);\nconst degreesRenderStrategy = generateLerpRenderStrategy(0);\n\nconst transformRenderStrategies = {\n x: widthBasedTranslateRenderStrategy,\n y: heightBasedTranslateRenderStrategy,\n z: widthBasedTranslateRenderStrategy,\n scale: scaleRenderStrategy,\n scaleX: scaleRenderStrategy,\n scaleY: scaleRenderStrategy,\n scaleZ: scaleRenderStrategy,\n skew: degreesRenderStrategy,\n skewX: degreesRenderStrategy,\n skewY: degreesRenderStrategy,\n rotate: degreesRenderStrategy,\n rotateX: degreesRenderStrategy,\n rotateY: degreesRenderStrategy,\n rotateZ: degreesRenderStrategy,\n};\n\n/**\n * Render an element style based on 2 keyframes and a progress value.\n */\nfunction render(\n element: HTMLElement,\n from: NormalizedKeyframe,\n to: NormalizedKeyframe,\n progress: number,\n) {\n const stepProgress = to.easing(map(progress, from.offset, to.offset, 0, 1));\n\n scheduler.read(() => {\n let opacity: false | number | string = false;\n if (isDefined(from.opacity) || isDefined(to.opacity)) {\n opacity = map(stepProgress, 0, 1, from.opacity ?? 1, to.opacity ?? 1);\n } else if (element.style.opacity) {\n opacity = '';\n }\n\n let transformOrigin: false | string = false;\n if (isDefined(to.transformOrigin)) {\n transformOrigin = to.transformOrigin;\n } else if (element.style.transformOrigin) {\n transformOrigin = '';\n }\n\n let customProperties: false | [string, number][] = false;\n if (isDefined(from.vars) && isDefined(to.vars)) {\n customProperties = [];\n for (const customPropertyName of from.vars) {\n customProperties.push([\n customPropertyName,\n lerp(from[customPropertyName], to[customPropertyName], stepProgress),\n ]);\n }\n }\n\n const props = {};\n\n for (const name of TRANSFORM_PROPS) {\n if (isDefined(from[name]) || isDefined(to[name])) {\n props[name] = transformRenderStrategies[name](element, from[name], to[name], stepProgress);\n }\n }\n\n scheduler.write(() => {\n if (opacity !== false) {\n // @ts-ignore\n element.style.opacity = opacity;\n }\n if (transformOrigin !== false) {\n element.style.transformOrigin = transformOrigin;\n }\n if (customProperties !== false) {\n for (const customProperty of customProperties) {\n element.style.setProperty(customProperty[0], customProperty[1].toString());\n }\n }\n transform(element, props);\n });\n });\n}\n\n/**\n * Animate an element.\n */\nfunction singleAnimate(\n element: HTMLElement,\n keyframes: Keyframe[],\n options: TweenOptions = {},\n): Animate {\n const keyframesCount = keyframes.length - 1;\n const normalizedKeyframes = keyframes.map(\n (keyframe, index): NormalizedKeyframe => ({\n ...keyframe,\n offset: keyframe.offset ?? index / keyframesCount,\n easing: normalizeEase(keyframe.easing),\n vars: Object.keys(keyframe).filter((key) => startsWith(key, '--')),\n }),\n );\n\n if (!running.has(element)) {\n running.set(element, new Map());\n }\n\n const key = `animate-${id}`;\n id += 1;\n\n /**\n * Set the progress value.\n */\n function callback(progress: number) {\n let toIndex = 0;\n while (\n normalizedKeyframes[toIndex] &&\n normalizedKeyframes[toIndex].offset <= progress &&\n normalizedKeyframes[toIndex].offset !== 1\n ) {\n toIndex += 1;\n }\n\n render(element, normalizedKeyframes[toIndex - 1], normalizedKeyframes[toIndex], progress);\n }\n\n const controls = tween(callback, {\n ...options,\n onStart(progress) {\n if (isFunction(options.onStart)) {\n options.onStart(progress);\n }\n // Stop running instances\n const runningKeys = running.get(element);\n for (const [runningKey, runningPause] of runningKeys.entries()) {\n runningPause();\n runningKeys.delete(runningKey);\n }\n runningKeys.set(key, controls.pause);\n running.set(element, runningKeys);\n },\n });\n\n return controls;\n}\n\ntype Duration = number;\ntype Delay = number;\ntype DurationWithDelay = number;\n\n/**\n * Animate one or more elements.\n * @link https://js-toolkit.studiometa.dev/utils/css/animate.html\n*/\nexport function animate(\n elementOrElements: HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>,\n keyframes: Keyframe[],\n options: AnimateOptions = {},\n): Animate {\n if (elementOrElements instanceof HTMLElement) {\n return singleAnimate(elementOrElements, keyframes, {\n ...options,\n duration: isFunction(options.duration)\n ? options.duration(elementOrElements, 0)\n : options.duration,\n });\n }\n\n const stagger = options.stagger ?? 0;\n const staggerIsFunction = isFunction(stagger);\n const durationFn = isFunction(options.duration) ? options.duration : null;\n const progressFn = isFunction(options.onProgress) ? options.onProgress : null;\n const progresses: number[] = [];\n const timings: [Duration, Delay, DurationWithDelay][] = [];\n let duration = 0;\n let previousTimings = [0, 0, 0];\n\n const controls = eachElements(elementOrElements, (element, index) => {\n const delay = staggerIsFunction ? stagger(element, index) : stagger * index;\n const itemOptions = { ...options, delay } as TweenOptions;\n\n if (durationFn) {\n itemOptions.duration = durationFn(element, index);\n } else if (!isDefined(itemOptions.duration)) {\n itemOptions.duration = 1;\n }\n\n timings[index] = [itemOptions.duration, delay, itemOptions.duration + delay];\n\n if (timings[index][2] > previousTimings[2]) {\n // eslint-disable-next-line prefer-destructuring\n duration = timings[index][2];\n }\n\n previousTimings = timings[index];\n\n progresses[index] = 0;\n itemOptions.onProgress = (itemProgress) => {\n progresses[index] = itemProgress;\n if (progressFn) {\n progressFn(mean(progresses));\n }\n };\n\n return singleAnimate(element, keyframes, itemOptions);\n });\n\n const delegate = (key) =>\n // eslint-disable-next-line consistent-return\n function delegated() {\n if (key === 'progress') {\n if (arguments.length === 1) {\n // eslint-disable-next-line prefer-rest-params\n const newProgress = arguments[0];\n const newTime = lerp(0, duration, newProgress);\n for (const [index, control] of controls.entries()) {\n const controlProgress = clamp01(\n map(newTime, timings[index][1], timings[index][2], 0, 1),\n );\n control.progress(controlProgress);\n }\n }\n\n return mean(progresses);\n }\n\n for (const control of controls) {\n // eslint-disable-next-line prefer-rest-params\n control[key].call(null, arguments);\n }\n };\n\n return {\n start: delegate('start'),\n pause: delegate('pause'),\n finish: delegate('finish'),\n play: delegate('play'),\n progress: delegate('progress'),\n };\n}\n"],
5
- "mappings": "AAAA,SAAS,SAAS,MAAM,KAAK,YAAY;AACzC,SAAS,WAAW,YAAY,gBAAgB;AAChD,SAAS,WAAW,uBAAuB;AAC3C,SAAS,gBAAgB,iBAAiB;AAC1C,SAAS,OAAO,qBAAqB;AACrC,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAkD3B,IAAI,KAAK;AACT,MAAM,UAAU,oBAAI,QAAQ;AAE5B,MAAM,mBAAmB;AAAA,EACvB,KAAK,CAAC,OAAO,eAAgB,QAAQ,WAAW,IAAK;AAAA,EACrD,IAAI,CAAC,UAAW,QAAQ,OAAO,cAAe;AAAA,EAC9C,IAAI,CAAC,UAAW,QAAQ,OAAO,aAAc;AAAA,EAC7C,MAAM,CAAC,UAAW,QAAQ,KAAK,IAAI,OAAO,YAAY,OAAO,WAAW,IAAK;AAAA,EAC7E,MAAM,CAAC,UAAW,QAAQ,KAAK,IAAI,OAAO,YAAY,OAAO,WAAW,IAAK;AAC/E;AAKA,SAAS,sBAAsB,KAAgC,YAAkC;AAC/F,MAAI,SAAS,GAAG,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,CAAC,GAAG;AACxC,WAAO,IAAI,CAAC;AAAA,EACd;AAEA,SAAO,iBAAiB,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,UAAU;AACpD;AAEA,MAAM,kCAAkC,CAAC,YAAY,CAAC,SAAS,WAAW,SAAS,aACjF;AAAA,EACE;AAAA,IACE,aAAa;AAAA;AAAA,IAEb,MAAM,QAAQ,OAAO;AAAA,EACvB;AAAA,EACA,sBAAsB,WAAW,GAAG,MAAM,QAAQ,OAAO,CAAC;AAAA,EAC1D;AACF;AACF,MAAM,oCAAoC,gCAAgC,aAAa;AACvF,MAAM,qCAAqC,gCAAgC,cAAc;AAEzF,MAAM,6BAA6B,CAAC,iBAAiB,CAAC,SAAS,WAAW,SAAS,aACjF,KAAK,aAAa,cAAc,WAAW,cAAc,QAAQ;AACnE,MAAM,sBAAsB,2BAA2B,CAAC;AACxD,MAAM,wBAAwB,2BAA2B,CAAC;AAE1D,MAAM,4BAA4B;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAKA,SAAS,OACP,SACA,MACA,IACA,UACA;AACA,QAAM,eAAe,GAAG,OAAO,IAAI,UAAU,KAAK,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC;AAE1E,YAAU,KAAK,MAAM;AACnB,QAAI,UAAmC;AACvC,QAAI,UAAU,KAAK,OAAO,KAAK,UAAU,GAAG,OAAO,GAAG;AACpD,gBAAU,IAAI,cAAc,GAAG,GAAG,KAAK,WAAW,GAAG,GAAG,WAAW,CAAC;AAAA,IACtE,WAAW,QAAQ,MAAM,SAAS;AAChC,gBAAU;AAAA,IACZ;AAEA,QAAI,kBAAkC;AACtC,QAAI,UAAU,GAAG,eAAe,GAAG;AACjC,wBAAkB,GAAG;AAAA,IACvB,WAAW,QAAQ,MAAM,iBAAiB;AACxC,wBAAkB;AAAA,IACpB;AAEA,QAAI,mBAA+C;AACnD,QAAI,UAAU,KAAK,IAAI,KAAK,UAAU,GAAG,IAAI,GAAG;AAC9C,yBAAmB,CAAC;AACpB,iBAAW,sBAAsB,KAAK,MAAM;AAC1C,yBAAiB,KAAK;AAAA,UACpB;AAAA,UACA,KAAK,KAAK,kBAAkB,GAAG,GAAG,kBAAkB,GAAG,YAAY;AAAA,QACrE,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,QAAQ,CAAC;AAEf,eAAW,QAAQ,iBAAiB;AAClC,UAAI,UAAU,KAAK,IAAI,CAAC,KAAK,UAAU,GAAG,IAAI,CAAC,GAAG;AAChD,cAAM,IAAI,IAAI,0BAA0B,IAAI,EAAE,SAAS,KAAK,IAAI,GAAG,GAAG,IAAI,GAAG,YAAY;AAAA,MAC3F;AAAA,IACF;AAEA,cAAU,MAAM,MAAM;AACpB,UAAI,YAAY,OAAO;AAErB,gBAAQ,MAAM,UAAU;AAAA,MAC1B;AACA,UAAI,oBAAoB,OAAO;AAC7B,gBAAQ,MAAM,kBAAkB;AAAA,MAClC;AACA,UAAI,qBAAqB,OAAO;AAC9B,mBAAW,kBAAkB,kBAAkB;AAC7C,kBAAQ,MAAM,YAAY,eAAe,CAAC,GAAG,eAAe,CAAC,EAAE,SAAS,CAAC;AAAA,QAC3E;AAAA,MACF;AACA,gBAAU,SAAS,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH,CAAC;AACH;AAKA,SAAS,cACP,SACA,WACA,UAAwB,CAAC,GAChB;AACT,QAAM,iBAAiB,UAAU,SAAS;AAC1C,QAAM,sBAAsB,UAAU;AAAA,IACpC,CAAC,UAAU,WAA+B;AAAA,MACxC,GAAG;AAAA,MACH,QAAQ,SAAS,UAAU,QAAQ;AAAA,MACnC,QAAQ,cAAc,SAAS,MAAM;AAAA,MACrC,MAAM,OAAO,KAAK,QAAQ,EAAE,OAAO,CAACA,SAAQ,WAAWA,MAAK,IAAI,CAAC;AAAA,IACnE;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,IAAI,OAAO,GAAG;AACzB,YAAQ,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,EAChC;AAEA,QAAM,MAAM,WAAW,EAAE;AACzB,QAAM;AAKN,WAAS,SAAS,UAAkB;AAClC,QAAI,UAAU;AACd,WACE,oBAAoB,OAAO,KAC3B,oBAAoB,OAAO,EAAE,UAAU,YACvC,oBAAoB,OAAO,EAAE,WAAW,GACxC;AACA,iBAAW;AAAA,IACb;AAEA,WAAO,SAAS,oBAAoB,UAAU,CAAC,GAAG,oBAAoB,OAAO,GAAG,QAAQ;AAAA,EAC1F;AAEA,QAAM,WAAW,MAAM,UAAU;AAAA,IAC/B,GAAG;AAAA,IACH,QAAQ,UAAU;AAChB,UAAI,WAAW,QAAQ,OAAO,GAAG;AAC/B,gBAAQ,QAAQ,QAAQ;AAAA,MAC1B;AAEA,YAAM,cAAc,QAAQ,IAAI,OAAO;AACvC,iBAAW,CAAC,YAAY,YAAY,KAAK,YAAY,QAAQ,GAAG;AAC9D,qBAAa;AACb,oBAAY,OAAO,UAAU;AAAA,MAC/B;AACA,kBAAY,IAAI,KAAK,SAAS,KAAK;AACnC,cAAQ,IAAI,SAAS,WAAW;AAAA,IAClC;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAUO,SAAS,QACd,mBACA,WACA,UAA0B,CAAC,GAClB;AACT,MAAI,6BAA6B,aAAa;AAC5C,WAAO,cAAc,mBAAmB,WAAW;AAAA,MACjD,GAAG;AAAA,MACH,UAAU,WAAW,QAAQ,QAAQ,IACjC,QAAQ,SAAS,mBAAmB,CAAC,IACrC,QAAQ;AAAA,IACd,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,oBAAoB,WAAW,OAAO;AAC5C,QAAM,aAAa,WAAW,QAAQ,QAAQ,IAAI,QAAQ,WAAW;AACrE,QAAM,aAAa,WAAW,QAAQ,UAAU,IAAI,QAAQ,aAAa;AACzE,QAAM,aAAuB,CAAC;AAC9B,QAAM,UAAkD,CAAC;AACzD,MAAI,WAAW;AACf,MAAI,kBAAkB,CAAC,GAAG,GAAG,CAAC;AAE9B,QAAM,WAAW,aAAa,mBAAmB,CAAC,SAAS,UAAU;AACnE,UAAM,QAAQ,oBAAoB,QAAQ,SAAS,KAAK,IAAI,UAAU;AACtE,UAAM,cAAc,EAAE,GAAG,SAAS,MAAM;AAExC,QAAI,YAAY;AACd,kBAAY,WAAW,WAAW,SAAS,KAAK;AAAA,IAClD,WAAW,CAAC,UAAU,YAAY,QAAQ,GAAG;AAC3C,kBAAY,WAAW;AAAA,IACzB;AAEA,YAAQ,KAAK,IAAI,CAAC,YAAY,UAAU,OAAO,YAAY,WAAW,KAAK;AAE3E,QAAI,QAAQ,KAAK,EAAE,CAAC,IAAI,gBAAgB,CAAC,GAAG;AAE1C,iBAAW,QAAQ,KAAK,EAAE,CAAC;AAAA,IAC7B;AAEA,sBAAkB,QAAQ,KAAK;AAE/B,eAAW,KAAK,IAAI;AACpB,gBAAY,aAAa,CAAC,iBAAiB;AACzC,iBAAW,KAAK,IAAI;AACpB,UAAI,YAAY;AACd,mBAAW,KAAK,UAAU,CAAC;AAAA,MAC7B;AAAA,IACF;AAEA,WAAO,cAAc,SAAS,WAAW,WAAW;AAAA,EACtD,CAAC;AAED,QAAM,WAAW,CAAC;AAAA;AAAA,IAEhB,SAAS,YAAY;AACnB,UAAI,QAAQ,YAAY;AACtB,YAAI,UAAU,WAAW,GAAG;AAE1B,gBAAM,cAAc,UAAU,CAAC;AAC/B,gBAAM,UAAU,KAAK,GAAG,UAAU,WAAW;AAC7C,qBAAW,CAAC,OAAO,OAAO,KAAK,SAAS,QAAQ,GAAG;AACjD,kBAAM,kBAAkB;AAAA,cACtB,IAAI,SAAS,QAAQ,KAAK,EAAE,CAAC,GAAG,QAAQ,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;AAAA,YACzD;AACA,oBAAQ,SAAS,eAAe;AAAA,UAClC;AAAA,QACF;AAEA,eAAO,KAAK,UAAU;AAAA,MACxB;AAEA,iBAAW,WAAW,UAAU;AAE9B,gBAAQ,GAAG,EAAE,KAAK,MAAM,SAAS;AAAA,MACnC;AAAA,IACF;AAAA;AAEF,SAAO;AAAA,IACL,OAAO,SAAS,OAAO;AAAA,IACvB,OAAO,SAAS,OAAO;AAAA,IACvB,QAAQ,SAAS,QAAQ;AAAA,IACzB,MAAM,SAAS,MAAM;AAAA,IACrB,UAAU,SAAS,UAAU;AAAA,EAC/B;AACF;",
4
+ "sourcesContent": ["import { clamp01, lerp, map } from '../math/index.js';\nimport { isFunction } from '../is.js';\nimport { domScheduler as scheduler } from '../scheduler.js';\nimport { tween, normalizeEase } from '../tween.js';\nimport { eachElements } from './utils.js';\nimport { startsWith } from '../string/index.js';\nimport type { TransformProps } from './transform.js';\nimport type { EasingFunction } from '../math/index.js';\nimport type { BezierCurve, Tween, TweenOptions } from '../tween.js';\n\nexport type CSSCustomPropertyName = `--${string}`;\n\ntype KeyframeTransforms<Type> = {\n [Property in keyof Type]: number | [number, string];\n};\n\nexport type Keyframe = Partial<\n KeyframeTransforms<TransformProps> & {\n opacity: number;\n transformOrigin: string;\n easing: EasingFunction | BezierCurve;\n offset: number;\n [key: CSSCustomPropertyName]: number;\n }\n>;\n\nexport type NormalizedKeyframe = Keyframe & {\n easing: EasingFunction;\n offset: number;\n vars: string[];\n};\n\n\n/**\n * A pre-compiled segment between two keyframes.\n * All constant parts (deltas, offsets, writers) are resolved once at creation.\n * The render loop only does multiply-add and string concatenation.\n */\ninterface CompiledSegment {\n fromOffset: number;\n toOffset: number;\n easing: EasingFunction;\n /** Parallel arrays for transform properties (structure-of-arrays layout) */\n transformStarts: number[];\n transformDeltas: number[];\n transformCssFunctions: string[];\n transformUnits: string[];\n /** Whether translate3d is needed */\n hasTranslate: boolean;\n /** Indices into transformStarts/transformDeltas for x, y, z axes */\n translateAxisIndices: number[];\n /** The index where non-translate transforms start in the parallel arrays */\n simpleTransformStart: number;\n /** Translate properties that need element size for CSS unit conversion at render time */\n dynamicTranslates: Array<{\n index: number;\n from: number | [number, string];\n to: number | [number, string];\n sizeRef: string;\n }>;\n /** Opacity: pre-computed start and delta, or null if not animated */\n opacityStart: number;\n opacityDelta: number;\n hasOpacity: boolean;\n /** CSS custom properties: parallel arrays */\n customPropertyNames: string[];\n customPropertyStarts: number[];\n customPropertyDeltas: number[];\n /** Transform origin for this segment, or false */\n transformOrigin: string | false;\n}\n\nexport interface AnimateOptions extends Omit<TweenOptions, 'duration'> {\n /**\n * The duration of the tween, in seconds.\n * When using multiple targets, it can be a function which will be\n * called with the current target and its index and should return\n * the duration in seconds for this element.\n *\n * Defaults to `1`.\n */\n duration?: number | ((target: HTMLElement, index: number) => number);\n /**\n * Delay between the start of each target animation, in seconds.\n * When using multiple targets, it can be a function which will be called\n * with the current target and its index and should return the delay\n * in seconds for this element's tween.\n *\n * Defaults to `0`.\n */\n stagger?: number | ((target: HTMLElement, index: number) => number);\n}\n\nexport type Animate = Tween;\n\nlet id = 0;\nconst running = new WeakMap();\n\nconst CSSUnitConverter = {\n '%': (value: number, size: number) => (value * size) / 100,\n vh: (value: number) => (value * window.innerHeight) / 100,\n vw: (value: number) => (value * window.innerWidth) / 100,\n vmin: (value: number) => (value * Math.min(window.innerWidth, window.innerHeight)) / 100,\n vmax: (value: number) => (value * Math.max(window.innerWidth, window.innerHeight)) / 100,\n};\n\n/**\n * Resolve a keyframe value that may have a CSS unit (e.g. [50, '%']).\n */\nfunction resolveUnitValue(val: number | [number, string], elementSize: number): number {\n if (typeof val === 'number') {\n return val;\n }\n\n if (!val[1] || !CSSUnitConverter[val[1]]) {\n return val[0];\n }\n\n return CSSUnitConverter[val[1]](val[0], elementSize);\n}\n\n/**\n * Non-translate transform property definitions: [keyframeProp, cssFn, unit, defaultValue].\n */\nconst SIMPLE_TRANSFORM_DEFS: ReadonlyArray<\n readonly [string, string, string, number]\n> = [\n ['rotate', 'rotate', 'deg', 0],\n ['rotateX', 'rotateX', 'deg', 0],\n ['rotateY', 'rotateY', 'deg', 0],\n ['rotateZ', 'rotateZ', 'deg', 0],\n ['scale', 'scale', '', 1],\n ['scaleX', 'scaleX', '', 1],\n ['scaleY', 'scaleY', '', 1],\n ['scaleZ', 'scaleZ', '', 1],\n ['skew', 'skew', 'deg', 0],\n ['skewX', 'skewX', 'deg', 0],\n ['skewY', 'skewY', 'deg', 0],\n];\n\n/**\n * Translate axis definitions: [keyframeProp, defaultValue, sizeRef].\n * These are grouped into a single translate3d() call during rendering.\n */\nconst TRANSLATE_DEFS: ReadonlyArray<\n readonly [string, number, string]\n> = [\n ['x', 0, 'offsetWidth'],\n ['y', 0, 'offsetHeight'],\n ['z', 0, 'offsetWidth'],\n];\n\n/**\n * Compile a pair of keyframes into a pre-computed segment.\n * All constant work (deltas, property filtering) is done here once.\n */\nfunction compileSegment(\n from: NormalizedKeyframe,\n to: NormalizedKeyframe,\n): CompiledSegment {\n const transformStarts: number[] = [];\n const transformDeltas: number[] = [];\n const transformCssFunctions: string[] = [];\n const transformUnits: string[] = [];\n const dynamicTranslates: CompiledSegment['dynamicTranslates'] = [];\n\n // Translate axes: grouped into translate3d(x, y, z) during rendering.\n // We track indices into the parallel arrays for x, y, z.\n let hasTranslate = false;\n const translateAxisIndices: number[] = [];\n\n for (const [prop, defaultValue, sizeRef] of TRANSLATE_DEFS) {\n const propertyExists = from[prop] !== undefined || to[prop] !== undefined;\n if (propertyExists) hasTranslate = true;\n\n const fromValue = from[prop] ?? defaultValue;\n const toValue = to[prop] ?? defaultValue;\n const arrayIndex = transformStarts.length;\n translateAxisIndices.push(arrayIndex);\n\n // Placeholder CSS function/unit \u2014 not used for translate (special rendering)\n transformCssFunctions.push('');\n transformUnits.push('px');\n\n if (typeof fromValue !== 'number' || typeof toValue !== 'number') {\n transformStarts.push(0);\n transformDeltas.push(0);\n dynamicTranslates.push({ index: arrayIndex, from: fromValue, to: toValue, sizeRef });\n } else {\n transformStarts.push(fromValue);\n transformDeltas.push(toValue - fromValue);\n }\n }\n\n // Non-translate transforms: each gets its own CSS function\n for (const [prop, cssFunction, unit, defaultValue] of SIMPLE_TRANSFORM_DEFS) {\n if (from[prop] === undefined && to[prop] === undefined) continue;\n\n const startValue = (from[prop] as number) ?? defaultValue;\n transformCssFunctions.push(cssFunction);\n transformUnits.push(unit);\n transformStarts.push(startValue);\n transformDeltas.push(((to[prop] as number) ?? defaultValue) - startValue);\n }\n\n // Opacity\n const hasOpacity = from.opacity !== undefined || to.opacity !== undefined;\n const opacityStart = hasOpacity ? (from.opacity ?? 1) : 0;\n const opacityDelta = hasOpacity ? (to.opacity ?? 1) - opacityStart : 0;\n\n // CSS custom properties\n const customPropertyNames: string[] = [];\n const customPropertyStarts: number[] = [];\n const customPropertyDeltas: number[] = [];\n if (from.vars && to.vars) {\n for (const name of from.vars) {\n const startValue = from[name] as number;\n const endValue = (to[name] as number | undefined) ?? startValue;\n customPropertyNames.push(name);\n customPropertyStarts.push(startValue);\n customPropertyDeltas.push(endValue - startValue);\n }\n }\n\n return {\n fromOffset: from.offset,\n toOffset: to.offset,\n easing: to.easing,\n transformStarts,\n transformDeltas,\n transformCssFunctions,\n transformUnits,\n hasTranslate,\n translateAxisIndices,\n simpleTransformStart: TRANSLATE_DEFS.length,\n dynamicTranslates,\n hasOpacity,\n opacityStart,\n opacityDelta,\n customPropertyNames,\n customPropertyStarts,\n customPropertyDeltas,\n transformOrigin: to.transformOrigin !== undefined ? to.transformOrigin : false,\n };\n}\n\n/**\n * Render an element using a pre-compiled segment and a progress value.\n * The hot path: only multiply-add, string concatenation, and DOM writes.\n */\nfunction renderSegment(\n element: HTMLElement,\n segment: CompiledSegment,\n progress: number,\n) {\n const easedProgress = segment.easing(\n map(progress, segment.fromOffset, segment.toOffset, 0, 1),\n );\n\n scheduler.read(() => {\n // Resolve dynamic (CSS-unit) transforms that need element size\n for (let i = 0; i < segment.dynamicTranslates.length; i++) {\n const dynamic = segment.dynamicTranslates[i];\n const elementSize = element[dynamic.sizeRef];\n const startValue = resolveUnitValue(dynamic.from, elementSize);\n segment.transformStarts[dynamic.index] = startValue;\n segment.transformDeltas[dynamic.index] = resolveUnitValue(dynamic.to, elementSize) - startValue;\n }\n\n // Build transform string: translate3d grouped, then individual transforms\n let transformValue = '';\n\n if (segment.hasTranslate) {\n const xIndex = segment.translateAxisIndices[0];\n const yIndex = segment.translateAxisIndices[1];\n const zIndex = segment.translateAxisIndices[2];\n const x = segment.transformStarts[xIndex] + segment.transformDeltas[xIndex] * easedProgress;\n const y = segment.transformStarts[yIndex] + segment.transformDeltas[yIndex] * easedProgress;\n const z = segment.transformStarts[zIndex] + segment.transformDeltas[zIndex] * easedProgress;\n transformValue += `translate3d(${x}px, ${y}px, ${z}px) `;\n }\n\n for (let i = segment.simpleTransformStart; i < segment.transformStarts.length; i++) {\n const value = segment.transformStarts[i] + segment.transformDeltas[i] * easedProgress;\n transformValue += `${segment.transformCssFunctions[i]}(${value}${segment.transformUnits[i]}) `;\n }\n\n // Compute opacity\n let opacity: false | number | string = false;\n if (segment.hasOpacity) {\n opacity = segment.opacityStart + segment.opacityDelta * easedProgress;\n } else if (element.style.opacity) {\n opacity = '';\n }\n\n // Compute transform origin\n let transformOrigin: false | string = false;\n if (segment.transformOrigin !== false) {\n transformOrigin = segment.transformOrigin;\n } else if (element.style.transformOrigin) {\n transformOrigin = '';\n }\n\n // Compute CSS custom properties\n const hasCustomProperties = segment.customPropertyNames.length > 0;\n\n scheduler.write(() => {\n if (opacity !== false) {\n // @ts-ignore\n element.style.opacity = opacity;\n }\n if (transformOrigin !== false) {\n element.style.transformOrigin = transformOrigin;\n }\n if (hasCustomProperties) {\n for (let i = 0; i < segment.customPropertyNames.length; i++) {\n element.style.setProperty(\n segment.customPropertyNames[i],\n (segment.customPropertyStarts[i] + segment.customPropertyDeltas[i] * easedProgress).toString(),\n );\n }\n }\n element.style.transform = transformValue;\n });\n });\n}\n\n/**\n * Animate an element.\n */\nfunction singleAnimate(\n element: HTMLElement,\n keyframes: Keyframe[],\n options: TweenOptions = {},\n): Animate {\n const keyframesCount = keyframes.length - 1;\n const normalizedKeyframes = keyframes.map(\n (keyframe, index): NormalizedKeyframe => ({\n ...keyframe,\n offset: keyframe.offset ?? index / keyframesCount,\n easing: normalizeEase(keyframe.easing),\n vars: Object.keys(keyframe).filter((key) => startsWith(key, '--')),\n }),\n );\n\n // Compile keyframe pairs into pre-computed segments (stage 1: partial evaluation)\n const segments: CompiledSegment[] = [];\n for (let i = 1; i < normalizedKeyframes.length; i++) {\n segments.push(compileSegment(normalizedKeyframes[i - 1], normalizedKeyframes[i]));\n }\n\n if (!running.has(element)) {\n running.set(element, new Map());\n }\n\n const key = `animate-${id}`;\n id += 1;\n\n /**\n * Set the progress value.\n */\n function callback(progress: number) {\n let segmentIndex = 0;\n while (\n segmentIndex < segments.length - 1 &&\n segments[segmentIndex].toOffset <= progress &&\n segments[segmentIndex].toOffset !== 1\n ) {\n segmentIndex += 1;\n }\n\n renderSegment(element, segments[segmentIndex], progress);\n }\n\n const controls = tween(callback, {\n ...options,\n onStart(progress) {\n if (isFunction(options.onStart)) {\n options.onStart(progress);\n }\n // Stop running instances\n const runningKeys = running.get(element);\n for (const [runningKey, runningPause] of runningKeys.entries()) {\n runningPause();\n runningKeys.delete(runningKey);\n }\n runningKeys.set(key, controls.pause);\n running.set(element, runningKeys);\n },\n });\n\n return controls;\n}\n\ntype Duration = number;\ntype Delay = number;\ntype DurationWithDelay = number;\n\n/**\n * Animate one or more elements.\n * @link https://js-toolkit.studiometa.dev/utils/css/animate.html\n*/\nexport function animate(\n elementOrElements: HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>,\n keyframes: Keyframe[],\n options: AnimateOptions = {},\n): Animate {\n if (elementOrElements instanceof HTMLElement) {\n return singleAnimate(elementOrElements, keyframes, {\n ...options,\n duration: isFunction(options.duration)\n ? options.duration(elementOrElements, 0)\n : options.duration,\n });\n }\n\n const stagger = options.stagger ?? 0;\n const staggerIsFunction = isFunction(stagger);\n const durationFn = isFunction(options.duration) ? options.duration : null;\n const progressFn = isFunction(options.onProgress) ? options.onProgress : null;\n const progresses: number[] = [];\n const timings: [Duration, Delay, DurationWithDelay][] = [];\n let duration = 0;\n let progressSum = 0;\n let elementCount = 0;\n\n const controls = eachElements(elementOrElements, (element, index) => {\n const delay = staggerIsFunction ? stagger(element, index) : stagger * index;\n const itemOptions = { ...options, delay } as TweenOptions;\n\n if (durationFn) {\n itemOptions.duration = durationFn(element, index);\n } else if (itemOptions.duration === undefined) {\n itemOptions.duration = 1;\n }\n\n timings[index] = [itemOptions.duration, delay, itemOptions.duration + delay];\n\n if (timings[index][2] > duration) {\n // eslint-disable-next-line prefer-destructuring\n duration = timings[index][2];\n }\n\n progresses[index] = 0;\n elementCount = index + 1;\n itemOptions.onProgress = (itemProgress) => {\n progressSum += itemProgress - progresses[index];\n progresses[index] = itemProgress;\n if (progressFn) {\n progressFn(progressSum / elementCount);\n }\n };\n\n return singleAnimate(element, keyframes, itemOptions);\n });\n\n function forAll(key: string) {\n for (const control of controls) {\n control[key]();\n }\n }\n\n function progress(newProgress?: number) {\n if (newProgress !== undefined) {\n const newTime = lerp(0, duration, newProgress);\n for (let i = 0; i < controls.length; i++) {\n const controlProgress = clamp01(\n map(newTime, timings[i][1], timings[i][2], 0, 1),\n );\n controls[i].progress(controlProgress);\n }\n }\n\n return progressSum / elementCount;\n }\n\n return {\n start: () => forAll('start'),\n pause: () => forAll('pause'),\n finish: () => forAll('finish'),\n play: () => forAll('play'),\n progress,\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["key"]
7
7
  }