feat(sdk,core): ws-3 — unrollDynamicAnimations acorn port + SDK op (#1501)

* feat(sdk,core): ws-3 — unrollDynamicAnimations acorn port + SDK op

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Co-authored-by: Miguel Ángel <miguel07alm@protonmail.com>

* test(core): recast-vs-acorn parity + acorn fixes for arc/unroll/keyframe-add/%-removeKeyframe/add-with-keyframes (WS-3.F gate)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(core): port shiftPositions/scalePositions to acorn writer (WS-3.F)

shiftPositionsInScript + scalePositionsInScript were recast-only GSAP-script
writers reachable from executeGsapMutation (shift-positions/scale-positions),
called by Studio timeline clip move/resize — the last write ops blocking recast
retirement. Ported to gsapWriterAcorn.ts mirroring recast's arithmetic
(shift: max(0,pos+delta); scale: remap pos by duration ratio + scale duration),
reusing a shared overwritePosition helper (also adopted by updateAnimationInScript).
Adds 10 recast-vs-acorn parity tests. Closes the WS-3.F op-coverage gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Miguel Ángel <miguel07alm@protonmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-06-17 16:54:04 -07:00
committed by GitHub
co-authored by Claude Opus 4.8 Miguel Ángel
parent 1612d18fdf
commit 09cefc1bb7
4 changed files with 709 additions and 9 deletions
+8
View File
@@ -61,6 +61,7 @@ import {
setArcPathInScript,
updateArcSegmentInScript,
removeArcPathFromScript,
unrollDynamicAnimations,
} from "@hyperframes/core/gsap-writer-acorn";
import { deriveKeyframeBackfillDefaults } from "./keyframeBackfill.js";
@@ -208,6 +209,12 @@ function applyArcPathOp(parsed: ParsedDocument, op: EditOp): MutationResult | un
);
case "removeArcPath":
return handleArcPathScript(parsed, s, removeArcPathFromScript(s, op.animationId));
case "unrollDynamicAnimations":
return handleArcPathScript(
parsed,
s,
unrollDynamicAnimations(s, op.animationId, op.elements),
);
default:
return undefined;
}
@@ -1107,6 +1114,7 @@ export function validateOp(parsed: ParsedDocument, op: EditOp): CanResult {
case "setArcPath":
case "updateArcSegment":
case "removeArcPath":
case "unrollDynamicAnimations":
case "deleteAllForSelector":
case "removeLabel":
if (getGsapScript(parsed.document) === null)
+10 -1
View File
@@ -157,7 +157,16 @@ export type EditOp =
cp2?: { x: number; y: number };
};
}
| { type: "removeArcPath"; animationId: string };
| { type: "removeArcPath"; animationId: string }
| {
type: "unrollDynamicAnimations";
animationId: string;
elements: Array<{
selector: string;
keyframes: Array<{ percentage: number; properties: Record<string, number | string> }>;
easeEach?: string;
}>;
};
export interface ElasticHold {
start: number;