Files
hyperframes/packages/core
Miguel Ángel c1699ec98b feat(studio): runtime-first dynamic keyframe system [8/10] (#1190)
* feat(core): spring physics solver + runtime fixes + spring ease editor

* feat(core): spring physics solver + runtime fixes + spring ease editor

Revert totalTime nudge that caused black first frames in from() tweens.
Keep stale CSS offset cleanup. Regenerate baselines for offset cleanup.

* ci: trigger regression run

* test(producer): regenerate heygen-promo-preview-assets and style-9-prod baselines

Baselines regenerated inside Dockerfile.test on the devbox to match
the current runtime init.ts changes. Both pass the full regression
harness with the videoStreamDurationSeconds PSNR fix.

* feat(studio): design panel integration, timeline polish, feature flag

* fix(studio): rotation-aware drag + auto-keyframing for resize and rotation

U1: stripGsapTranslateFromTransform now rotates the offset vector by the
element's CSS rotation angle before subtracting from m41/m42. Fixes
elements drifting from cursor during drag when rotated.

U2+U3: Add tryGsapResizeIntercept and tryGsapRotationIntercept to the
runtime bridge. Resize and rotation handle changes now create keyframes
via the same async pipeline as position drag. CSS path guards prevent
double-persistence for GSAP-animated elements.

* fix(studio): counter-rotate drag offset for css-rotated elements

CSS compose order is translate → rotate → transform. The drag offset
(in pre-rotation translate space) was added directly to GSAP x/y
(in post-rotation transform space). Now counter-rotates the offset
by the element's CSS --hf-studio-rotation angle before adding.

* feat(studio): add 'delete all keyframes' to diamond context menu

* fix(studio): include all animated properties in every keyframe commit

Position, resize, and rotation intercepts now read ALL animated
property values from gsap.getProperty() at commit time and include
them in the keyframe. Prevents other properties from jumping to
interpolated values between surrounding keyframes when only one
property (e.g., width) was explicitly changed.

* feat(core): spring physics solver + runtime fixes + spring ease editor

* feat(core): spring physics solver + runtime fixes + spring ease editor

Revert totalTime nudge that caused black first frames in from() tweens.
Keep stale CSS offset cleanup. Regenerate baselines for offset cleanup.

* ci: trigger regression run

* feat(core): spring physics solver + runtime fixes + spring ease editor

* feat(core): spring physics solver + runtime fixes + spring ease editor

Revert totalTime nudge that caused black first frames in from() tweens.
Keep stale CSS offset cleanup. Regenerate baselines for offset cleanup.

* ci: trigger regression run

* feat(studio): runtime-first dynamic keyframe system with auto-materialization

Read GSAP keyframe data from the live runtime instead of only the AST parser.
Dynamic keyframes (loops, variables, computed selectors) now show diamonds
on timeline clips and animation cards in the design panel.

On first edit, dynamic code is automatically materialized:
- Unresolved keyframes (keyframes: kf) replaced with static object
- Unresolved selectors (tl.to(sel, ...)) entire loop unrolled into
  individual static tl.to() calls per element

Key changes:
- Parser: hasUnresolvedKeyframes/hasUnresolvedSelector flags
- Runtime bridge: scanAllRuntimeKeyframes reads tween.vars from iframe
- Tween cache: interval-based runtime scan for dynamic animations
- materializeKeyframesInScript + unrollDynamicAnimations parser functions
- Keyframe cache dual-writes both sourceFile#id and index.html#id keys
- commitMutation updates cache from mutation response
- easeEach placement fix (inside keyframes object, not tween vars)
2026-06-05 12:08:03 -04:00
..

@hyperframes/core

Types, parsers, generators, compiler, linter, runtime, and frame adapters for the Hyperframes video framework.

Install

npm install @hyperframes/core

Most users don't need to install core directly — the CLI, producer, and studio packages depend on it internally.

What's inside

Module Description
Types TimelineElement, CompositionSpec, Asset, canvas dimensions, defaults
Parsers parseHtml — extract timeline elements from HTML; parseGsapScript — parse GSAP animations
Generators generateHyperframesHtml — produce valid Hyperframes HTML from a composition spec
Compiler compileTimingAttrs — resolve data-start / data-duration into absolute times
Linter lintHyperframeHtml — validate Hyperframes HTML (missing attributes, overlapping tracks, etc.)
Runtime IIFE script injected into the browser — manages seek, media playback, and the window.__hf protocol
Frame Adapters Pluggable animation drivers (GSAP, Lottie, CSS, or custom)

Frame Adapters

A frame adapter tells the engine how to seek your animation to a specific frame:

import { createGSAPFrameAdapter } from "@hyperframes/core";

const adapter = createGSAPFrameAdapter({
  getTimeline: () => gsap.timeline(),
  compositionId: "my-video",
});

Implement FrameAdapter for custom animation runtimes:

import type { FrameAdapter } from "@hyperframes/core";

const myAdapter: FrameAdapter = {
  id: "my-adapter",
  getDurationFrames: () => 300,
  seekFrame: (frame) => {
    /* seek your animation */
  },
};

Parsing and generating HTML

import { parseHtml, generateHyperframesHtml } from "@hyperframes/core";

const { elements, metadata } = parseHtml(htmlString);
const html = generateHyperframesHtml(spec);

Linting

import { lintHyperframeHtml } from "@hyperframes/core/lint";

const result = lintHyperframeHtml(htmlString);
// result.findings: { severity, message, elementId }[]

Documentation

Full documentation: hyperframes.heygen.com/packages/core