@studiometa/js-toolkit 3.5.0 → 3.6.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Base/Base.d.ts +2 -2
- package/Base/Base.js.map +2 -2
- package/Base/managers/AbstractManager.d.ts +2 -2
- package/Base/types.d.ts +3 -3
- package/Base/utils.d.ts +1 -1
- package/Base/utils.js +1 -2
- package/Base/utils.js.map +2 -2
- package/README.md +10 -0
- package/decorators/withBreakpointManager.d.ts +1 -1
- package/decorators/withBreakpointManager.js.map +1 -1
- package/decorators/withBreakpointObserver.d.ts +1 -1
- package/decorators/withBreakpointObserver.js.map +1 -1
- package/decorators/withDrag.d.ts +1 -1
- package/decorators/withDrag.js.map +1 -1
- package/decorators/withExtraConfig.d.ts +1 -1
- package/decorators/withExtraConfig.js.map +1 -1
- package/decorators/withFreezedOptions.d.ts +1 -1
- package/decorators/withFreezedOptions.js.map +1 -1
- package/decorators/withGroup.js.map +2 -2
- package/decorators/withIntersectionObserver.d.ts +1 -1
- package/decorators/withIntersectionObserver.js.map +1 -1
- package/decorators/withMountOnMediaQuery.d.ts +1 -1
- package/decorators/withMountOnMediaQuery.js.map +1 -1
- package/decorators/withMountWhenInView.d.ts +1 -1
- package/decorators/withMountWhenInView.js.map +1 -1
- package/decorators/withMutation.d.ts +1 -1
- package/decorators/withMutation.js.map +1 -1
- package/decorators/withRelativePointer.d.ts +1 -1
- package/decorators/withRelativePointer.js.map +1 -1
- package/decorators/withResponsiveOptions.d.ts +1 -1
- package/decorators/withResponsiveOptions.js.map +1 -1
- package/decorators/withScrolledInView/withScrolledInView.d.ts +1 -1
- package/decorators/withScrolledInView/withScrolledInView.js.map +1 -1
- package/helpers/createApp.d.ts +1 -1
- package/helpers/createApp.js +6 -4
- package/helpers/createApp.js.map +2 -2
- package/helpers/getClosestParent.d.ts +1 -1
- package/helpers/getClosestParent.js.map +1 -1
- package/helpers/getDirectChildren.d.ts +2 -2
- package/helpers/getDirectChildren.js.map +1 -1
- package/helpers/getInstanceFromElement.d.ts +1 -1
- package/helpers/getInstanceFromElement.js.map +1 -1
- package/helpers/importOnInteraction.d.ts +1 -1
- package/helpers/importOnInteraction.js.map +1 -1
- package/helpers/importOnMediaQuery.d.ts +1 -1
- package/helpers/importOnMediaQuery.js.map +1 -1
- package/helpers/importWhenIdle.d.ts +1 -1
- package/helpers/importWhenIdle.js.map +1 -1
- package/helpers/importWhenPrefersMotion.d.ts +1 -1
- package/helpers/importWhenPrefersMotion.js.map +1 -1
- package/helpers/importWhenVisible.d.ts +1 -1
- package/helpers/importWhenVisible.js.map +1 -1
- package/helpers/index.d.ts +1 -0
- package/helpers/index.js +1 -0
- package/helpers/index.js.map +2 -2
- package/helpers/logTree.d.ts +17 -0
- package/helpers/logTree.js +59 -0
- package/helpers/logTree.js.map +7 -0
- package/helpers/queryComponent.js +9 -10
- package/helpers/queryComponent.js.map +2 -2
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/services/AbstractService.d.ts +1 -1
- package/services/AbstractService.js +1 -1
- package/services/AbstractService.js.map +2 -2
- package/services/DragService.d.ts +6 -6
- package/services/DragService.js.map +1 -1
- package/services/KeyService.d.ts +1 -1
- package/services/KeyService.js.map +1 -1
- package/services/LoadService.d.ts +1 -1
- package/services/LoadService.js.map +1 -1
- package/services/MutationService.d.ts +1 -1
- package/services/MutationService.js.map +1 -1
- package/services/PointerService.d.ts +1 -1
- package/services/PointerService.js.map +1 -1
- package/services/RafService.d.ts +2 -2
- package/services/RafService.js +13 -7
- package/services/RafService.js.map +2 -2
- package/services/ResizeService.d.ts +1 -1
- package/services/ResizeService.js.map +1 -1
- package/services/ScrollService.d.ts +22 -4
- package/services/ScrollService.js +55 -7
- package/services/ScrollService.js.map +2 -2
- package/utils/cache.d.ts +1 -1
- package/utils/cache.js.map +1 -1
- package/utils/collide/boundingRectToCircle.d.ts +3 -3
- package/utils/collide/boundingRectToCircle.js.map +1 -1
- package/utils/collide/collideCircleCircle.d.ts +1 -1
- package/utils/collide/collideCircleCircle.js.map +1 -1
- package/utils/collide/collideCircleRect.d.ts +1 -1
- package/utils/collide/collideCircleRect.js.map +1 -1
- package/utils/collide/collidePointCircle.d.ts +1 -1
- package/utils/collide/collidePointCircle.js.map +1 -1
- package/utils/collide/collidePointRect.d.ts +1 -1
- package/utils/collide/collidePointRect.js.map +1 -1
- package/utils/collide/collideRectRect.d.ts +1 -1
- package/utils/collide/collideRectRect.js.map +1 -1
- package/utils/css/animate.d.ts +1 -1
- package/utils/css/animate.js +162 -96
- package/utils/css/animate.js.map +2 -2
- package/utils/css/classes.d.ts +3 -3
- package/utils/css/classes.js.map +1 -1
- package/utils/css/getOffsetSizes.d.ts +1 -1
- package/utils/css/getOffsetSizes.js.map +1 -1
- package/utils/css/matrix.d.ts +1 -1
- package/utils/css/matrix.js.map +1 -1
- package/utils/css/styles.d.ts +2 -2
- package/utils/css/styles.js.map +1 -1
- package/utils/css/transform.d.ts +1 -1
- package/utils/css/transform.js +12 -13
- package/utils/css/transform.js.map +2 -2
- package/utils/css/transition.d.ts +1 -1
- package/utils/css/transition.js.map +1 -1
- package/utils/debounce.d.ts +1 -1
- package/utils/debounce.js.map +1 -1
- package/utils/history.d.ts +3 -3
- package/utils/history.js.map +1 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/index.js.map +2 -2
- package/utils/is.d.ts +10 -10
- package/utils/is.js.map +1 -1
- package/utils/loadElement.d.ts +5 -5
- package/utils/loadElement.js.map +1 -1
- package/utils/math/clamp.d.ts +1 -1
- package/utils/math/clamp.js.map +1 -1
- package/utils/math/clamp01.d.ts +1 -1
- package/utils/math/clamp01.js.map +1 -1
- package/utils/math/createEases.d.ts +2 -2
- package/utils/math/createEases.js.map +1 -1
- package/utils/math/createRange.d.ts +1 -1
- package/utils/math/createRange.js.map +1 -1
- package/utils/math/damp.d.ts +1 -1
- package/utils/math/damp.js.map +2 -2
- package/utils/math/inertiaFinalValue.d.ts +1 -1
- package/utils/math/inertiaFinalValue.js.map +1 -1
- package/utils/math/lerp.d.ts +1 -1
- package/utils/math/lerp.js.map +1 -1
- package/utils/math/map.d.ts +1 -1
- package/utils/math/map.js.map +1 -1
- package/utils/math/round.d.ts +1 -1
- package/utils/math/round.js.map +1 -1
- package/utils/math/smoothTo.d.ts +24 -6
- package/utils/math/wrap.d.ts +1 -1
- package/utils/math/wrap.js.map +1 -1
- package/utils/memo.d.ts +1 -1
- package/utils/memo.js.map +1 -1
- package/utils/memoize.d.ts +2 -2
- package/utils/memoize.js.map +1 -1
- package/utils/nextFrame.d.ts +1 -1
- package/utils/nextFrame.js.map +1 -1
- package/utils/nextMicrotask.d.ts +1 -1
- package/utils/nextMicrotask.js.map +1 -1
- package/utils/nextTick.d.ts +1 -1
- package/utils/nextTick.js.map +1 -1
- package/utils/object/getAllProperties.js +4 -2
- package/utils/object/getAllProperties.js.map +2 -2
- package/utils/random.d.ts +3 -3
- package/utils/random.js.map +1 -1
- package/utils/scheduler.d.ts +3 -3
- package/utils/scheduler.js.map +1 -1
- package/utils/scrollTo.d.ts +1 -1
- package/utils/scrollTo.js.map +1 -1
- package/utils/storage/createLocalStorageProvider.d.ts +2 -0
- package/utils/storage/createLocalStorageProvider.js +32 -0
- package/utils/storage/createLocalStorageProvider.js.map +7 -0
- package/utils/storage/createMemoryStorageProvider.d.ts +2 -0
- package/utils/storage/createMemoryStorageProvider.js +27 -0
- package/utils/storage/createMemoryStorageProvider.js.map +7 -0
- package/utils/storage/createNoopProvider.d.ts +2 -0
- package/utils/storage/createNoopProvider.js +23 -0
- package/utils/storage/createNoopProvider.js.map +7 -0
- package/utils/storage/createSessionStorageProvider.d.ts +2 -0
- package/utils/storage/createSessionStorageProvider.js +31 -0
- package/utils/storage/createSessionStorageProvider.js.map +7 -0
- package/utils/storage/createStorage.d.ts +2 -0
- package/utils/storage/createStorage.js +96 -0
- package/utils/storage/createStorage.js.map +7 -0
- package/utils/storage/createUrlSearchParamsInHashProvider.d.ts +2 -0
- package/utils/storage/createUrlSearchParamsInHashProvider.js +57 -0
- package/utils/storage/createUrlSearchParamsInHashProvider.js.map +7 -0
- package/utils/storage/createUrlSearchParamsProvider.d.ts +2 -0
- package/utils/storage/createUrlSearchParamsProvider.js +41 -0
- package/utils/storage/createUrlSearchParamsProvider.js.map +7 -0
- package/utils/storage/getBrowserContext.d.ts +1 -0
- package/utils/storage/getBrowserContext.js +17 -0
- package/utils/storage/getBrowserContext.js.map +7 -0
- package/utils/storage/getGlobalStorage.d.ts +1 -0
- package/utils/storage/getGlobalStorage.js +7 -0
- package/utils/storage/getGlobalStorage.js.map +7 -0
- package/utils/storage/getStorageKeys.d.ts +1 -0
- package/utils/storage/getStorageKeys.js +12 -0
- package/utils/storage/getStorageKeys.js.map +7 -0
- package/utils/storage/index.d.ts +8 -0
- package/utils/storage/index.js +62 -0
- package/utils/storage/index.js.map +7 -0
- package/utils/storage/providers.d.ts +11 -0
- package/utils/storage/providers.js +30 -0
- package/utils/storage/providers.js.map +7 -0
- package/utils/storage/serializers.d.ts +2 -0
- package/utils/storage/serializers.js +14 -0
- package/utils/storage/serializers.js.map +7 -0
- package/utils/storage/types.d.ts +33 -0
- package/utils/storage/types.js +1 -0
- package/utils/storage/types.js.map +7 -0
- package/utils/storage.d.ts +1 -0
- package/utils/storage.js +2 -0
- package/utils/storage.js.map +7 -0
- package/utils/string/changeCase.d.ts +6 -6
- package/utils/string/changeCase.js +1 -1
- package/utils/string/changeCase.js.map +2 -2
- package/utils/string/withLeadingCharacters.d.ts +1 -1
- package/utils/string/withLeadingCharacters.js.map +1 -1
- package/utils/string/withLeadingSlash.d.ts +1 -1
- package/utils/string/withLeadingSlash.js.map +1 -1
- package/utils/string/withTrailingCharacters.d.ts +1 -1
- package/utils/string/withTrailingCharacters.js.map +1 -1
- package/utils/string/withTrailingSlash.d.ts +1 -1
- package/utils/string/withTrailingSlash.js.map +1 -1
- package/utils/string/withoutLeadingCharacters.d.ts +1 -1
- package/utils/string/withoutLeadingCharacters.js.map +1 -1
- package/utils/string/withoutLeadingCharactersRecursive.d.ts +1 -1
- package/utils/string/withoutLeadingCharactersRecursive.js.map +1 -1
- package/utils/string/withoutLeadingSlash.d.ts +1 -1
- package/utils/string/withoutLeadingSlash.js.map +1 -1
- package/utils/string/withoutTrailingCharacters.d.ts +1 -1
- package/utils/string/withoutTrailingCharacters.js.map +1 -1
- package/utils/string/withoutTrailingCharactersRecursive.d.ts +1 -1
- package/utils/string/withoutTrailingCharactersRecursive.js.map +1 -1
- package/utils/string/withoutTrailingSlash.d.ts +1 -1
- package/utils/string/withoutTrailingSlash.js.map +1 -1
- package/utils/throttle.d.ts +1 -1
- package/utils/throttle.js.map +1 -1
- package/utils/trapFocus.d.ts +2 -2
- package/utils/trapFocus.js.map +1 -1
- package/utils/tween.js +5 -5
- package/utils/tween.js.map +2 -2
- package/tsconfig.build.tsbuildinfo +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/collide/boundingRectToCircle.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Convert clientRect to a formatted circle object\n *\n * @param {Partial<DOMRect>} domRect DOMRect of a square DOMElement\n * @param {boolean} force Force usage of non-square DOMElements\n * @return {Circle} Circle object that can be used in collides functions\n * @link https://js-toolkit.studiometa.dev/utils/collision/boundingRectToCircle.html\n*/\nexport function boundingRectToCircle({ x, y, width, height }, force = false) {\n if (width !== height && !force) {\n throw new Error('Initial DOMElement is not a square. Please use the force mode.');\n }\n return {\n x: x + width / 2,\n y: y + height / 2,\n radius: (width + height) / 4,\n };\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Convert clientRect to a formatted circle object\n *\n * @param {Partial<DOMRect>} domRect DOMRect of a square DOMElement\n * @param {boolean} force Force usage of non-square DOMElements\n * @return {Circle} Circle object that can be used in collides functions\n * @link https://js-toolkit.studiometa.dev/utils/collision/boundingRectToCircle.html\n */\nexport function boundingRectToCircle({ x, y, width, height }, force = false) {\n if (width !== height && !force) {\n throw new Error('Initial DOMElement is not a square. Please use the force mode.');\n }\n return {\n x: x + width / 2,\n y: y + height / 2,\n radius: (width + height) / 4,\n };\n}\n"],
|
|
5
5
|
"mappings": "AAeO,SAAS,qBAAqB,EAAE,GAAG,GAAG,OAAO,OAAO,GAAG,QAAQ,OAAO;AAC3E,MAAI,UAAU,UAAU,CAAC,OAAO;AAC9B,UAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AACA,SAAO;AAAA,IACL,GAAG,IAAI,QAAQ;AAAA,IACf,GAAG,IAAI,SAAS;AAAA,IAChB,SAAS,QAAQ,UAAU;AAAA,EAC7B;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
* @param {Circle} circle2 Circle 2
|
|
13
13
|
* @return {boolean} Are the sides of one circle touching the other ?
|
|
14
14
|
* @link https://js-toolkit.studiometa.dev/utils/collision/collideCircleCircle.html
|
|
15
|
-
*/
|
|
15
|
+
*/
|
|
16
16
|
export declare function collideCircleCircle(circle1: any, circle2: any): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/collide/collideCircleCircle.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Test if a circle collides with another.\n * Inspired by http://www.jeffreythompson.org/collision-detection/circle-circle.php\n *\n * @param {Circle} circle1 Circle 1\n * @param {Circle} circle2 Circle 2\n * @return {boolean} Are the sides of one circle touching the other ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collideCircleCircle.html\n*/\nexport function collideCircleCircle(circle1, circle2) {\n // get distance between the circle's centers\n // use the Pythagorean Theorem to compute the distance\n const distX = circle1.x - circle2.x;\n const distY = circle1.y - circle2.y;\n const distance = Math.sqrt(distX * distX + distY * distY);\n\n // if the distance is less than the sum of the circle's\n // radii, the circles are touching!\n if (distance <= circle1.radius + circle2.radius) {\n return true;\n }\n return false;\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Test if a circle collides with another.\n * Inspired by http://www.jeffreythompson.org/collision-detection/circle-circle.php\n *\n * @param {Circle} circle1 Circle 1\n * @param {Circle} circle2 Circle 2\n * @return {boolean} Are the sides of one circle touching the other ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collideCircleCircle.html\n */\nexport function collideCircleCircle(circle1, circle2) {\n // get distance between the circle's centers\n // use the Pythagorean Theorem to compute the distance\n const distX = circle1.x - circle2.x;\n const distY = circle1.y - circle2.y;\n const distance = Math.sqrt(distX * distX + distY * distY);\n\n // if the distance is less than the sum of the circle's\n // radii, the circles are touching!\n if (distance <= circle1.radius + circle2.radius) {\n return true;\n }\n return false;\n}\n"],
|
|
5
5
|
"mappings": "AAgBO,SAAS,oBAAoB,SAAS,SAAS;AAGpD,QAAM,QAAQ,QAAQ,IAAI,QAAQ;AAClC,QAAM,QAAQ,QAAQ,IAAI,QAAQ;AAClC,QAAM,WAAW,KAAK,KAAK,QAAQ,QAAQ,QAAQ,KAAK;AAIxD,MAAI,YAAY,QAAQ,SAAS,QAAQ,QAAQ;AAC/C,WAAO;AAAA,EACT;AACA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -19,5 +19,5 @@
|
|
|
19
19
|
* @param {Rect} rect Rectangle
|
|
20
20
|
* @return {boolean} Are the sides of the circle touching the rectangle ?
|
|
21
21
|
* @link https://js-toolkit.studiometa.dev/utils/collision/collideCircleRect.html
|
|
22
|
-
*/
|
|
22
|
+
*/
|
|
23
23
|
export declare function collideCircleRect(circle: any, rect: any): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/collide/collideCircleRect.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @typedef {Object} Rect\n * @property {number} x Rectangle's x position\n * @property {number} y Rectangle's y position\n * @property {number} width Rectangle's width\n * @property {number} height Rectangle's height\n */\n\n/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Test if a circle collides with a rectangle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/circle-rect.php\n *\n * @param {Circle} circle Circle\n * @param {Rect} rect Rectangle\n * @return {boolean} Are the sides of the circle touching the rectangle ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collideCircleRect.html\n*/\nexport function collideCircleRect(circle, rect) {\n // temporary variables to set edges for testing\n let testX = circle.x;\n let testY = circle.y;\n\n // which edge is closest?\n if (circle.x < rect.x) {\n testX = rect.x; // test left edge\n } else if (circle.x > rect.x + rect.width) {\n testX = rect.x + rect.width; // right edge\n }\n\n if (circle.y < rect.y) {\n testY = rect.y; // top edge\n } else if (circle.y > rect.y + rect.height) {\n testY = rect.y + rect.height; // bottom edge\n }\n\n // get distance from closest edges\n const distX = circle.x - testX;\n const distY = circle.y - testY;\n const distance = Math.sqrt(distX * distX + distY * distY);\n\n // if the distance is less than the radius, collision!\n if (distance <= circle.radius) {\n return true;\n }\n return false;\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * @typedef {Object} Rect\n * @property {number} x Rectangle's x position\n * @property {number} y Rectangle's y position\n * @property {number} width Rectangle's width\n * @property {number} height Rectangle's height\n */\n\n/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Test if a circle collides with a rectangle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/circle-rect.php\n *\n * @param {Circle} circle Circle\n * @param {Rect} rect Rectangle\n * @return {boolean} Are the sides of the circle touching the rectangle ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collideCircleRect.html\n */\nexport function collideCircleRect(circle, rect) {\n // temporary variables to set edges for testing\n let testX = circle.x;\n let testY = circle.y;\n\n // which edge is closest?\n if (circle.x < rect.x) {\n testX = rect.x; // test left edge\n } else if (circle.x > rect.x + rect.width) {\n testX = rect.x + rect.width; // right edge\n }\n\n if (circle.y < rect.y) {\n testY = rect.y; // top edge\n } else if (circle.y > rect.y + rect.height) {\n testY = rect.y + rect.height; // bottom edge\n }\n\n // get distance from closest edges\n const distX = circle.x - testX;\n const distY = circle.y - testY;\n const distance = Math.sqrt(distX * distX + distY * distY);\n\n // if the distance is less than the radius, collision!\n if (distance <= circle.radius) {\n return true;\n }\n return false;\n}\n"],
|
|
5
5
|
"mappings": "AAwBO,SAAS,kBAAkB,QAAQ,MAAM;AAE9C,MAAI,QAAQ,OAAO;AACnB,MAAI,QAAQ,OAAO;AAGnB,MAAI,OAAO,IAAI,KAAK,GAAG;AACrB,YAAQ,KAAK;AAAA,EACf,WAAW,OAAO,IAAI,KAAK,IAAI,KAAK,OAAO;AACzC,YAAQ,KAAK,IAAI,KAAK;AAAA,EACxB;AAEA,MAAI,OAAO,IAAI,KAAK,GAAG;AACrB,YAAQ,KAAK;AAAA,EACf,WAAW,OAAO,IAAI,KAAK,IAAI,KAAK,QAAQ;AAC1C,YAAQ,KAAK,IAAI,KAAK;AAAA,EACxB;AAGA,QAAM,QAAQ,OAAO,IAAI;AACzB,QAAM,QAAQ,OAAO,IAAI;AACzB,QAAM,WAAW,KAAK,KAAK,QAAQ,QAAQ,QAAQ,KAAK;AAGxD,MAAI,YAAY,OAAO,QAAQ;AAC7B,WAAO;AAAA,EACT;AACA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
* @param {Circle} circle Circle
|
|
18
18
|
* @return {boolean} Is the point inside the circle's bounds ?
|
|
19
19
|
* @link https://js-toolkit.studiometa.dev/utils/collision/collidePointCircle.html
|
|
20
|
-
*/
|
|
20
|
+
*/
|
|
21
21
|
export declare function collidePointCircle(point: any, circle: any): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/collide/collidePointCircle.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @typedef {Object} Point\n * @property {number} x Point's x position\n * @property {number} y Point's y position\n */\n\n/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Test if a point is inside a circle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/point-circle.php\n *\n * @param {Point} point Point\n * @param {Circle} circle Circle\n * @return {boolean} Is the point inside the circle's bounds ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collidePointCircle.html\n*/\nexport function collidePointCircle(point, circle) {\n // get distance between the point and circle's center\n // using the Pythagorean Theorem\n const distX = point.x - circle.x;\n const distY = point.y - circle.y;\n const distance = Math.sqrt(distX * distX + distY * distY);\n\n // if the distance is less than the circle's\n // radius the point is inside!\n return distance <= circle.radius;\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * @typedef {Object} Point\n * @property {number} x Point's x position\n * @property {number} y Point's y position\n */\n\n/**\n * @typedef {Object} Circle\n * @property {number} x Circle's x position\n * @property {number} y Circle's y position\n * @property {number} radius Circle's radius\n */\n\n/**\n * Test if a point is inside a circle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/point-circle.php\n *\n * @param {Point} point Point\n * @param {Circle} circle Circle\n * @return {boolean} Is the point inside the circle's bounds ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collidePointCircle.html\n */\nexport function collidePointCircle(point, circle) {\n // get distance between the point and circle's center\n // using the Pythagorean Theorem\n const distX = point.x - circle.x;\n const distY = point.y - circle.y;\n const distance = Math.sqrt(distX * distX + distY * distY);\n\n // if the distance is less than the circle's\n // radius the point is inside!\n return distance <= circle.radius;\n}\n"],
|
|
5
5
|
"mappings": "AAsBO,SAAS,mBAAmB,OAAO,QAAQ;AAGhD,QAAM,QAAQ,MAAM,IAAI,OAAO;AAC/B,QAAM,QAAQ,MAAM,IAAI,OAAO;AAC/B,QAAM,WAAW,KAAK,KAAK,QAAQ,QAAQ,QAAQ,KAAK;AAIxD,SAAO,YAAY,OAAO;AAC5B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -18,5 +18,5 @@
|
|
|
18
18
|
* @param {Rect} rect Rectangle
|
|
19
19
|
* @return {boolean} Is the point inside the rectangle's bounds ?
|
|
20
20
|
* @link https://js-toolkit.studiometa.dev/utils/collision/collidePointRect.html
|
|
21
|
-
*/
|
|
21
|
+
*/
|
|
22
22
|
export declare function collidePointRect(point: any, rect: any): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/collide/collidePointRect.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @typedef {Object} Point\n * @property {number} x Point's x position\n * @property {number} y Point's y position\n */\n\n/**\n * @typedef {Object} Rect\n * @property {number} x Rectangle's x position\n * @property {number} y Rectangle's y position\n * @property {number} width Rectangle's width\n * @property {number} height Rectangle's height\n */\n\n/**\n * Test if a point collides with a rectangle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/point-rect.php\n *\n * @param {Point} point Point\n * @param {Rect} rect Rectangle\n * @return {boolean} Is the point inside the rectangle's bounds ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collidePointRect.html\n*/\nexport function collidePointRect(point, rect) {\n return (\n point.x >= rect.x && // right of the left edge AND\n point.x <= rect.x + rect.width && // left of the right edge AND\n point.y >= rect.y && // below the top AND\n point.y <= rect.y + rect.height // above the bottom\n );\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * @typedef {Object} Point\n * @property {number} x Point's x position\n * @property {number} y Point's y position\n */\n\n/**\n * @typedef {Object} Rect\n * @property {number} x Rectangle's x position\n * @property {number} y Rectangle's y position\n * @property {number} width Rectangle's width\n * @property {number} height Rectangle's height\n */\n\n/**\n * Test if a point collides with a rectangle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/point-rect.php\n *\n * @param {Point} point Point\n * @param {Rect} rect Rectangle\n * @return {boolean} Is the point inside the rectangle's bounds ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collidePointRect.html\n */\nexport function collidePointRect(point, rect) {\n return (\n point.x >= rect.x && // right of the left edge AND\n point.x <= rect.x + rect.width && // left of the right edge AND\n point.y >= rect.y && // below the top AND\n point.y <= rect.y + rect.height // above the bottom\n );\n}\n"],
|
|
5
5
|
"mappings": "AAuBO,SAAS,iBAAiB,OAAO,MAAM;AAC5C,SACE,MAAM,KAAK,KAAK;AAAA,EAChB,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,EACzB,MAAM,KAAK,KAAK;AAAA,EAChB,MAAM,KAAK,KAAK,IAAI,KAAK;AAE7B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
* @param {Rect} rect2 Rectangle 2
|
|
14
14
|
* @return {boolean} Are the sides of one rectangle touching the other ?
|
|
15
15
|
* @link https://js-toolkit.studiometa.dev/utils/collision/collideRectRect.html
|
|
16
|
-
*/
|
|
16
|
+
*/
|
|
17
17
|
export declare function collideRectRect(rect1: any, rect2: any): boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/collide/collideRectRect.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @typedef {Object} Rect\n * @property {number} x Rectangle's x position\n * @property {number} y Rectangle's y position\n * @property {number} width Rectangle's width\n * @property {number} height Rectangle's height\n */\n\n/**\n * Test if a rectangle collides with another rectangle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/rect-rect.php\n *\n * @param {Rect} rect1 Rectangle 1\n * @param {Rect} rect2 Rectangle 2\n * @return {boolean} Are the sides of one rectangle touching the other ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collideRectRect.html\n*/\nexport function collideRectRect(rect1, rect2) {\n return (\n rect1.x + rect1.width >= rect2.x && // rect1 right edge past rect2 left AND\n rect1.x <= rect2.x + rect2.width && // rect1 left edge past rect2 right AND\n rect1.y + rect1.height >= rect2.y && // rect1 top edge past rect2 bottom AND\n rect1.y <= rect2.y + rect2.height // rect1 bottom edge past rect2 top\n );\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * @typedef {Object} Rect\n * @property {number} x Rectangle's x position\n * @property {number} y Rectangle's y position\n * @property {number} width Rectangle's width\n * @property {number} height Rectangle's height\n */\n\n/**\n * Test if a rectangle collides with another rectangle.\n * Inspired by http://www.jeffreythompson.org/collision-detection/rect-rect.php\n *\n * @param {Rect} rect1 Rectangle 1\n * @param {Rect} rect2 Rectangle 2\n * @return {boolean} Are the sides of one rectangle touching the other ?\n * @link https://js-toolkit.studiometa.dev/utils/collision/collideRectRect.html\n */\nexport function collideRectRect(rect1, rect2) {\n return (\n rect1.x + rect1.width >= rect2.x && // rect1 right edge past rect2 left AND\n rect1.x <= rect2.x + rect2.width && // rect1 left edge past rect2 right AND\n rect1.y + rect1.height >= rect2.y && // rect1 top edge past rect2 bottom AND\n rect1.y <= rect2.y + rect2.height // rect1 bottom edge past rect2 top\n );\n}\n"],
|
|
5
5
|
"mappings": "AAiBO,SAAS,gBAAgB,OAAO,OAAO;AAC5C,SACE,MAAM,IAAI,MAAM,SAAS,MAAM;AAAA,EAC/B,MAAM,KAAK,MAAM,IAAI,MAAM;AAAA,EAC3B,MAAM,IAAI,MAAM,UAAU,MAAM;AAAA,EAChC,MAAM,KAAK,MAAM,IAAI,MAAM;AAE/B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/utils/css/animate.d.ts
CHANGED
|
@@ -41,6 +41,6 @@ export type Animate = Tween;
|
|
|
41
41
|
/**
|
|
42
42
|
* Animate one or more elements.
|
|
43
43
|
* @link https://js-toolkit.studiometa.dev/utils/css/animate.html
|
|
44
|
-
*/
|
|
44
|
+
*/
|
|
45
45
|
export declare function animate(elementOrElements: HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>, keyframes: Keyframe[], options?: AnimateOptions): Animate;
|
|
46
46
|
export {};
|
package/utils/css/animate.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { clamp01, lerp, map
|
|
2
|
-
import {
|
|
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,146 @@ import { startsWith } from "../string/index.js";
|
|
|
8
7
|
let id = 0;
|
|
9
8
|
const running = /* @__PURE__ */ new WeakMap();
|
|
10
9
|
const CSSUnitConverter = {
|
|
11
|
-
"%": (value,
|
|
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
|
|
18
|
-
if (
|
|
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],
|
|
23
|
+
return CSSUnitConverter[val[1]](val[0], elementSize);
|
|
25
24
|
}
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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(map(progress, segment.fromOffset, segment.toOffset, 0, 1));
|
|
58
115
|
scheduler.read(() => {
|
|
116
|
+
for (let i = 0; i < segment.dynamicTranslates.length; i++) {
|
|
117
|
+
const dynamic = segment.dynamicTranslates[i];
|
|
118
|
+
const elementSize = element[dynamic.sizeRef];
|
|
119
|
+
const startValue = resolveUnitValue(dynamic.from, elementSize);
|
|
120
|
+
segment.transformStarts[dynamic.index] = startValue;
|
|
121
|
+
segment.transformDeltas[dynamic.index] = resolveUnitValue(dynamic.to, elementSize) - startValue;
|
|
122
|
+
}
|
|
123
|
+
let transformValue = "";
|
|
124
|
+
if (segment.hasTranslate) {
|
|
125
|
+
const xIndex = segment.translateAxisIndices[0];
|
|
126
|
+
const yIndex = segment.translateAxisIndices[1];
|
|
127
|
+
const zIndex = segment.translateAxisIndices[2];
|
|
128
|
+
const x = segment.transformStarts[xIndex] + segment.transformDeltas[xIndex] * easedProgress;
|
|
129
|
+
const y = segment.transformStarts[yIndex] + segment.transformDeltas[yIndex] * easedProgress;
|
|
130
|
+
const z = segment.transformStarts[zIndex] + segment.transformDeltas[zIndex] * easedProgress;
|
|
131
|
+
transformValue += `translate3d(${x}px, ${y}px, ${z}px) `;
|
|
132
|
+
}
|
|
133
|
+
for (let i = segment.simpleTransformStart; i < segment.transformStarts.length; i++) {
|
|
134
|
+
const value = segment.transformStarts[i] + segment.transformDeltas[i] * easedProgress;
|
|
135
|
+
transformValue += `${segment.transformCssFunctions[i]}(${value}${segment.transformUnits[i]}) `;
|
|
136
|
+
}
|
|
59
137
|
let opacity = false;
|
|
60
|
-
if (
|
|
61
|
-
opacity =
|
|
138
|
+
if (segment.hasOpacity) {
|
|
139
|
+
opacity = segment.opacityStart + segment.opacityDelta * easedProgress;
|
|
62
140
|
} else if (element.style.opacity) {
|
|
63
141
|
opacity = "";
|
|
64
142
|
}
|
|
65
143
|
let transformOrigin = false;
|
|
66
|
-
if (
|
|
67
|
-
transformOrigin =
|
|
144
|
+
if (segment.transformOrigin !== false) {
|
|
145
|
+
transformOrigin = segment.transformOrigin;
|
|
68
146
|
} else if (element.style.transformOrigin) {
|
|
69
147
|
transformOrigin = "";
|
|
70
148
|
}
|
|
71
|
-
|
|
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
|
-
}
|
|
149
|
+
const hasCustomProperties = segment.customPropertyNames.length > 0;
|
|
87
150
|
scheduler.write(() => {
|
|
88
151
|
if (opacity !== false) {
|
|
89
152
|
element.style.opacity = opacity;
|
|
@@ -91,12 +154,15 @@ function render(element, from, to, progress) {
|
|
|
91
154
|
if (transformOrigin !== false) {
|
|
92
155
|
element.style.transformOrigin = transformOrigin;
|
|
93
156
|
}
|
|
94
|
-
if (
|
|
95
|
-
for (
|
|
96
|
-
element.style.setProperty(
|
|
157
|
+
if (hasCustomProperties) {
|
|
158
|
+
for (let i = 0; i < segment.customPropertyNames.length; i++) {
|
|
159
|
+
element.style.setProperty(
|
|
160
|
+
segment.customPropertyNames[i],
|
|
161
|
+
(segment.customPropertyStarts[i] + segment.customPropertyDeltas[i] * easedProgress).toString()
|
|
162
|
+
);
|
|
97
163
|
}
|
|
98
164
|
}
|
|
99
|
-
transform
|
|
165
|
+
element.style.transform = transformValue;
|
|
100
166
|
});
|
|
101
167
|
});
|
|
102
168
|
}
|
|
@@ -110,17 +176,21 @@ function singleAnimate(element, keyframes, options = {}) {
|
|
|
110
176
|
vars: Object.keys(keyframe).filter((key2) => startsWith(key2, "--"))
|
|
111
177
|
})
|
|
112
178
|
);
|
|
179
|
+
const segments = [];
|
|
180
|
+
for (let i = 1; i < normalizedKeyframes.length; i++) {
|
|
181
|
+
segments.push(compileSegment(normalizedKeyframes[i - 1], normalizedKeyframes[i]));
|
|
182
|
+
}
|
|
113
183
|
if (!running.has(element)) {
|
|
114
184
|
running.set(element, /* @__PURE__ */ new Map());
|
|
115
185
|
}
|
|
116
186
|
const key = `animate-${id}`;
|
|
117
187
|
id += 1;
|
|
118
188
|
function callback(progress) {
|
|
119
|
-
let
|
|
120
|
-
while (
|
|
121
|
-
|
|
189
|
+
let segmentIndex = 0;
|
|
190
|
+
while (segmentIndex < segments.length - 1 && segments[segmentIndex].toOffset <= progress && segments[segmentIndex].toOffset !== 1) {
|
|
191
|
+
segmentIndex += 1;
|
|
122
192
|
}
|
|
123
|
-
|
|
193
|
+
renderSegment(element, segments[segmentIndex], progress);
|
|
124
194
|
}
|
|
125
195
|
const controls = tween(callback, {
|
|
126
196
|
...options,
|
|
@@ -153,56 +223,52 @@ function animate(elementOrElements, keyframes, options = {}) {
|
|
|
153
223
|
const progresses = [];
|
|
154
224
|
const timings = [];
|
|
155
225
|
let duration = 0;
|
|
156
|
-
let
|
|
226
|
+
let progressSum = 0;
|
|
227
|
+
let elementCount = 0;
|
|
157
228
|
const controls = eachElements(elementOrElements, (element, index) => {
|
|
158
229
|
const delay = staggerIsFunction ? stagger(element, index) : stagger * index;
|
|
159
230
|
const itemOptions = { ...options, delay };
|
|
160
231
|
if (durationFn) {
|
|
161
232
|
itemOptions.duration = durationFn(element, index);
|
|
162
|
-
} else if (
|
|
233
|
+
} else if (itemOptions.duration === void 0) {
|
|
163
234
|
itemOptions.duration = 1;
|
|
164
235
|
}
|
|
165
236
|
timings[index] = [itemOptions.duration, delay, itemOptions.duration + delay];
|
|
166
|
-
if (timings[index][2] >
|
|
237
|
+
if (timings[index][2] > duration) {
|
|
167
238
|
duration = timings[index][2];
|
|
168
239
|
}
|
|
169
|
-
previousTimings = timings[index];
|
|
170
240
|
progresses[index] = 0;
|
|
241
|
+
elementCount = index + 1;
|
|
171
242
|
itemOptions.onProgress = (itemProgress) => {
|
|
243
|
+
progressSum += itemProgress - progresses[index];
|
|
172
244
|
progresses[index] = itemProgress;
|
|
173
245
|
if (progressFn) {
|
|
174
|
-
progressFn(
|
|
246
|
+
progressFn(progressSum / elementCount);
|
|
175
247
|
}
|
|
176
248
|
};
|
|
177
249
|
return singleAnimate(element, keyframes, itemOptions);
|
|
178
250
|
});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
control.progress(controlProgress);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return mean(progresses);
|
|
194
|
-
}
|
|
195
|
-
for (const control of controls) {
|
|
196
|
-
control[key].call(null, arguments);
|
|
251
|
+
function forAll(key) {
|
|
252
|
+
for (const control of controls) {
|
|
253
|
+
control[key]();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function progress(newProgress) {
|
|
257
|
+
if (newProgress !== void 0) {
|
|
258
|
+
const newTime = lerp(0, duration, newProgress);
|
|
259
|
+
for (let i = 0; i < controls.length; i++) {
|
|
260
|
+
const controlProgress = clamp01(map(newTime, timings[i][1], timings[i][2], 0, 1));
|
|
261
|
+
controls[i].progress(controlProgress);
|
|
197
262
|
}
|
|
198
263
|
}
|
|
199
|
-
|
|
264
|
+
return progressSum / elementCount;
|
|
265
|
+
}
|
|
200
266
|
return {
|
|
201
|
-
start:
|
|
202
|
-
pause:
|
|
203
|
-
finish:
|
|
204
|
-
play:
|
|
205
|
-
progress
|
|
267
|
+
start: () => forAll("start"),
|
|
268
|
+
pause: () => forAll("pause"),
|
|
269
|
+
finish: () => forAll("finish"),
|
|
270
|
+
play: () => forAll("play"),
|
|
271
|
+
progress
|
|
206
272
|
};
|
|
207
273
|
}
|
|
208
274
|
export {
|
package/utils/css/animate.js.map
CHANGED
|
@@ -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,
|
|
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 * 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<readonly [string, string, string, number]> = [\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<readonly [string, number, string]> = [\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(from: NormalizedKeyframe, to: NormalizedKeyframe): 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(element: HTMLElement, segment: CompiledSegment, progress: number) {\n const easedProgress = segment.easing(map(progress, segment.fromOffset, segment.toOffset, 0, 1));\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] =\n 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 (\n segment.customPropertyStarts[i] +\n segment.customPropertyDeltas[i] * easedProgress\n ).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(map(newTime, timings[i][1], timings[i][2], 0, 1));\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
|
}
|
package/utils/css/classes.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Add class names to an element.
|
|
3
3
|
* @link https://js-toolkit.studiometa.dev/utils/css/addClass.html
|
|
4
|
-
*/
|
|
4
|
+
*/
|
|
5
5
|
export declare function add(element: Element | Element[] | NodeListOf<Element>, classNames: string | string[]): void;
|
|
6
6
|
/**
|
|
7
7
|
* Remove class names from an element.
|
|
8
8
|
* @link https://js-toolkit.studiometa.dev/utils/css/removeClass.html
|
|
9
|
-
*/
|
|
9
|
+
*/
|
|
10
10
|
export declare function remove(element: Element | Element[] | NodeListOf<Element>, classNames: string | string[]): void;
|
|
11
11
|
/**
|
|
12
12
|
* Toggle class names from an element.
|
|
13
13
|
* @link https://js-toolkit.studiometa.dev/utils/css/toggleClass.html
|
|
14
|
-
*/
|
|
14
|
+
*/
|
|
15
15
|
export declare function toggle(element: Element | Element[] | NodeListOf<Element>, classNames: string | string[], force?: boolean): void;
|