MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / addKeyframeToScript

Function addKeyframeToScript

packages/parsers/src/gsapWriterAcorn.ts:1007–1056  ·  view source on GitHub ↗
(
  script: string,
  animationId: string,
  percentage: number,
  properties: Record<string, number | string>,
  ease?: string,
  backfillDefaults?: Record<string, number | string>,
)

Source from the content-addressed store, hash-verified

1005}
1006
1007export function addKeyframeToScript(
1008 script: string,
1009 animationId: string,
1010 percentage: number,
1011 properties: Record<string, number | string>,
1012 ease?: string,
1013 backfillDefaults?: Record<string, number | string>,
1014): string {
1015 const located = ensureKeyframesNode(script, animationId);
1016 if (!located) return script;
1017 const { script: src, kfNode } = located;
1018
1019 const existing = findKfPropByPct(kfNode, percentage);
1020
1021 // Final record for the target keyframe (merge if it already exists).
1022 const targetRecord = buildTargetRecord(existing, src, properties, ease);
1023 // `_auto` endpoint syncs fire only on new inserts; a merge landing ON an
1024 // endpoint already preserves `_auto` via buildTargetRecord.
1025 const endpointOverwrites = existing
1026 ? new Map<any, Record<string, number | string>>()
1027 : autoEndpointOverwrites(kfNode, src, percentage, properties);
1028 // Backfilled siblings (each node changes at most once).
1029 const backfillOverwrites = collectBackfillOverwrites(kfNode, src, properties, backfillDefaults, {
1030 existingProp: existing?.prop,
1031 endpoints: endpointOverwrites,
1032 });
1033
1034 // Emit exactly one overwrite per changed node, plus one insert for a new key.
1035 const ms = new MagicString(src);
1036 if (existing) {
1037 // Merge into the existing keyframe at this percentage, preserving sibling
1038 // properties — overwrite only the given keys. (A whole-value overwrite here
1039 // would silently drop other properties already keyframed at this percent.)
1040 if (existing.prop.value?.type === "ObjectExpression") {
1041 for (const [k, v] of Object.entries(properties)) {
1042 upsertProp(ms, existing.prop.value, k, v);
1043 }
1044 if (ease !== undefined) upsertProp(ms, existing.prop.value, "ease", ease);
1045 } else {
1046 ms.overwrite(existing.prop.value.start, existing.prop.value.end, recordToCode(targetRecord));
1047 }
1048 } else {
1049 insertNewKeyframe(ms, kfNode, percentage, `${percentage}%`, recordToCode(targetRecord));
1050 }
1051 for (const [prop, rec] of [...endpointOverwrites, ...backfillOverwrites]) {
1052 ms.overwrite(prop.value.start, prop.value.end, recordToCode(rec));
1053 }
1054
1055 return ms.toString();
1056}
1057
1058/** Insert a brand-new `"pct%": {...}` property in sorted order. */
1059function insertNewKeyframe(

Callers

nothing calls this directly

Calls 9

ensureKeyframesNodeFunction · 0.85
findKfPropByPctFunction · 0.85
buildTargetRecordFunction · 0.85
autoEndpointOverwritesFunction · 0.85
upsertPropFunction · 0.85
recordToCodeFunction · 0.85
insertNewKeyframeFunction · 0.85
entriesMethod · 0.80

Tested by

no test coverage detected