Skip to content

feat(registry): add pendulum-swing component - #3764

Open
rottenpen wants to merge 1 commit into
heygen-com:mainfrom
rottenpen:feat/pendulum-swing-component
Open

feat(registry): add pendulum-swing component#3764
rottenpen wants to merge 1 commit into
heygen-com:mainfrom
rottenpen:feat/pendulum-swing-component

Conversation

@rottenpen

@rottenpen rottenpen commented Sep 8, 2026

Copy link
Copy Markdown

What

Add a new registry component, pendulum-swing: a motion primitive that hangs content from a fixed pivot and lets it settle with a damped oscillation, like a hanging sign coming to rest on its hook.

Why

The catalog has plenty of "arrive" primitives (slam, pop, slide, dissolve) but none that reads as a physical hanging object settling. pendulum-swing fills that gap with a small, composable primitive that pins a top edge and swings the content in.

How

  • Recipe-only snippet. pendulum-swing.html owns no timeline. It reads its variables, writes CSS custom props, and rotates about a transform-origin pinned to the pivot. All motion rides a single unitless custom property --hf-swing-angle that the host timeline eases 1 → 0, so only transform: rotate() animates — sub-pixel, no layout/reflow property, safe under the seek-by-frame capture engine.
  • Damped-oscillation ease. The demo drives the swing with 1 - exp(-2.3·p)·cos(3.5π·p) — a cosine (the swings) inside an exponential decay (the damping), normalised so the tween lands exactly upright. The sign passes through center several times, each pass smaller, before resting — a real pendulum settle rather than a single overshoot.
  • Four enum variables: pivot (top-center/left/right), amplitude (gentle/standard/wide), direction (right/left), tone (ink/paper/accent — each a bg/fg pair to keep AA contrast on any frame). Unrecognised overrides fall back to declared defaults.
  • Component manifest carries no dimensions/duration (per schema). The demo carries the same variable declaration as the snippet.

Preview

The sign swings right → left → right, each pass smaller, settling upright.

pendulum-swing.mp4

Test plan

  • npx hyperframes lint + npx hyperframes validate on both HTML files — clean (only ignore-level root_missing_* rules fire on the bare snippet, expected)
  • Demo validates 0 errors / 0 warnings
  • snippet == demo variable declaration parity verified
  • registry.json regenerated via scripts/generate-registry-items.ts (not hand-edited); catalogArtifact.revision untouched
  • Docs regenerated via scripts/generate-catalog-pages.ts (mdx + catalog-index.json + docs.json nav)
  • Rendered the demo locally via the demo's own GSAP timeline to confirm the motion
  • Unit tests — n/a (registry data + HTML, no package code changed)

Notes for maintainers (the two contributor-can't-finish steps)

Per CONTRIBUTING.md, these need assets an outside contributor isn't expected to install; neither blocks review:

  1. Search index (registry/catalog-artifact/local-vectors.*) — not regenerated here (needs the 32 MB on-device embedding model). The Catalog: search index covers the registry CI job will name the gap; it's a deterministic rebuild from this registry, so it's regenerated before merge. Until then the item is findable by word search, just not by meaning.
  2. Catalog preview image/MP4preview.poster in the manifest points at the conventional CDN path (static.heygen.ai/.../catalog/components/pendulum-swing.png); the actual asset is published by scripts/upload-docs-images.sh (HeyGen AWS creds), so a maintainer runs the official preview + upload before merge. The MP4 above is a local render for review.

Add a motion-primitive component that hangs content from a fixed pivot and
lets it settle with a damped oscillation, like a hanging sign coming to rest
on its hook.

The swing rides a single unitless custom property (--hf-swing-angle) that the
timeline eases 1 -> 0, so only rotation animates and it stays sub-pixel under
the seek-by-frame capture engine. The demo drives it with a damped-oscillation
ease (a cosine inside an exponential decay, normalised to land exactly upright)
so the sign passes through center several times, each pass smaller, before it
rests.

Four enum variables: pivot (top-center/left/right), amplitude
(gentle/standard/wide), direction (right/left), tone (ink/paper/accent, each a
bg/fg pair to keep AA contrast on any frame). The snippet is recipe-only and
does not own its timeline; its demo carries the same variable declaration.

Ran npx hyperframes lint/validate on both files, regenerated registry.json via
scripts/generate-registry-items.ts and the docs via
scripts/generate-catalog-pages.ts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant