open-design/prompt-templates/video/hyperframes-html-in-canvas-magnetic.json
Tom Huang e11e86d468
feat(hyperframes): land HTML-in-Canvas across web + skills (#866)
* feat(hyperframes): land HTML-in-Canvas across web + skills

Ships HTML-in-Canvas as a first-class HyperFrames video path:
- 7 new video prompt templates (liquid glass, iPhone+MacBook, portal,
  shatter, magnetic, liquid background, text-cursor reveal).
- skills/hyperframes/references/html-in-canvas.md, surfaced via
  SKILL.md description+triggers and the system-prompt pre-flight
  references list.
- ChatPane starter prompts now branch by project kind and video model,
  so the hyperframes-html surface shows HTML-in-canvas-shaped prompts
  instead of the generic prototype trio.
- NewProjectPanel propagates a picked template's model+aspect onto
  the project, and defaults videoModel to hyperframes-html when the
  hyperframes skill resolves for the video tab.

Polish bundled in the same branch:
- DesignFilesPanel empty state becomes a centered pill with a "New
  sketch" CTA; designFiles.empty copy simplified across 19 locales.
- Topbar project title + meta render on one baseline row separated
  by a middot.
- scripts/seed-test-projects.ts hardens daemon URL discovery against
  pnpm engine warnings on stdout.

* fix(new-project): preserve explicit video model choice across tab revisits

Latch a videoModelTouched guard once the user picks a model via the
dropdown or via a template that declares one, so the hyperframes-html
auto-default no longer silently overwrites the override when the Video
tab is re-entered.

Generated-By: looper 0.6.1 (runner=fixer, agent=claude-code)

* fix(i18n): register hyperframes html-in-canvas templates, category, and tags

Adds the seven new prompt-template ids, the "VFX / HTML-in-Canvas"
category, and the new tag set to the de/ru/fr i18n bundles so the
e2e localized-content coverage test passes.

Generated-By: looper 0.6.1 (runner=fixer, agent=claude-code)

* fix(daemon): inject html-in-canvas preflight for hyperframes runs

The contracts-side derivePreflight() learned about
references/html-in-canvas.md when this PR landed, but the daemon
copy at apps/daemon/src/prompts/system.ts kept the older five-ref
allowlist. server.ts:4138 wires composeSystemPrompt from the
daemon copy into live chat runs, so the main HyperFrames flow this
PR is meant to improve still wasn't auto-injecting the preflight
directive in production.

Mirror the html-in-canvas case into the daemon composer and lock it
behind a daemon-side test so the two copies cannot drift again on
this reference. The broader live-artifact preflight gap (artifact-
schema / connector-policy / refresh-contract) is pre-existing drift
and is intentionally out of scope here.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): restyle designs empty state as centered card on grid backdrop

Swap the horizontal pill for a stacked card and add a faint grid backdrop
so the empty designs surface reads as an intentional canvas rather than a
gap. Title now wraps instead of truncating; container is taller.

* fix(new-project): pin skillId to hyperframes when videoModel is hyperframes-html

When the Video tab resolves its skill it used to fall back to `list[0]?.id`
if no skill declared `default_for: video`. That list is built from an
unsorted `readdir()` in apps/daemon/src/skills.ts, so a freshly mounted
project could land on `video-shortform` even when the user had explicitly
chosen the HyperFrames-HTML model (or one of the new
`hyperframes-html-in-canvas-*` templates). The agent then ran without the
hyperframes SKILL body or its `references/html-in-canvas.md` preflight —
the exact regression PR #866 was meant to land.

`skillIdForTab` now pins to `hyperframes` whenever the current video model
is `hyperframes-html`, regardless of discovery order. Added a unit test
that mounts both `video-shortform` and `hyperframes` (with hyperframes
last, simulating the bad readdir order) and asserts the create payload
routes through `hyperframes`.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 15:45:12 +08:00

