@studiometa/js-toolkit 3.4.3 → 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.
- package/Base/Base.d.ts +21 -1
- package/Base/Base.js +47 -5
- package/Base/Base.js.map +2 -2
- package/Base/managers/AbstractManager.d.ts +2 -2
- package/Base/managers/EventsManager.js +1 -1
- package/Base/managers/EventsManager.js.map +2 -2
- package/Base/utils.d.ts +1 -1
- package/Base/utils.js +1 -2
- package/Base/utils.js.map +2 -2
- package/decorators/withBreakpointManager.js +1 -1
- package/decorators/withBreakpointManager.js.map +2 -2
- package/helpers/createApp.js +8 -17
- package/helpers/createApp.js.map +2 -2
- package/helpers/defineFeatures.d.ts +7 -0
- package/helpers/defineFeatures.js +21 -0
- package/helpers/defineFeatures.js.map +7 -0
- package/helpers/getDirectChildren.js +4 -3
- package/helpers/getDirectChildren.js.map +2 -2
- package/helpers/index.d.ts +3 -0
- package/helpers/index.js +12 -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.d.ts +28 -0
- package/helpers/queryComponent.js +66 -0
- package/helpers/queryComponent.js.map +7 -0
- 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 +5 -5
- package/services/RafService.d.ts +1 -1
- package/services/RafService.js +13 -7
- package/services/RafService.js.map +2 -2
- package/services/ScrollService.d.ts +21 -3
- package/services/ScrollService.js +55 -7
- package/services/ScrollService.js.map +2 -2
- package/utils/collide/boundingRectToCircle.d.ts +2 -2
- package/utils/css/animate.js +166 -96
- package/utils/css/animate.js.map +2 -2
- package/utils/css/transform.js +12 -13
- package/utils/css/transform.js.map +2 -2
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/index.js.map +2 -2
- package/utils/math/smoothTo.d.ts +24 -6
- package/utils/memoize.d.ts +1 -1
- package/utils/object/getAllProperties.js +4 -2
- package/utils/object/getAllProperties.js.map +2 -2
- package/utils/scheduler.d.ts +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 +100 -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.js +1 -1
- package/utils/string/changeCase.js.map +2 -2
- 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/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 =
|
|
5
|
-
"mappings": "AACA,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AACzB,SAAS,qCAAqC;AAC9C,SAAS,gBAAgB;AA6BlB,MAAM,sBAAsB,gBAAoC;AAAA,EACrE,OAAO,SAAwB,
|
|
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;
|
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,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,
|
|
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(
|
|
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 (
|
|
61
|
-
opacity =
|
|
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 (
|
|
67
|
-
transformOrigin =
|
|
146
|
+
if (segment.transformOrigin !== false) {
|
|
147
|
+
transformOrigin = segment.transformOrigin;
|
|
68
148
|
} else if (element.style.transformOrigin) {
|
|
69
149
|
transformOrigin = "";
|
|
70
150
|
}
|
|
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
|
-
}
|
|
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 (
|
|
95
|
-
for (
|
|
96
|
-
element.style.setProperty(
|
|
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
|
|
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
|
|
120
|
-
while (
|
|
121
|
-
|
|
191
|
+
let segmentIndex = 0;
|
|
192
|
+
while (segmentIndex < segments.length - 1 && segments[segmentIndex].toOffset <= progress && segments[segmentIndex].toOffset !== 1) {
|
|
193
|
+
segmentIndex += 1;
|
|
122
194
|
}
|
|
123
|
-
|
|
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
|
|
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 (
|
|
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] >
|
|
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(
|
|
248
|
+
progressFn(progressSum / elementCount);
|
|
175
249
|
}
|
|
176
250
|
};
|
|
177
251
|
return singleAnimate(element, keyframes, itemOptions);
|
|
178
252
|
});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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:
|
|
202
|
-
pause:
|
|
203
|
-
finish:
|
|
204
|
-
play:
|
|
205
|
-
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 {
|
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/**\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
|
}
|
package/utils/css/transform.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isDefined } from "../is.js";
|
|
2
1
|
import { eachElements } from "./utils.js";
|
|
3
2
|
const TRANSFORM_PROPS = [
|
|
4
3
|
"x",
|
|
@@ -19,42 +18,42 @@ const TRANSFORM_PROPS = [
|
|
|
19
18
|
function transform(elementOrElements, props) {
|
|
20
19
|
if (!elementOrElements) return;
|
|
21
20
|
let value = "";
|
|
22
|
-
if (
|
|
21
|
+
if (props.x !== void 0 || props.y !== void 0 || props.z !== void 0) {
|
|
23
22
|
value += `translate3d(${props.x ?? 0}px, ${props.y ?? 0}px, ${props.z ?? 0}px) `;
|
|
24
23
|
}
|
|
25
|
-
if (
|
|
24
|
+
if (props.rotate !== void 0) {
|
|
26
25
|
value += `rotate(${props.rotate}deg) `;
|
|
27
26
|
} else {
|
|
28
|
-
if (
|
|
27
|
+
if (props.rotateX !== void 0) {
|
|
29
28
|
value += `rotateX(${props.rotateX}deg) `;
|
|
30
29
|
}
|
|
31
|
-
if (
|
|
30
|
+
if (props.rotateY !== void 0) {
|
|
32
31
|
value += `rotateY(${props.rotateY}deg) `;
|
|
33
32
|
}
|
|
34
|
-
if (
|
|
33
|
+
if (props.rotateZ !== void 0) {
|
|
35
34
|
value += `rotateZ(${props.rotateZ}deg) `;
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
|
-
if (
|
|
37
|
+
if (props.scale !== void 0) {
|
|
39
38
|
value += `scale(${props.scale}) `;
|
|
40
39
|
} else {
|
|
41
|
-
if (
|
|
40
|
+
if (props.scaleX !== void 0) {
|
|
42
41
|
value += `scaleX(${props.scaleX}) `;
|
|
43
42
|
}
|
|
44
|
-
if (
|
|
43
|
+
if (props.scaleY !== void 0) {
|
|
45
44
|
value += `scaleY(${props.scaleY}) `;
|
|
46
45
|
}
|
|
47
|
-
if (
|
|
46
|
+
if (props.scaleZ !== void 0) {
|
|
48
47
|
value += `scaleZ(${props.scaleZ}) `;
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
|
-
if (
|
|
50
|
+
if (props.skew !== void 0) {
|
|
52
51
|
value += `skew(${props.skew}deg) `;
|
|
53
52
|
} else {
|
|
54
|
-
if (
|
|
53
|
+
if (props.skewX !== void 0) {
|
|
55
54
|
value += `skewX(${props.skewX}deg) `;
|
|
56
55
|
}
|
|
57
|
-
if (
|
|
56
|
+
if (props.skewY !== void 0) {
|
|
58
57
|
value += `skewY(${props.skewY}deg) `;
|
|
59
58
|
}
|
|
60
59
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/js-toolkit/utils/css/transform.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["// eslint-disable-next-line import/extensions\nimport { eachElements } from './utils.js';\n\nexport type TransformProps = Partial<{\n x: number;\n y: number;\n z: number;\n rotate: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n scale: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n skew: number;\n skewX: number;\n skewY: number;\n}>;\n\nexport const TRANSFORM_PROPS = [\n 'x',\n 'y',\n 'z',\n 'rotate',\n 'rotateX',\n 'rotateY',\n 'rotateZ',\n 'scale',\n 'scaleX',\n 'scaleY',\n 'scaleZ',\n 'skew',\n 'skewX',\n 'skewY',\n];\n\n/**\n * Generate a CSS transform.\n * @link https://js-toolkit.studiometa.dev/utils/css/transform.html\n*/\nexport function transform(\n elementOrElements: HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>,\n props: TransformProps,\n): string {\n if (!elementOrElements) return\n\n let value = '';\n\n if (props.x !== undefined || props.y !== undefined || props.z !== undefined) {\n value += `translate3d(${props.x ?? 0}px, ${props.y ?? 0}px, ${props.z ?? 0}px) `;\n }\n\n if (props.rotate !== undefined) {\n value += `rotate(${props.rotate}deg) `;\n } else {\n if (props.rotateX !== undefined) {\n value += `rotateX(${props.rotateX}deg) `;\n }\n\n if (props.rotateY !== undefined) {\n value += `rotateY(${props.rotateY}deg) `;\n }\n\n if (props.rotateZ !== undefined) {\n value += `rotateZ(${props.rotateZ}deg) `;\n }\n }\n\n if (props.scale !== undefined) {\n value += `scale(${props.scale}) `;\n } else {\n if (props.scaleX !== undefined) {\n value += `scaleX(${props.scaleX}) `;\n }\n\n if (props.scaleY !== undefined) {\n value += `scaleY(${props.scaleY}) `;\n }\n\n if (props.scaleZ !== undefined) {\n value += `scaleZ(${props.scaleZ}) `;\n }\n }\n\n if (props.skew !== undefined) {\n value += `skew(${props.skew}deg) `;\n } else {\n if (props.skewX !== undefined) {\n value += `skewX(${props.skewX}deg) `;\n }\n\n if (props.skewY !== undefined) {\n value += `skewY(${props.skewY}deg) `;\n }\n }\n\n eachElements(elementOrElements, (element) => {\n element.style.transform = value;\n });\n return value;\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,oBAAoB;AAmBtB,MAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,SAAS,UACd,mBACA,OACQ;AACR,MAAI,CAAC,kBAAmB;AAExB,MAAI,QAAQ;AAEZ,MAAI,MAAM,MAAM,UAAa,MAAM,MAAM,UAAa,MAAM,MAAM,QAAW;AAC3E,aAAS,eAAe,MAAM,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC;AAAA,EAC5E;AAEA,MAAI,MAAM,WAAW,QAAW;AAC9B,aAAS,UAAU,MAAM,MAAM;AAAA,EACjC,OAAO;AACL,QAAI,MAAM,YAAY,QAAW;AAC/B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAEA,QAAI,MAAM,YAAY,QAAW;AAC/B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAEA,QAAI,MAAM,YAAY,QAAW;AAC/B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,MAAM,UAAU,QAAW;AAC7B,aAAS,SAAS,MAAM,KAAK;AAAA,EAC/B,OAAO;AACL,QAAI,MAAM,WAAW,QAAW;AAC9B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,MAAM,WAAW,QAAW;AAC9B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,MAAM,WAAW,QAAW;AAC9B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,QAAW;AAC5B,aAAS,QAAQ,MAAM,IAAI;AAAA,EAC7B,OAAO;AACL,QAAI,MAAM,UAAU,QAAW;AAC7B,eAAS,SAAS,MAAM,KAAK;AAAA,IAC/B;AAEA,QAAI,MAAM,UAAU,QAAW;AAC7B,eAAS,SAAS,MAAM,KAAK;AAAA,IAC/B;AAAA,EACF;AAEA,eAAa,mBAAmB,CAAC,YAAY;AAC3C,YAAQ,MAAM,YAAY;AAAA,EAC5B,CAAC;AACD,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/utils/index.d.ts
CHANGED