mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(core): split-into-property-groups and replace-with-keyframes mutations (#1355)
* 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.
This commit is contained in:
@@ -409,6 +409,20 @@ type GsapMutationRequest =
|
||||
}>;
|
||||
ease?: string;
|
||||
}
|
||||
| {
|
||||
type: "replace-with-keyframes";
|
||||
animationId: string;
|
||||
targetSelector: string;
|
||||
position: number;
|
||||
duration: number;
|
||||
keyframes: Array<{
|
||||
percentage: number;
|
||||
properties: Record<string, number | string>;
|
||||
ease?: string;
|
||||
auto?: boolean;
|
||||
}>;
|
||||
ease?: string;
|
||||
}
|
||||
| {
|
||||
type: "split-animations";
|
||||
originalId: string;
|
||||
@@ -416,6 +430,10 @@ type GsapMutationRequest =
|
||||
splitTime: number;
|
||||
elementStart: number;
|
||||
elementDuration: number;
|
||||
}
|
||||
| {
|
||||
type: "split-into-property-groups";
|
||||
animationId: string;
|
||||
};
|
||||
|
||||
// ── GSAP mutation executor ──────────────────────────────────────────────────
|
||||
@@ -445,6 +463,7 @@ async function executeGsapMutation(
|
||||
removeArcPathFromScript,
|
||||
addAnimationWithKeyframesToScript,
|
||||
splitAnimationsInScript,
|
||||
splitIntoPropertyGroups,
|
||||
} = parser;
|
||||
|
||||
function requireAnimation(
|
||||
@@ -617,6 +636,18 @@ async function executeGsapMutation(
|
||||
);
|
||||
return result.script;
|
||||
}
|
||||
case "replace-with-keyframes": {
|
||||
const script = removeAnimationFromScript(block.scriptText, body.animationId);
|
||||
const added = addAnimationWithKeyframesToScript(
|
||||
script,
|
||||
body.targetSelector,
|
||||
body.position,
|
||||
body.duration,
|
||||
body.keyframes,
|
||||
body.ease,
|
||||
);
|
||||
return added.script;
|
||||
}
|
||||
case "split-animations": {
|
||||
if (
|
||||
typeof body.originalId !== "string" ||
|
||||
@@ -647,6 +678,10 @@ async function executeGsapMutation(
|
||||
elementDuration: body.elementDuration,
|
||||
});
|
||||
}
|
||||
case "split-into-property-groups": {
|
||||
const result = splitIntoPropertyGroups(block.scriptText, body.animationId);
|
||||
return result.script;
|
||||
}
|
||||
default:
|
||||
return respond({ error: `unknown mutation type: ${(body as { type: string }).type}` }, 400);
|
||||
}
|
||||
@@ -1061,8 +1096,9 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void {
|
||||
if (result instanceof Response) return result;
|
||||
|
||||
const newScript = typeof result === "string" ? result : result.script;
|
||||
const newHtml = block.replaceScript(newScript);
|
||||
if (newHtml !== html) {
|
||||
const changed = newScript !== block.scriptText;
|
||||
const newHtml = changed ? block.replaceScript(newScript) : html;
|
||||
if (changed) {
|
||||
writeFileSync(res.absPath, newHtml, "utf-8");
|
||||
}
|
||||
|
||||
@@ -1070,6 +1106,7 @@ export function registerFileRoutes(api: Hono, adapter: StudioApiAdapter): void {
|
||||
const freshParsed = parseGsapScript(newScript);
|
||||
const responsePayload: Record<string, unknown> = {
|
||||
ok: true,
|
||||
changed,
|
||||
parsed: freshParsed,
|
||||
before: html,
|
||||
after: newHtml,
|
||||
|
||||
Reference in New Issue
Block a user