@hyperframes/parsers 0.8.132 → 0.8.134
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gsapConstants.d.ts +1 -1
- package/dist/gsapConstants.js +29 -8
- package/dist/gsapConstants.js.map +1 -1
- package/dist/gsapParser.d.ts +3 -15
- package/dist/gsapParser.js +40 -9
- package/dist/gsapParser.js.map +1 -1
- package/dist/gsapParserAcorn.d.ts +2 -2
- package/dist/gsapParserAcorn.js.map +1 -1
- package/dist/gsapParserExports.d.ts +1 -1
- package/dist/gsapParserExports.js.map +1 -1
- package/dist/{gsapSerialize-CfSXM_Ez.d.ts → gsapSerialize-_tuK-qvB.d.ts} +10 -4
- package/dist/gsapWriterAcorn.d.ts +6 -3
- package/dist/gsapWriterAcorn.js +91 -9
- package/dist/gsapWriterAcorn.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/gsapConstants.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { B as BUILTIN_VAR_KEYS, D as DROPPED_VAR_KEYS, E as EXTRAS_KEYS, u as GSAP_DEFAULT_DURATION, j as PROPERTY_GROUPS, k as PropertyGroupName, S as SUPPORTED_EASES, l as SUPPORTED_PROPS, m as classifyPropertyGroup, n as classifyTweenPropertyGroup, x as
|
|
1
|
+
export { B as BUILTIN_VAR_KEYS, D as DROPPED_VAR_KEYS, E as EXTRAS_KEYS, u as GSAP_DEFAULT_DURATION, H as HoldScope, j as PROPERTY_GROUPS, k as PropertyGroupName, S as SUPPORTED_EASES, l as SUPPORTED_PROPS, m as classifyPropertyGroup, n as classifyTweenPropertyGroup, x as holdScope, y as isTweenConfigKey, z as isXYPositionWrite, C as keyframeHoldForAnimation } from './gsapSerialize-_tuK-qvB.js';
|
|
2
2
|
import './types-Ejqndkej.js';
|
package/dist/gsapConstants.js
CHANGED
|
@@ -94,23 +94,43 @@ function knownStart(animation) {
|
|
|
94
94
|
if (animation.resolvedStart !== void 0) return animation.resolvedStart;
|
|
95
95
|
return typeof animation.position === "number" ? animation.position : void 0;
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
var tweenSignature = (a) => JSON.stringify([a.targetSelector, a.method, a.position, a.duration, a.properties, a.keyframes]);
|
|
98
|
+
function holdScope(before, previous) {
|
|
99
|
+
const kept = new Set(previous?.map(tweenSignature));
|
|
100
|
+
const held = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const a of before.filter((b) => b.method === "set" && b.properties?.data === "hf-hold")) {
|
|
102
|
+
const props = held.get(a.targetSelector) ?? /* @__PURE__ */ new Map();
|
|
103
|
+
for (const [property, value] of Object.entries(a.properties)) props.set(property, value);
|
|
104
|
+
held.set(a.targetSelector, props);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
touched: (a) => previous !== null && !kept.has(tweenSignature(a)),
|
|
108
|
+
held: (selector) => held.get(selector) ?? /* @__PURE__ */ new Map()
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function keyframeHoldForAnimation(animation, animations, scope) {
|
|
98
112
|
if (!animation.keyframes) return null;
|
|
99
|
-
const start = knownStart(animation)
|
|
100
|
-
|
|
113
|
+
const start = knownStart(animation);
|
|
114
|
+
const lone = animation.keyframes.keyframes.length === 1;
|
|
115
|
+
if (start === void 0 || !(start > 1e-3) && !lone) return null;
|
|
101
116
|
const atStart = animation.keyframes.keyframes.find((keyframe) => keyframe.percentage === 0);
|
|
102
117
|
if (!atStart) return null;
|
|
103
118
|
const earlier = animations.filter((other) => {
|
|
104
119
|
const otherStart = knownStart(other);
|
|
105
120
|
return other !== animation && !other.global && other.targetSelector === animation.targetSelector && otherStart !== void 0 && otherStart < start - 1e-3;
|
|
106
121
|
});
|
|
107
|
-
const
|
|
122
|
+
const touched = scope.touched(animation);
|
|
123
|
+
const pinned = scope.held(animation.targetSelector);
|
|
124
|
+
const kept = (property, value) => touched ? pinned.has(property) : pinned.get(property) === value;
|
|
125
|
+
const pins = (group, property, value) => group === "position" && start > 1e-3 || (group === "position" || group === "size") && (lone && touched || kept(property, value));
|
|
126
|
+
const hold = {};
|
|
108
127
|
for (const [property, value] of Object.entries(atStart.properties)) {
|
|
109
|
-
if (classifyPropertyGroup(property)
|
|
128
|
+
if (!pins(classifyPropertyGroup(property), property, value) || typeof value !== "number")
|
|
129
|
+
continue;
|
|
110
130
|
if (earlier.some((other) => writesProperty(other, property))) continue;
|
|
111
|
-
|
|
131
|
+
hold[property] = value;
|
|
112
132
|
}
|
|
113
|
-
return Object.keys(
|
|
133
|
+
return Object.keys(hold).length > 0 ? hold : null;
|
|
114
134
|
}
|
|
115
135
|
var SUPPORTED_EASES = [
|
|
116
136
|
"none",
|
|
@@ -159,8 +179,9 @@ export {
|
|
|
159
179
|
SUPPORTED_PROPS,
|
|
160
180
|
classifyPropertyGroup,
|
|
161
181
|
classifyTweenPropertyGroup,
|
|
182
|
+
holdScope,
|
|
162
183
|
isTweenConfigKey,
|
|
163
184
|
isXYPositionWrite,
|
|
164
|
-
|
|
185
|
+
keyframeHoldForAnimation
|
|
165
186
|
};
|
|
166
187
|
//# sourceMappingURL=gsapConstants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/gsapConstants.ts"],"sourcesContent":["/**\n * GSAP property and ease constants.\n *\n * Extracted into a standalone module so browser code can import them\n * without pulling in gsapParser (which depends on recast / @babel/parser).\n */\n\nimport type { GsapAnimation } from \"./gsapSerialize.js\";\n\nexport const GSAP_DEFAULT_DURATION = 0.5;\n\nexport const SUPPORTED_PROPS = [\n // 2D Transforms\n \"x\",\n \"y\",\n \"scale\",\n \"scaleX\",\n \"scaleY\",\n \"rotation\",\n \"skewX\",\n \"skewY\",\n // 3D Transforms\n \"z\",\n \"rotationX\",\n \"rotationY\",\n \"rotationZ\",\n \"perspective\",\n \"transformPerspective\",\n \"transformOrigin\",\n // Visibility\n \"opacity\",\n \"visibility\",\n \"autoAlpha\",\n // Dimensions\n \"width\",\n \"height\",\n // Colors\n \"color\",\n \"backgroundColor\",\n \"borderColor\",\n // Box model\n \"borderRadius\",\n // Typography\n \"fontSize\",\n \"letterSpacing\",\n // Filter & Clipping\n \"filter\",\n \"clipPath\",\n // DOM content (number counters, text roll-ups)\n \"innerText\",\n];\n\n/** Keys stored on dedicated GsapAnimation fields (not in properties/extras). */\nexport const BUILTIN_VAR_KEYS: ReadonlySet<string> = new Set([\"duration\", \"ease\", \"delay\"]);\nexport const DROPPED_VAR_KEYS: ReadonlySet<string> = new Set([\n \"onComplete\",\n \"onStart\",\n \"onUpdate\",\n \"onRepeat\",\n]);\n/** Keys that go in `extras`: non-editable GSAP config that must survive round-trips. */\nexport const EXTRAS_KEYS: ReadonlySet<string> = new Set([\n \"stagger\",\n \"yoyo\",\n \"repeat\",\n \"repeatDelay\",\n \"snap\",\n \"overwrite\",\n \"immediateRender\",\n]);\n\nexport function isTweenConfigKey(key: string): boolean {\n return BUILTIN_VAR_KEYS.has(key) || DROPPED_VAR_KEYS.has(key) || EXTRAS_KEYS.has(key);\n}\n\n// ── Property Groups ─────────────────────────────────────────────────────────\n// Each group maps to an independent GSAP tween so editing one property\n// (e.g. drag → x/y) never contaminates another (e.g. scale, rotation).\n\nexport type PropertyGroupName = \"position\" | \"scale\" | \"size\" | \"rotation\" | \"visual\" | \"other\";\n\nexport const PROPERTY_GROUPS: Record<PropertyGroupName, ReadonlySet<string>> = {\n position: new Set([\"x\", \"y\", \"xPercent\", \"yPercent\"]),\n scale: new Set([\"scale\", \"scaleX\", \"scaleY\"]),\n size: new Set([\"width\", \"height\"]),\n rotation: new Set([\"rotation\", \"skewX\", \"skewY\"]),\n visual: new Set([\"opacity\", \"autoAlpha\"]),\n other: new Set<string>(),\n};\n\nconst PROP_TO_GROUP = new Map<string, PropertyGroupName>();\nfor (const [group, props] of Object.entries(PROPERTY_GROUPS) as [\n PropertyGroupName,\n ReadonlySet<string>,\n][]) {\n for (const p of props) PROP_TO_GROUP.set(p, group);\n}\n\ntype PositionWrite = Pick<\n GsapAnimation,\n \"propertyGroup\" | \"properties\" | \"fromProperties\" | \"keyframes\"\n>;\n\nfunction writesProperty(animation: PositionWrite, property: string): boolean {\n return (\n property in animation.properties ||\n (!!animation.fromProperties && property in animation.fromProperties) ||\n !!animation.keyframes?.keyframes.some((k) => property in k.properties)\n );\n}\n\n/** A position write that sets x or y. An xPercent/yPercent centring set never duplicates one. */\nexport function isXYPositionWrite(a: PositionWrite): boolean {\n return a.propertyGroup === \"position\" && (writesProperty(a, \"x\") || writesProperty(a, \"y\"));\n}\n\nexport function classifyPropertyGroup(prop: string): PropertyGroupName {\n return PROP_TO_GROUP.get(prop) ?? \"other\";\n}\n\nexport function classifyTweenPropertyGroup(\n properties: Record<string, unknown>,\n): PropertyGroupName | undefined {\n const groups = new Set<PropertyGroupName>();\n for (const key of Object.keys(properties)) {\n // transformOrigin is a modifier; `_auto` is Studio's internal endpoint marker;\n // `data` is GSAP-reserved (carries the Studio hold-set tag). None is an animated\n // property, so none should affect the group.\n if (key === \"transformOrigin\" || key === \"_auto\" || key === \"data\") continue;\n const g = classifyPropertyGroup(key);\n groups.add(g);\n }\n if (groups.size === 1) return groups.values().next().value;\n return undefined;\n}\n\nfunction knownStart(animation: GsapAnimation): number | undefined {\n if (animation.resolvedStart !== undefined) return animation.resolvedStart;\n return typeof animation.position === \"number\" ? animation.position : undefined;\n}\n\n/**\n * What a Studio hold pins from t=0 before a later keyframed tween: its 0% keyframe's position props,\n * minus those an earlier timeline tween on the target writes (a global `gsap.set` is a base value).\n */\nexport function positionHoldForAnimation(\n animation: GsapAnimation,\n animations: readonly GsapAnimation[],\n): Record<string, number> | null {\n if (!animation.keyframes) return null;\n const start = knownStart(animation) ?? 0;\n if (!(start > 0.001)) return null;\n const atStart = animation.keyframes.keyframes.find((keyframe) => keyframe.percentage === 0);\n if (!atStart) return null;\n // A tween whose start the parser could not resolve (a label, say) is not known to come first.\n const earlier = animations.filter((other) => {\n const otherStart = knownStart(other);\n return (\n other !== animation &&\n !other.global &&\n other.targetSelector === animation.targetSelector &&\n otherStart !== undefined &&\n otherStart < start - 0.001\n );\n });\n const position: Record<string, number> = {};\n for (const [property, value] of Object.entries(atStart.properties)) {\n if (classifyPropertyGroup(property) !== \"position\" || typeof value !== \"number\") continue;\n if (earlier.some((other) => writesProperty(other, property))) continue;\n position[property] = value;\n }\n return Object.keys(position).length > 0 ? position : null;\n}\n\nexport const SUPPORTED_EASES = [\n \"none\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ.inOut\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"elastic.out(1,0.3)\",\n \"elastic.inOut(1,0.3)\",\n \"spring-gentle\",\n \"spring-bouncy\",\n \"spring-stiff\",\n \"spring-wobbly\",\n \"spring-heavy\",\n \"hold\",\n \"steps(1)\",\n];\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/gsapConstants.ts"],"sourcesContent":["/**\n * GSAP property and ease constants.\n *\n * Extracted into a standalone module so browser code can import them\n * without pulling in gsapParser (which depends on recast / @babel/parser).\n */\n\nimport type { GsapAnimation } from \"./gsapSerialize.js\";\n\nexport const GSAP_DEFAULT_DURATION = 0.5;\n\nexport const SUPPORTED_PROPS = [\n // 2D Transforms\n \"x\",\n \"y\",\n \"scale\",\n \"scaleX\",\n \"scaleY\",\n \"rotation\",\n \"skewX\",\n \"skewY\",\n // 3D Transforms\n \"z\",\n \"rotationX\",\n \"rotationY\",\n \"rotationZ\",\n \"perspective\",\n \"transformPerspective\",\n \"transformOrigin\",\n // Visibility\n \"opacity\",\n \"visibility\",\n \"autoAlpha\",\n // Dimensions\n \"width\",\n \"height\",\n // Colors\n \"color\",\n \"backgroundColor\",\n \"borderColor\",\n // Box model\n \"borderRadius\",\n // Typography\n \"fontSize\",\n \"letterSpacing\",\n // Filter & Clipping\n \"filter\",\n \"clipPath\",\n // DOM content (number counters, text roll-ups)\n \"innerText\",\n];\n\n/** Keys stored on dedicated GsapAnimation fields (not in properties/extras). */\nexport const BUILTIN_VAR_KEYS: ReadonlySet<string> = new Set([\"duration\", \"ease\", \"delay\"]);\nexport const DROPPED_VAR_KEYS: ReadonlySet<string> = new Set([\n \"onComplete\",\n \"onStart\",\n \"onUpdate\",\n \"onRepeat\",\n]);\n/** Keys that go in `extras`: non-editable GSAP config that must survive round-trips. */\nexport const EXTRAS_KEYS: ReadonlySet<string> = new Set([\n \"stagger\",\n \"yoyo\",\n \"repeat\",\n \"repeatDelay\",\n \"snap\",\n \"overwrite\",\n \"immediateRender\",\n]);\n\nexport function isTweenConfigKey(key: string): boolean {\n return BUILTIN_VAR_KEYS.has(key) || DROPPED_VAR_KEYS.has(key) || EXTRAS_KEYS.has(key);\n}\n\n// ── Property Groups ─────────────────────────────────────────────────────────\n// Each group maps to an independent GSAP tween so editing one property\n// (e.g. drag → x/y) never contaminates another (e.g. scale, rotation).\n\nexport type PropertyGroupName = \"position\" | \"scale\" | \"size\" | \"rotation\" | \"visual\" | \"other\";\n\nexport const PROPERTY_GROUPS: Record<PropertyGroupName, ReadonlySet<string>> = {\n position: new Set([\"x\", \"y\", \"xPercent\", \"yPercent\"]),\n scale: new Set([\"scale\", \"scaleX\", \"scaleY\"]),\n size: new Set([\"width\", \"height\"]),\n rotation: new Set([\"rotation\", \"skewX\", \"skewY\"]),\n visual: new Set([\"opacity\", \"autoAlpha\"]),\n other: new Set<string>(),\n};\n\nconst PROP_TO_GROUP = new Map<string, PropertyGroupName>();\nfor (const [group, props] of Object.entries(PROPERTY_GROUPS) as [\n PropertyGroupName,\n ReadonlySet<string>,\n][]) {\n for (const p of props) PROP_TO_GROUP.set(p, group);\n}\n\ntype PositionWrite = Pick<\n GsapAnimation,\n \"propertyGroup\" | \"properties\" | \"fromProperties\" | \"keyframes\"\n>;\n\nfunction writesProperty(animation: PositionWrite, property: string): boolean {\n return (\n property in animation.properties ||\n (!!animation.fromProperties && property in animation.fromProperties) ||\n !!animation.keyframes?.keyframes.some((k) => property in k.properties)\n );\n}\n\n/** A position write that sets x or y. An xPercent/yPercent centring set never duplicates one. */\nexport function isXYPositionWrite(a: PositionWrite): boolean {\n return a.propertyGroup === \"position\" && (writesProperty(a, \"x\") || writesProperty(a, \"y\"));\n}\n\nexport function classifyPropertyGroup(prop: string): PropertyGroupName {\n return PROP_TO_GROUP.get(prop) ?? \"other\";\n}\n\nexport function classifyTweenPropertyGroup(\n properties: Record<string, unknown>,\n): PropertyGroupName | undefined {\n const groups = new Set<PropertyGroupName>();\n for (const key of Object.keys(properties)) {\n // transformOrigin is a modifier; `_auto` is Studio's internal endpoint marker;\n // `data` is GSAP-reserved (carries the Studio hold-set tag). None is an animated\n // property, so none should affect the group.\n if (key === \"transformOrigin\" || key === \"_auto\" || key === \"data\") continue;\n const g = classifyPropertyGroup(key);\n groups.add(g);\n }\n if (groups.size === 1) return groups.values().next().value;\n return undefined;\n}\n\nfunction knownStart(animation: GsapAnimation): number | undefined {\n if (animation.resolvedStart !== undefined) return animation.resolvedStart;\n return typeof animation.position === \"number\" ? animation.position : undefined;\n}\n\nexport interface HoldScope {\n touched: (animation: GsapAnimation) => boolean;\n held: (selector: string) => ReadonlyMap<string, unknown>;\n}\n\nconst tweenSignature = (a: GsapAnimation) =>\n JSON.stringify([a.targetSelector, a.method, a.position, a.duration, a.properties, a.keyframes]);\n\n/** The tweens an edit touched (not in `previous`; none without it), and what the script's holds already pin. */\nexport function holdScope(\n before: readonly GsapAnimation[],\n previous: readonly GsapAnimation[] | null,\n): HoldScope {\n const kept = new Set(previous?.map(tweenSignature));\n const held = new Map<string, Map<string, unknown>>();\n for (const a of before.filter((b) => b.method === \"set\" && b.properties?.data === \"hf-hold\")) {\n const props = held.get(a.targetSelector) ?? new Map<string, unknown>();\n for (const [property, value] of Object.entries(a.properties)) props.set(property, value);\n held.set(a.targetSelector, props);\n }\n return {\n touched: (a) => previous !== null && !kept.has(tweenSignature(a)),\n held: (selector) => held.get(selector) ?? new Map(),\n };\n}\n\n/**\n * What a Studio hold pins from t=0: a keyframed tween's 0% position props before a later start, and the position and\n * size of a lone key (GSAP renders none) only where this edit made it or a hold already pins it, minus earlier tweens.\n */\nexport function keyframeHoldForAnimation(\n animation: GsapAnimation,\n animations: readonly GsapAnimation[],\n scope: HoldScope,\n): Record<string, number> | null {\n if (!animation.keyframes) return null;\n const start = knownStart(animation);\n const lone = animation.keyframes.keyframes.length === 1;\n if (start === undefined || (!(start > 0.001) && !lone)) return null;\n const atStart = animation.keyframes.keyframes.find((keyframe) => keyframe.percentage === 0);\n if (!atStart) return null;\n // A tween whose start the parser could not resolve (a label, say) is not known to come first.\n const earlier = animations.filter((other) => {\n const otherStart = knownStart(other);\n return (\n other !== animation &&\n !other.global &&\n other.targetSelector === animation.targetSelector &&\n otherStart !== undefined &&\n otherStart < start - 0.001\n );\n });\n const touched = scope.touched(animation);\n const pinned = scope.held(animation.targetSelector);\n // An untouched tween keeps only the hold it made: one with its own first value.\n const kept = (property: string, value: unknown) =>\n touched ? pinned.has(property) : pinned.get(property) === value;\n const pins = (group: PropertyGroupName, property: string, value: unknown) =>\n (group === \"position\" && start > 0.001) ||\n ((group === \"position\" || group === \"size\") && ((lone && touched) || kept(property, value)));\n const hold: Record<string, number> = {};\n for (const [property, value] of Object.entries(atStart.properties)) {\n if (!pins(classifyPropertyGroup(property), property, value) || typeof value !== \"number\")\n continue;\n if (earlier.some((other) => writesProperty(other, property))) continue;\n hold[property] = value;\n }\n return Object.keys(hold).length > 0 ? hold : null;\n}\n\nexport const SUPPORTED_EASES = [\n \"none\",\n \"power1.in\",\n \"power1.out\",\n \"power1.inOut\",\n \"power2.in\",\n \"power2.out\",\n \"power2.inOut\",\n \"power3.in\",\n \"power3.out\",\n \"power3.inOut\",\n \"power4.in\",\n \"power4.out\",\n \"power4.inOut\",\n \"back.in\",\n \"back.out\",\n \"back.inOut\",\n \"elastic.in\",\n \"elastic.out\",\n \"elastic.inOut\",\n \"bounce.in\",\n \"bounce.out\",\n \"bounce.inOut\",\n \"circ.inOut\",\n \"expo.in\",\n \"expo.out\",\n \"expo.inOut\",\n \"elastic.out(1,0.3)\",\n \"elastic.inOut(1,0.3)\",\n \"spring-gentle\",\n \"spring-bouncy\",\n \"spring-stiff\",\n \"spring-wobbly\",\n \"spring-heavy\",\n \"hold\",\n \"steps(1)\",\n];\n"],"mappings":"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","names":[]}
|
package/dist/gsapParser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as GsapAnimation, P as ParsedGsap, A as ArcPathConfig, b as ArcPathSegment } from './gsapSerialize-
|
|
2
|
-
export { g as GsapKeyframeFormat, h as GsapKeyframesData, G as GsapMethod, i as GsapPercentageKeyframe, j as PROPERTY_GROUPS, k as PropertyGroupName, S as SUPPORTED_EASES, l as SUPPORTED_PROPS, m as classifyPropertyGroup, n as classifyTweenPropertyGroup, o as getAnimationsForElementId, p as gsapAnimationsToKeyframes, q as keyframesToGsapAnimations, s as serializeGsapAnimations, v as validateCompositionGsap } from './gsapSerialize-
|
|
1
|
+
import { a as GsapAnimation, P as ParsedGsap, A as ArcPathConfig, b as ArcPathSegment } from './gsapSerialize-_tuK-qvB.js';
|
|
2
|
+
export { g as GsapKeyframeFormat, h as GsapKeyframesData, G as GsapMethod, i as GsapPercentageKeyframe, j as PROPERTY_GROUPS, k as PropertyGroupName, S as SUPPORTED_EASES, l as SUPPORTED_PROPS, m as classifyPropertyGroup, n as classifyTweenPropertyGroup, o as getAnimationsForElementId, p as gsapAnimationsToKeyframes, q as keyframesToGsapAnimations, s as serializeGsapAnimations, v as validateCompositionGsap } from './gsapSerialize-_tuK-qvB.js';
|
|
3
3
|
export { SPRING_PRESETS, SpringPreset, generateSpringEaseData } from './springEase.js';
|
|
4
4
|
import './types-Ejqndkej.js';
|
|
5
5
|
|
|
@@ -36,19 +36,7 @@ declare function dedupePositionWritesInScript(script: string, selector: string,
|
|
|
36
36
|
/** True for a `tl.set(...)` this module emitted to hold a keyframe before its tween.
|
|
37
37
|
* The Studio filters these out so they never appear as user keyframes/diamonds. */
|
|
38
38
|
declare function isStudioHoldSet(anim: GsapAnimation): boolean;
|
|
39
|
-
|
|
40
|
-
* Keep a `tl.set(selector, {x,y}, 0)` "hold" in front of every position-keyframed
|
|
41
|
-
* tween that starts after t=0, so the element holds its first keyframe's position
|
|
42
|
-
* BEFORE the tween plays instead of snapping to its CSS base (the universal NLE
|
|
43
|
-
* "hold before first keyframe" behavior). The set is tagged with `data: "hf-hold"`
|
|
44
|
-
* so this pass owns it: every call wipes the prior holds and recomputes from the
|
|
45
|
-
* current keyframes, keeping them in sync as keyframes are added/moved/deleted.
|
|
46
|
-
*
|
|
47
|
-
* Idempotent. Only position props (x/y/xPercent/yPercent) are held — opacity/scale
|
|
48
|
-
* keep their authored pre-tween behavior. A tween already starting at 0 needs no
|
|
49
|
-
* hold (no gap before it).
|
|
50
|
-
*/
|
|
51
|
-
declare function syncPositionHoldsBeforeKeyframes(script: string): string;
|
|
39
|
+
declare function syncPositionHoldsBeforeKeyframes(script: string, previous?: string): string;
|
|
52
40
|
interface SplitAnimationsOptions {
|
|
53
41
|
originalId: string;
|
|
54
42
|
newId: string;
|
package/dist/gsapParser.js
CHANGED
|
@@ -98,23 +98,43 @@ function knownStart(animation) {
|
|
|
98
98
|
if (animation.resolvedStart !== void 0) return animation.resolvedStart;
|
|
99
99
|
return typeof animation.position === "number" ? animation.position : void 0;
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
var tweenSignature = (a) => JSON.stringify([a.targetSelector, a.method, a.position, a.duration, a.properties, a.keyframes]);
|
|
102
|
+
function holdScope(before, previous) {
|
|
103
|
+
const kept = new Set(previous?.map(tweenSignature));
|
|
104
|
+
const held = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const a of before.filter((b) => b.method === "set" && b.properties?.data === "hf-hold")) {
|
|
106
|
+
const props = held.get(a.targetSelector) ?? /* @__PURE__ */ new Map();
|
|
107
|
+
for (const [property, value] of Object.entries(a.properties)) props.set(property, value);
|
|
108
|
+
held.set(a.targetSelector, props);
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
touched: (a) => previous !== null && !kept.has(tweenSignature(a)),
|
|
112
|
+
held: (selector) => held.get(selector) ?? /* @__PURE__ */ new Map()
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function keyframeHoldForAnimation(animation, animations, scope) {
|
|
102
116
|
if (!animation.keyframes) return null;
|
|
103
|
-
const start = knownStart(animation)
|
|
104
|
-
|
|
117
|
+
const start = knownStart(animation);
|
|
118
|
+
const lone = animation.keyframes.keyframes.length === 1;
|
|
119
|
+
if (start === void 0 || !(start > 1e-3) && !lone) return null;
|
|
105
120
|
const atStart = animation.keyframes.keyframes.find((keyframe) => keyframe.percentage === 0);
|
|
106
121
|
if (!atStart) return null;
|
|
107
122
|
const earlier = animations.filter((other) => {
|
|
108
123
|
const otherStart = knownStart(other);
|
|
109
124
|
return other !== animation && !other.global && other.targetSelector === animation.targetSelector && otherStart !== void 0 && otherStart < start - 1e-3;
|
|
110
125
|
});
|
|
111
|
-
const
|
|
126
|
+
const touched = scope.touched(animation);
|
|
127
|
+
const pinned = scope.held(animation.targetSelector);
|
|
128
|
+
const kept = (property, value) => touched ? pinned.has(property) : pinned.get(property) === value;
|
|
129
|
+
const pins = (group, property, value) => group === "position" && start > 1e-3 || (group === "position" || group === "size") && (lone && touched || kept(property, value));
|
|
130
|
+
const hold = {};
|
|
112
131
|
for (const [property, value] of Object.entries(atStart.properties)) {
|
|
113
|
-
if (classifyPropertyGroup(property)
|
|
132
|
+
if (!pins(classifyPropertyGroup(property), property, value) || typeof value !== "number")
|
|
133
|
+
continue;
|
|
114
134
|
if (earlier.some((other) => writesProperty(other, property))) continue;
|
|
115
|
-
|
|
135
|
+
hold[property] = value;
|
|
116
136
|
}
|
|
117
|
-
return Object.keys(
|
|
137
|
+
return Object.keys(hold).length > 0 ? hold : null;
|
|
118
138
|
}
|
|
119
139
|
var SUPPORTED_EASES = [
|
|
120
140
|
"none",
|
|
@@ -1768,7 +1788,14 @@ var STUDIO_HOLD_MARKER = "hf-hold";
|
|
|
1768
1788
|
function isStudioHoldSet(anim) {
|
|
1769
1789
|
return anim.method === "set" && anim.properties?.data === STUDIO_HOLD_MARKER;
|
|
1770
1790
|
}
|
|
1771
|
-
function
|
|
1791
|
+
function animationsOf(script) {
|
|
1792
|
+
try {
|
|
1793
|
+
return parseGsapScript(script).animations;
|
|
1794
|
+
} catch {
|
|
1795
|
+
return null;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
function syncPositionHoldsBeforeKeyframes(script, previous) {
|
|
1772
1799
|
let parsed;
|
|
1773
1800
|
try {
|
|
1774
1801
|
parsed = parseGsapScript(script);
|
|
@@ -1784,8 +1811,12 @@ function syncPositionHoldsBeforeKeyframes(script) {
|
|
|
1784
1811
|
} catch {
|
|
1785
1812
|
return result;
|
|
1786
1813
|
}
|
|
1814
|
+
const scope = holdScope(
|
|
1815
|
+
parsed.animations,
|
|
1816
|
+
previous === void 0 ? null : animationsOf(previous)
|
|
1817
|
+
);
|
|
1787
1818
|
for (const anim of reparsed.animations) {
|
|
1788
|
-
const posProps =
|
|
1819
|
+
const posProps = keyframeHoldForAnimation(anim, reparsed.animations, scope);
|
|
1789
1820
|
if (!posProps) continue;
|
|
1790
1821
|
result = insertInheritedStateSet(result, anim.targetSelector, 0, {
|
|
1791
1822
|
...posProps,
|