19 lines
4.2 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"id": "hyperframes-html-in-canvas-magnetic",
"surface": "video",
"title": "HyperFrames HTML-in-Canvas: Magnetic Field Visualisation",
"summary": "A 15-second magnetic-field particle visualisation reacting to a live DOM heatmap or chart — particles trace field lines that bend around the captured HTML, ideal for ML/data products. Built on the vfx-magnetic catalog block.",
"category": "VFX / HTML-in-Canvas",
"tags": ["hyperframes", "html-in-canvas", "magnetic", "particles", "data"],
"model": "hyperframes-html",
"aspect": "16:9",
"prompt": "Build a 15-second HyperFrames composition (1920×1080, 30fps) titled \"magnetic-field-data\". Pull the catalog block first: `npx hyperframes add vfx-magnetic`.\n\nVisual identity: graphite canvas #0a0c11, single primary particle color #ff6a00 with a cool secondary #38e6ff for opposing-pole particles, off-white text #eef2f7. Display face: \"PP Neue Machina\" 124px Plain Ultrabold; body \"PP Mondwest\" Regular 24px; mono \"Berkeley Mono\" 18px on labels. Tabular-nums on every numeral.\n\nLayer A — `field-source`: a `<canvas layoutsubtree width=\"1920\" height=\"1080\">` containing real DOM that drives the magnetic field — a centered chart card (760×520px) with a live SVG line chart (12 data points, animated path), two KPI labels above (\"signal strength\" 0.84 and \"coverage\" 92%), and a small mono caption beneath (\"polling 412 nodes · realtime\"). The chart card acts as the magnetic source — particles repel from its bounds, attract toward dipole anchors at the chart's two endpoints.\n\nLayer B — `theater`: WebGL canvas running the vfx-magnetic shader. Particle count 1800, deterministic spawn seeded mulberry32(91347), spawn distribution rim-biased so the field lines read clearly. Two opposing dipoles at the chart's first and last data points sample the captured DOM bounds every frame so the field re-flows when the chart line animates.\n\nTimeline (paused: true, window.__timelines.main, data-duration=15):\n\n0.02.4s ENTRY — particles spawn invisible, opacity ramps 0 → 0.85 over 2.0s ease expo.out. Field strength 0 → 1.0 ease power3.out 1.6s. Chart card fades in at 0.4s (`gsap.from('.chart-card', { y: 60, opacity: 0, scale: 0.96, duration: 0.9, ease: 'power3.out' })`). KPI labels stagger in at 0.9s and 1.2s (200ms apart, y:30 → 0).\n\n2.410.0s FLOW — particles trace field lines. Chart line animates over 6.0s (`gsap.from('.chart-line', { strokeDashoffset: pathLength, duration: 6.0, ease: 'sine.inOut' })`); the captured-DOM resampling means particles bend around the moving chart line in real time. KPI numerals tick: signal strength 0.84 → 0.91, coverage 92% → 96%, both ease none. At 6.0s, brief field-strength pulse from 1.0 → 1.4 → 1.0 over 0.5s; particles speed up correspondingly.\n\n10.013.5s STATEMENT — headline appears (\"see the field, not the dots\") with marker-sweep highlight from `references/css-patterns.md` at 10.4s. Particles dim slightly (opacity 0.85 → 0.55) so the headline reads cleanly above them.\n\n13.515.0s SETTLE — field strength tapers 1.0 → 0.6, particle speed halves, ambient drift only. Final 0.6s holds the hero frame. No opacity-to-0 exits.\n\nFeature detection: if `drawElementImage` is unavailable, render the chart card DOM directly on a flat #0a0c11 background without the particle field. Studio preview must never go black.\n\nNon-negotiables: deterministic seeds, finite repeats only, no Math.random / Date.now, no `<br>` in headline (let it wrap with `max-width`). Particle position update runs inside the same window.__timelines.main timeline ticker — don't spin off requestAnimationFrame outside the framework's clock. Run `npx hyperframes lint` and `npx hyperframes inspect --samples 12 --at 1,2.5,4,6,8,11,13.5` before render. Output: `magnetic-field-data.mp4`.",
"previewImageUrl": "https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/vfx-magnetic.png",
"previewVideoUrl": "https://static.heygen.ai/hyperframes-oss/docs/images/catalog/blocks/vfx-magnetic.mp4",
"source": {
"repo": "heygen-com/hyperframes",
"license": "Apache-2.0",
"author": "HeyGen",
"url": "https://hyperframes.heygen.com/catalog/blocks/vfx-magnetic"
}
}