fix(studio): per-property-group intercept routing + drag/resize fixes (#1356)

* fix(core): per-property-group keyframe foundations

Add PropertyGroupName type system (position/scale/size/rotation/visual/other),
PROPERTY_GROUPS constant, classifyPropertyGroup/classifyTweenPropertyGroup
functions. Parser generates group-aware animation IDs, resolves position strings
(+=, -=, <, >), uses numeric matching with 2% tolerance, and preserves IDs
across all mutations.

* fix(core): add split-into-property-groups and replace-with-keyframes mutations

Server-side mutations for atomic property-group splitting and keyframe
replacement. Client commitMutation returns early on changed:false instead
of throwing.

* fix(studio): per-property-group intercept routing + drag/resize fixes

Rewire GSAP runtime bridge for property-group routing: drag sends only {x,y}
to position group, resize routes to scale group via data-hf-studio-original-width,
rotation routes to rotation group. Add resolveGroupTween helper, from-extend
with split-first-then-position-only pattern, autoKeyframeEnabled guards,
GSAP base + delta fix in drag draft, cancel-restores-GSAP-x/y from data attrs.
This commit is contained in:
Miguel Ángel
2026-06-12 00:19:13 -04:00
committed by GitHub
parent b6bf1b1190
commit 95029e083e
12 changed files with 503 additions and 176 deletions
@@ -52,10 +52,12 @@ function readElementPosition(
const element = sel.element;
if (!element?.isConnected || !gsap?.getProperty) return result;
const POSITION_PROPS = new Set(["x", "y", "xPercent", "yPercent"]);
const props = anim ? Object.keys(anim.properties) : ["x", "y", "opacity"];
for (const prop of props) {
const val = Number(gsap.getProperty(element, prop));
if (Number.isFinite(val)) result[prop] = Math.round(val);
if (!Number.isFinite(val)) continue;
result[prop] = POSITION_PROPS.has(prop) ? Math.round(val) : Math.round(val * 1000) / 1000;
}
return result;