@hyperframes/parsers 0.8.96 → 0.8.97

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.
@@ -12,6 +12,9 @@ declare function updateAnimationInScript(script: string, animationId: string, up
12
12
  * (used by timeline clip-move to keep GSAP positions in sync with the clip start).
13
13
  */
14
14
  declare function shiftPositionsInScript(script: string, targetSelector: string, delta: number): string;
15
+ /** Copies each tween on `fromSelector` for `toSelector`, `delta` seconds later, in its own argument text. Exact or
16
+ * absent: only a tween at a number, written straight in the timeline's own block, is copied. */
17
+ declare function copyAnimationsInScript(script: string, fromSelector: string, toSelector: string, delta: number): string;
15
18
  /**
16
19
  * Linearly remap every tween targeting `targetSelector` from the old clip
17
20
  * [oldStart, oldDuration] onto the new [newStart, newDuration] (position and,
@@ -148,4 +151,4 @@ type UnrollElement = {
148
151
  */
149
152
  declare function unrollDynamicAnimations(script: string, animationId: string, elements: UnrollElement[]): string;
150
153
 
151
- export { type UnrollElement, addAnimationToScript, addAnimationWithKeyframesToScript, addKeyframeToScript, addLabelToScript, addMotionPathPointInScript, addMotionPathToScript, convertToKeyframesFromScript, dedupePositionWritesInScript, materializeKeyframesFromScript, moveKeyframeInScript, removeAllKeyframesFromScript, removeAnimationFromScript, removeArcPathFromScript, removeKeyframeFromScript, removeLabelFromScript, removeMotionPathPointInScript, removePropertyFromAnimation, resizeKeyframedTweenInScript, scalePositionsInScript, setArcPathInScript, shiftPositionsInScript, splitAnimationsInScript, splitIntoPropertyGroupsFromScript, syncPositionHoldsBeforeKeyframes, unrollDynamicAnimations, updateAnimationInScript, updateArcSegmentInScript, updateKeyframeInScript, updateMotionPathPointInScript };
154
+ export { type UnrollElement, addAnimationToScript, addAnimationWithKeyframesToScript, addKeyframeToScript, addLabelToScript, addMotionPathPointInScript, addMotionPathToScript, convertToKeyframesFromScript, copyAnimationsInScript, dedupePositionWritesInScript, materializeKeyframesFromScript, moveKeyframeInScript, removeAllKeyframesFromScript, removeAnimationFromScript, removeArcPathFromScript, removeKeyframeFromScript, removeLabelFromScript, removeMotionPathPointInScript, removePropertyFromAnimation, resizeKeyframedTweenInScript, scalePositionsInScript, setArcPathInScript, shiftPositionsInScript, splitAnimationsInScript, splitIntoPropertyGroupsFromScript, syncPositionHoldsBeforeKeyframes, unrollDynamicAnimations, updateAnimationInScript, updateArcSegmentInScript, updateKeyframeInScript, updateMotionPathPointInScript };
@@ -1526,12 +1526,80 @@ function shiftPositionsInScript(script, targetSelector, delta) {
1526
1526
  for (const entry of parsed.located) {
1527
1527
  if (entry.animation.targetSelector !== targetSelector) continue;
1528
1528
  if (typeof entry.animation.position !== "number") continue;
1529
- const newPos = Math.max(0, Math.round((entry.animation.position + delta) * 1e3) / 1e3);
1530
- overwritePosition(ms, entry.call, newPos);
1529
+ overwritePosition(ms, entry.call, shiftedPosition(entry.animation.position, delta));
1531
1530
  changed = true;
1532
1531
  }
1533
1532
  return changed ? ms.toString() : script;
1534
1533
  }
1534
+ function copyAnimationsInScript(script, fromSelector, toSelector, delta) {
1535
+ const parsed = parseGsapScriptAcornForWrite(script);
1536
+ if (!parsed) return script;
1537
+ const block = timelineBlock(parsed);
1538
+ const target = JSON.stringify(toSelector);
1539
+ const ms = new MagicString(script);
1540
+ const tweens = [];
1541
+ for (const { animation, call } of parsed.located) {
1542
+ if (animation.targetSelector !== fromSelector || !copyable(call)) continue;
1543
+ const args = [target, ...argumentText(call, script)];
1544
+ const statement = findEnclosingExpressionStatement(call.ancestors);
1545
+ if (call.global && statement && inBlock(call, statement)) {
1546
+ ms.appendLeft(
1547
+ statement.end,
1548
+ `
1549
+ ${indentAt(script, statement.start)}gsap.set(${args.join(", ")});`
1550
+ );
1551
+ } else if (block.body.includes(statement) && typeof call.positionArg?.value === "number") {
1552
+ const position = valueToCode(shiftedPosition(call.positionArg.value, delta));
1553
+ tweens.push(`${parsed.timelineVar}.${call.method}(${[...args, position].join(", ")});`);
1554
+ }
1555
+ }
1556
+ appendAtBlockEnd(ms, script, block, tweens);
1557
+ return ms.toString();
1558
+ }
1559
+ function copyable(call) {
1560
+ if (call.node.arguments[0]?.type !== "Literal" || call.ancestors.some(isLoopOrForEach))
1561
+ return false;
1562
+ let link = findEnclosingExpressionStatement(call.ancestors)?.expression;
1563
+ while (link?.type === "CallExpression" && link !== call.node) link = link.callee?.object;
1564
+ return link === call.node;
1565
+ }
1566
+ function inBlock(call, statement) {
1567
+ return Array.isArray(call.ancestors[call.ancestors.indexOf(statement) - 1]?.body);
1568
+ }
1569
+ function argumentText(call, script) {
1570
+ return call.node.arguments.slice(1).filter((arg) => arg !== call.positionArg).map((arg) => script.slice(arg.start, arg.end));
1571
+ }
1572
+ function indentAt(script, at) {
1573
+ return /^[ \t]*/.exec(script.slice(script.lastIndexOf("\n", at - 1) + 1))[0];
1574
+ }
1575
+ function appendAtBlockEnd(ms, script, block, lines) {
1576
+ if (lines.length === 0) return;
1577
+ const last = block.body.at(-1);
1578
+ const indent = last ? indentAt(script, last.start) : "";
1579
+ const code = lines.map((line) => `${indent}${line}`).join("\n");
1580
+ if (last?.type === "ReturnStatement") ms.appendLeft(last.start, `${code.trimStart()}
1581
+ ${indent}`);
1582
+ else ms.appendLeft(last?.end ?? block.end, `
1583
+ ${code}`);
1584
+ }
1585
+ function shiftedPosition(position, delta) {
1586
+ return Math.max(0, Math.round((position + delta) * 1e3) / 1e3);
1587
+ }
1588
+ function timelineBlock(parsed) {
1589
+ const declaration = findTimelineDeclarationStatement(parsed.ast, parsed.timelineVar);
1590
+ let block = parsed.ast;
1591
+ if (declaration) {
1592
+ acornWalk2.ancestor(parsed.ast, {
1593
+ VariableDeclaration(node, _state, ancestors) {
1594
+ if (node === declaration) block = ancestors[ancestors.length - 2];
1595
+ }
1596
+ });
1597
+ }
1598
+ return Array.isArray(block?.body) ? block : parsed.ast;
1599
+ }
1600
+ function isLoopOrForEach(node) {
1601
+ return isLoopNode(node) || isForEachStatement(node) || node?.type === "DoWhileStatement";
1602
+ }
1535
1603
  function scalePositionsInScript(script, targetSelector, oldStart, oldDuration, newStart, newDuration) {
1536
1604
  if (oldDuration <= 0 || newDuration <= 0) return script;
1537
1605
  const ratio = newDuration / oldDuration;
@@ -2987,6 +3055,7 @@ export {
2987
3055
  addMotionPathPointInScript,
2988
3056
  addMotionPathToScript,
2989
3057
  convertToKeyframesFromScript,
3058
+ copyAnimationsInScript,
2990
3059
  dedupePositionWritesInScript,
2991
3060
  materializeKeyframesFromScript,
2992
3061
  moveKeyframeInScript,