Skip to content

Commit b0f754a

Browse files
authored
feat(registry): seed components — grain-overlay, shimmer-sweep, grid-pixelate-wipe (heygen-com#260)
## What Three reusable effect components for the registry, each with a snippet HTML and companion `demo.html`: | Component | Description | |-----------|-------------| | `grain-overlay` | Animated film grain texture overlay (CSS keyframes, extracted from warm-grain example) | | `shimmer-sweep` | CSS gradient light sweep across text/elements, driven by GSAP custom property animation | | `grid-pixelate-wipe` | Grid-based dissolve transition — screen breaks into 16×9 squares that scale in/out with stagger | Establishes the `demo.html` convention in `CONTRIBUTING.md`. ## Why Phase B of the catalog plan — seed the first components in the registry. Components are effect snippets that get merged into existing compositions (vs. blocks which are standalone sub-compositions). ## How - **grain-overlay**: Extracted the grain texture pattern from the warm-grain example. Uses a 200% oversized tiled texture with `steps(1)` keyframe animation for the random-noise effect. - **shimmer-sweep**: Original implementation using CSS custom properties (`--shimmer-pos`) animated by GSAP. The gradient mask uses `mix-blend-mode: overlay` for a natural light sweep. Auto-injects `.shimmer-mask` elements into `.shimmer-sweep-target` wrappers. - **grid-pixelate-wipe**: Creates a 16×9 CSS Grid of cells, animated with GSAP stagger. Users drive `.grid-cell` `scale` directly in their timeline. Simplify review addressed: scoped `.grain-texture` under `#grain-overlay`, scoped `.grid-cell` under `#grid-pixelate-overlay`, removed `window.gridPixelateIn/Out` globals in favor of direct GSAP patterns. Each component ships a `demo.html` — a standalone composition that previews the effect and doubles as a fixture for the CI preview pipeline (PR 8). ## Test plan - [x] `hyperframes add grain-overlay` installs to `compositions/components/grain-overlay.html` - [x] `hyperframes add shimmer-sweep` installs to `compositions/components/shimmer-sweep.html` - [x] `hyperframes add grid-pixelate-wipe` installs to `compositions/components/grid-pixelate-wipe.html` - [x] All three return correct `--json` output with snippet and type info - [x] `registry-item.json` files validate against the JSON Schema - [x] `demo.html` files are self-contained with correct `data-composition-id` and `window.__timelines` registration - [x] `oxfmt --check` and `oxlint` pass on all files - [x] `CONTRIBUTING.md` documents the `demo.html` convention and registry item checklist
1 parent 4685e5c commit b0f754a

11 files changed

Lines changed: 811 additions & 0 deletions

File tree

CONTRIBUTING.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,42 @@ If you must add a cast, add a comment:
6161
const event = data as unknown as RuntimeEvent;
6262
```
6363

64+
## Adding Registry Items (Blocks & Components)
65+
66+
The registry at `registry/` contains reusable items installable via `hyperframes add <name>`. Each item lives in its own directory under `registry/blocks/` or `registry/components/`.
67+
68+
### Directory structure
69+
70+
```
71+
registry/blocks/<name>/
72+
registry-item.json # Manifest (name, type, description, tags, files)
73+
<name>.html # The composition HTML
74+
75+
registry/components/<name>/
76+
registry-item.json # Manifest (no dimensions/duration for components)
77+
<name>.html # The snippet HTML to paste into a composition
78+
demo.html # Required — standalone demo showing the effect
79+
```
80+
81+
### The `demo.html` convention
82+
83+
Every **component** must ship a companion `demo.html`. This file:
84+
85+
1. Is a complete, standalone HTML document (with `<!doctype html>`, GSAP CDN, etc.)
86+
2. Shows the component effect applied to representative content
87+
3. Registers a GSAP timeline on `window.__timelines` so it can be previewed in the Studio and rendered by the CI preview pipeline
88+
4. Uses `data-composition-id="<name>-demo"` to avoid ID collisions
89+
90+
Blocks don't need `demo.html` — they are already standalone compositions.
91+
92+
### Checklist for new items
93+
94+
1. Create `registry/<blocks|components>/<name>/registry-item.json` following the [schema](packages/core/schemas/registry-item.json)
95+
2. Add the item to `registry/registry.json`
96+
3. For components: include a `demo.html`
97+
4. Run `npx hyperframes lint` and `npx hyperframes validate` on your HTML
98+
5. Test the install flow: `hyperframes add <name> --dir /tmp/test-project`
99+
64100
## Pull Requests
65101

66102
- Use [conventional commit](https://www.conventionalcommits.org/) format for **all commits** (e.g., `feat: add timeline export`, `fix: resolve seek overflow`). Enforced by a git hook.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=1920, height=1080" />
6+
<title>Grain Overlay — Demo</title>
7+
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8+
<style>
9+
* {
10+
margin: 0;
11+
padding: 0;
12+
box-sizing: border-box;
13+
}
14+
html,
15+
body {
16+
margin: 0;
17+
width: 1920px;
18+
height: 1080px;
19+
overflow: hidden;
20+
}
21+
</style>
22+
</head>
23+
<body>
24+
<div
25+
id="demo"
26+
data-composition-id="grain-overlay-demo"
27+
data-width="1920"
28+
data-height="1080"
29+
data-duration="5"
30+
>
31+
<!-- Background content to demonstrate the overlay -->
32+
<div
33+
class="demo-bg"
34+
style="
35+
width: 1920px;
36+
height: 1080px;
37+
background: linear-gradient(135deg, #f5f0e0 0%, #e8d8b8 50%, #d4c4a0 100%);
38+
display: flex;
39+
justify-content: center;
40+
align-items: center;
41+
font-family: &quot;Inter&quot;, sans-serif;
42+
position: relative;
43+
"
44+
>
45+
<div style="text-align: center; z-index: 1">
46+
<div
47+
class="demo-title"
48+
style="font-size: 80px; font-weight: 700; color: #2c1e16; opacity: 0"
49+
>
50+
Grain Overlay
51+
</div>
52+
<div
53+
class="demo-subtitle"
54+
style="font-size: 32px; color: #5a4a3a; margin-top: 20px; opacity: 0"
55+
>
56+
Adds warmth and analog character
57+
</div>
58+
</div>
59+
</div>
60+
61+
<!-- The grain overlay component -->
62+
<div
63+
id="grain-overlay"
64+
style="
65+
position: absolute;
66+
top: 0;
67+
left: 0;
68+
width: 100%;
69+
height: 100%;
70+
pointer-events: none;
71+
z-index: 100;
72+
"
73+
>
74+
<div class="grain-texture"></div>
75+
</div>
76+
77+
<style>
78+
@keyframes grain-noise {
79+
0%,
80+
100% {
81+
transform: translate(0, 0);
82+
}
83+
10% {
84+
transform: translate(-5%, -5%);
85+
}
86+
20% {
87+
transform: translate(-10%, 5%);
88+
}
89+
30% {
90+
transform: translate(5%, -10%);
91+
}
92+
40% {
93+
transform: translate(-5%, 15%);
94+
}
95+
50% {
96+
transform: translate(-10%, 5%);
97+
}
98+
60% {
99+
transform: translate(15%, 0);
100+
}
101+
70% {
102+
transform: translate(0, 10%);
103+
}
104+
80% {
105+
transform: translate(-15%, 0);
106+
}
107+
90% {
108+
transform: translate(10%, 5%);
109+
}
110+
}
111+
112+
#grain-overlay .grain-texture {
113+
position: absolute;
114+
top: -50%;
115+
left: -50%;
116+
width: 200%;
117+
height: 200%;
118+
background: url("https://www.transparenttextures.com/patterns/natural-paper.png");
119+
opacity: 0.15;
120+
animation: grain-noise 0.5s steps(1) infinite;
121+
}
122+
</style>
123+
124+
<script>
125+
(function () {
126+
const tl = gsap.timeline({ paused: true });
127+
128+
tl.to(
129+
".demo-title",
130+
{
131+
opacity: 1,
132+
y: -10,
133+
duration: 1,
134+
ease: "power3.out",
135+
},
136+
0.5,
137+
);
138+
139+
tl.to(
140+
".demo-subtitle",
141+
{
142+
opacity: 1,
143+
y: -5,
144+
duration: 0.8,
145+
ease: "power3.out",
146+
},
147+
1.0,
148+
);
149+
150+
window.__timelines = window.__timelines || {};
151+
window.__timelines["grain-overlay-demo"] = tl;
152+
})();
153+
</script>
154+
</div>
155+
</body>
156+
</html>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<!--
2+
Grain Overlay — animated film grain texture.
3+
4+
Usage: paste this snippet into your composition's HTML.
5+
The overlay covers the full viewport with pointer-events: none
6+
so it sits on top of all content without blocking interaction.
7+
8+
Customize:
9+
- opacity: adjust .grain-texture opacity (default 0.15)
10+
- speed: change animation duration (default 0.5s)
11+
- texture: swap the background URL for a different pattern
12+
- z-index: adjust #grain-overlay z-index to layer correctly
13+
-->
14+
15+
<div
16+
id="grain-overlay"
17+
style="
18+
position: absolute;
19+
top: 0;
20+
left: 0;
21+
width: 100%;
22+
height: 100%;
23+
pointer-events: none;
24+
z-index: 100;
25+
"
26+
>
27+
<div class="grain-texture"></div>
28+
</div>
29+
30+
<style>
31+
@keyframes grain-noise {
32+
0%,
33+
100% {
34+
transform: translate(0, 0);
35+
}
36+
10% {
37+
transform: translate(-5%, -5%);
38+
}
39+
20% {
40+
transform: translate(-10%, 5%);
41+
}
42+
30% {
43+
transform: translate(5%, -10%);
44+
}
45+
40% {
46+
transform: translate(-5%, 15%);
47+
}
48+
50% {
49+
transform: translate(-10%, 5%);
50+
}
51+
60% {
52+
transform: translate(15%, 0);
53+
}
54+
70% {
55+
transform: translate(0, 10%);
56+
}
57+
80% {
58+
transform: translate(-15%, 0);
59+
}
60+
90% {
61+
transform: translate(10%, 5%);
62+
}
63+
}
64+
65+
#grain-overlay .grain-texture {
66+
position: absolute;
67+
top: -50%;
68+
left: -50%;
69+
width: 200%;
70+
height: 200%;
71+
background: url("https://www.transparenttextures.com/patterns/natural-paper.png");
72+
opacity: 0.15;
73+
animation: grain-noise 0.5s steps(1) infinite;
74+
}
75+
</style>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"$schema": "https://hyperframes.heygen.com/schema/registry-item.json",
3+
"name": "grain-overlay",
4+
"type": "hyperframes:component",
5+
"title": "Grain Overlay",
6+
"description": "Animated film grain texture overlay using CSS keyframes — adds warmth and analog character to any composition",
7+
"tags": ["texture", "grain", "overlay", "film"],
8+
"files": [
9+
{
10+
"path": "grain-overlay.html",
11+
"target": "compositions/components/grain-overlay.html",
12+
"type": "hyperframes:snippet"
13+
}
14+
]
15+
}

0 commit comments

Comments
 (0)