hyperframes 0.2.2 → 0.2.3-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +8651 -7892
- package/dist/docker/Dockerfile.render +33 -0
- package/dist/hyperframe-runtime.js +5 -5
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +5 -5
- package/dist/skills/gsap/SKILL.md +222 -0
- package/dist/skills/gsap/references/effects.md +304 -0
- package/dist/skills/gsap/references/frameworks.md +56 -0
- package/dist/skills/gsap/references/plugins.md +194 -0
- package/dist/skills/gsap/references/react.md +80 -0
- package/dist/skills/gsap/references/scrolltrigger.md +147 -0
- package/dist/skills/gsap/references/utils.md +91 -0
- package/dist/skills/gsap/scripts/extract-audio-data.py +188 -0
- package/dist/skills/hyperframes/SKILL.md +175 -0
- package/dist/skills/hyperframes/references/audio-reactive.md +76 -0
- package/dist/skills/hyperframes/references/captions.md +132 -0
- package/dist/skills/hyperframes/references/css-patterns.md +371 -0
- package/dist/skills/hyperframes/references/examples.md +146 -0
- package/dist/skills/hyperframes/references/marker-highlight.md +158 -0
- package/dist/skills/hyperframes/references/transitions/catalog.md +132 -0
- package/dist/skills/hyperframes/references/transitions/css-3d.md +12 -0
- package/dist/skills/hyperframes/references/transitions/css-blur.md +51 -0
- package/dist/skills/hyperframes/references/transitions/css-cover.md +43 -0
- package/dist/skills/hyperframes/references/transitions/css-destruction.md +95 -0
- package/dist/skills/hyperframes/references/transitions/css-dissolve.md +66 -0
- package/dist/skills/hyperframes/references/transitions/css-distortion.md +45 -0
- package/dist/skills/hyperframes/references/transitions/css-grid.md +10 -0
- package/dist/skills/hyperframes/references/transitions/css-light.md +49 -0
- package/dist/skills/hyperframes/references/transitions/css-mechanical.md +30 -0
- package/dist/skills/hyperframes/references/transitions/css-other.md +36 -0
- package/dist/skills/hyperframes/references/transitions/css-push.md +41 -0
- package/dist/skills/hyperframes/references/transitions/css-radial.md +37 -0
- package/dist/skills/hyperframes/references/transitions/css-scale.md +24 -0
- package/dist/skills/hyperframes/references/transitions/shader-setup.md +463 -0
- package/dist/skills/hyperframes/references/transitions/shader-transitions.md +329 -0
- package/dist/skills/hyperframes/references/transitions.md +96 -0
- package/dist/skills/hyperframes/references/tts.md +56 -0
- package/dist/skills/hyperframes-cli/SKILL.md +114 -0
- package/dist/studio/assets/{index-DA_l-VKo.js → index-B0VCLOXQ.js} +15 -15
- package/dist/studio/index.html +1 -1
- package/dist/templates/_shared/CLAUDE.md +5 -7
- package/dist/templates/blank/index.html +8 -10
- package/package.json +2 -4
- package/dist/skills/hyperframes-captions/SKILL.md +0 -212
- package/dist/skills/hyperframes-compose/SKILL.md +0 -155
- package/dist/skills/hyperframes-tts/SKILL.md +0 -79
- package/dist/templates/blank/compositions/captions.html +0 -95
- /package/dist/skills/{hyperframes-compose → hyperframes}/data-in-motion.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/house-style.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/bold-energetic.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/clean-corporate.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/dark-premium.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/jewel-rich.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/monochrome.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/nature-earth.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/neon-electric.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/pastel-soft.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/palettes/warm-editorial.md +0 -0
- /package/dist/skills/{hyperframes-compose → hyperframes}/patterns.md +0 -0
- /package/dist/skills/{hyperframes-captions → hyperframes/references}/dynamic-techniques.md +0 -0
- /package/dist/skills/{hyperframes-captions → hyperframes/references}/transcript-guide.md +0 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# Shader Transition Fragment Shaders
|
|
2
|
+
|
|
3
|
+
Each shader below is just the GLSL fragment body. Plug it into `mkProg(H + NQ + "...")` using the setup from [shader-setup.md](./shader-setup.md).
|
|
4
|
+
|
|
5
|
+
### Domain Warp Dissolve
|
|
6
|
+
|
|
7
|
+
Cascaded `fbm(p + fbm(p))` — both scenes displace along the warp field in opposite directions. Iridescent cosine palette edge glow.
|
|
8
|
+
|
|
9
|
+
```glsl
|
|
10
|
+
// Requires: NQ + CP
|
|
11
|
+
void main() {
|
|
12
|
+
vec2 q = vec2(fbm(v_uv * 3.), fbm(v_uv * 3. + vec2(5.2, 1.3)));
|
|
13
|
+
vec2 r = vec2(fbm(v_uv * 3. + q * 4. + vec2(1.7, 9.2)),
|
|
14
|
+
fbm(v_uv * 3. + q * 4. + vec2(8.3, 2.8)));
|
|
15
|
+
float n = fbm(v_uv * 3. + r * 2.);
|
|
16
|
+
vec2 warpDir = (q - .5) * .4;
|
|
17
|
+
vec4 A = texture2D(u_from, clamp(v_uv + warpDir * u_progress, 0., 1.));
|
|
18
|
+
vec4 B = texture2D(u_to, clamp(v_uv - warpDir * (1. - u_progress), 0., 1.));
|
|
19
|
+
float e = smoothstep(u_progress - .08, u_progress + .08, n);
|
|
20
|
+
float ed = abs(n - u_progress);
|
|
21
|
+
float em = smoothstep(.1, 0., ed) * (1. - step(1., u_progress));
|
|
22
|
+
vec3 ec = palette(ed * 8., vec3(.5), vec3(.5), vec3(1.), vec3(0., .33, .67));
|
|
23
|
+
gl_FragColor = vec4(mix(B, A, e).rgb + ec * em * 2., 1.);
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Ridged Burn
|
|
28
|
+
|
|
29
|
+
`abs(noise)` creates sharp lightning-crack edges. Blackbody color gradient (dark red → orange → yellow → white) + high-frequency ember sparks near the edge.
|
|
30
|
+
|
|
31
|
+
```glsl
|
|
32
|
+
// Requires: NQ
|
|
33
|
+
float ridged(vec2 p) {
|
|
34
|
+
float v = 0., a = .5;
|
|
35
|
+
mat2 R = mat2(.8, .6, -.6, .8);
|
|
36
|
+
for (int i = 0; i < 5; i++) {
|
|
37
|
+
v += a * abs(vnoise(p) * 2. - 1.);
|
|
38
|
+
p = R * p * 2.02; a *= .5;
|
|
39
|
+
}
|
|
40
|
+
return v;
|
|
41
|
+
}
|
|
42
|
+
void main() {
|
|
43
|
+
vec4 A = texture2D(u_from, v_uv), B = texture2D(u_to, v_uv);
|
|
44
|
+
float n = ridged(v_uv * 4.);
|
|
45
|
+
float e = smoothstep(u_progress - .04, u_progress + .04, n);
|
|
46
|
+
float heat = smoothstep(.12, 0., abs(n - u_progress)) * (1. - step(1., u_progress));
|
|
47
|
+
vec3 burn = mix(vec3(.4, 0, 0), vec3(1, .4, 0), smoothstep(0., .25, heat));
|
|
48
|
+
burn = mix(burn, vec3(1, .85, .3), smoothstep(.25, .5, heat));
|
|
49
|
+
burn = mix(burn, vec3(1), smoothstep(.5, 1., heat));
|
|
50
|
+
float sparks = step(.92, vnoise(v_uv * 80.)) * heat * 3.;
|
|
51
|
+
gl_FragColor = vec4(mix(B, A, e).rgb + burn * heat * 3.5
|
|
52
|
+
+ vec3(1., .7, .3) * sparks, 1.);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Whip Pan
|
|
57
|
+
|
|
58
|
+
Both scenes slide horizontally in opposite directions with 10-sample directional motion blur. No noise needed.
|
|
59
|
+
|
|
60
|
+
```glsl
|
|
61
|
+
void main() {
|
|
62
|
+
float fromOff = u_progress * 1.5;
|
|
63
|
+
vec3 fromC = vec3(0.);
|
|
64
|
+
for (int i = 0; i < 10; i++) {
|
|
65
|
+
float f = float(i) / 10.;
|
|
66
|
+
vec2 fuv = vec2(v_uv.x + fromOff + u_progress * .08 * f, v_uv.y);
|
|
67
|
+
fromC += texture2D(u_from, clamp(fuv, 0., 1.)).rgb;
|
|
68
|
+
}
|
|
69
|
+
fromC /= 10.;
|
|
70
|
+
float toOff = (1. - u_progress) * 1.5;
|
|
71
|
+
vec3 toC = vec3(0.);
|
|
72
|
+
for (int i = 0; i < 10; i++) {
|
|
73
|
+
float f = float(i) / 10.;
|
|
74
|
+
vec2 tuv = vec2(v_uv.x - toOff - (1. - u_progress) * .08 * f, v_uv.y);
|
|
75
|
+
toC += texture2D(u_to, clamp(tuv, 0., 1.)).rgb;
|
|
76
|
+
}
|
|
77
|
+
toC /= 10.;
|
|
78
|
+
gl_FragColor = vec4(mix(fromC, toC, u_progress), 1.);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### SDF Iris
|
|
83
|
+
|
|
84
|
+
Aspect-corrected circle SDF opening from center. Triple onion ring glow.
|
|
85
|
+
|
|
86
|
+
```glsl
|
|
87
|
+
void main() {
|
|
88
|
+
vec4 A = texture2D(u_from, v_uv), B = texture2D(u_to, v_uv);
|
|
89
|
+
vec2 uv = (v_uv - .5) * vec2(u_resolution.x / u_resolution.y, 1.);
|
|
90
|
+
float d = length(uv);
|
|
91
|
+
float radius = u_progress * 1.2;
|
|
92
|
+
float fw = .003;
|
|
93
|
+
float edge = smoothstep(radius + fw, radius - fw, d);
|
|
94
|
+
float ring1 = exp(-abs(d - radius) * 25.);
|
|
95
|
+
float ring2 = exp(-abs(d - radius + .04) * 20.) * .5;
|
|
96
|
+
float ring3 = exp(-abs(d - radius + .08) * 15.) * .25;
|
|
97
|
+
float glow = (ring1 + ring2 + ring3) * u_progress * (1. - u_progress) * 4.;
|
|
98
|
+
gl_FragColor = vec4(mix(A, B, edge).rgb + vec3(1., .85, .6) * glow * .6, 1.);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Ripple Waves
|
|
103
|
+
|
|
104
|
+
Exponential sine waves (`exp(sin(x)-1)`) — sharp crests, broad troughs. Both scenes ripple in opposite phases.
|
|
105
|
+
|
|
106
|
+
```glsl
|
|
107
|
+
void main() {
|
|
108
|
+
vec2 uv = v_uv - .5;
|
|
109
|
+
float dist = length(uv);
|
|
110
|
+
vec2 dir = normalize(uv + .001);
|
|
111
|
+
float fromAmp = u_progress * .04;
|
|
112
|
+
float fw1 = exp(sin(dist * 25. - u_progress * 12.) - 1.);
|
|
113
|
+
float fw2 = exp(sin(dist * 50. - u_progress * 18.) - 1.) * .5;
|
|
114
|
+
vec2 fromUv = clamp(v_uv + dir * (fw1 + fw2) * fromAmp, 0., 1.);
|
|
115
|
+
float toAmp = (1. - u_progress) * .04;
|
|
116
|
+
float tw1 = exp(sin(dist * 25. + u_progress * 12.) - 1.);
|
|
117
|
+
float tw2 = exp(sin(dist * 50. + u_progress * 18.) - 1.) * .5;
|
|
118
|
+
vec2 toUv = clamp(v_uv - dir * (tw1 + tw2) * toAmp, 0., 1.);
|
|
119
|
+
vec4 A = texture2D(u_from, fromUv);
|
|
120
|
+
vec4 B = texture2D(u_to, toUv);
|
|
121
|
+
float peak = fw1 * u_progress;
|
|
122
|
+
vec3 tint = vec3(.9, .95, 1.) * peak * .1;
|
|
123
|
+
gl_FragColor = vec4(mix(A.rgb + tint, B.rgb, u_progress), 1.);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Gravitational Lens
|
|
128
|
+
|
|
129
|
+
Content warps toward gravity well with chromatic aberration + event horizon darkening. Pull is monotonic — never reverses.
|
|
130
|
+
|
|
131
|
+
```glsl
|
|
132
|
+
void main() {
|
|
133
|
+
vec4 B = texture2D(u_to, v_uv);
|
|
134
|
+
vec2 uv = v_uv - .5;
|
|
135
|
+
float dist = length(uv);
|
|
136
|
+
float pull = u_progress * 2.;
|
|
137
|
+
float warpStr = pull * .3 / (dist + .1);
|
|
138
|
+
vec2 warped = clamp(v_uv - uv * warpStr, 0., 1.);
|
|
139
|
+
vec4 A = texture2D(u_from, warped);
|
|
140
|
+
float horizon = smoothstep(0., .3, dist / (1. - u_progress * .85 + .001));
|
|
141
|
+
float shift = pull * .02 / (dist + .2);
|
|
142
|
+
float r = texture2D(u_from, clamp(v_uv - uv * (warpStr + shift), 0., 1.)).r;
|
|
143
|
+
float b = texture2D(u_from, clamp(v_uv - uv * (warpStr - shift), 0., 1.)).b;
|
|
144
|
+
vec3 lensed = vec3(r, A.g, b) * horizon;
|
|
145
|
+
gl_FragColor = vec4(mix(lensed, B.rgb, smoothstep(.3, .9, u_progress)), 1.);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Cinematic Zoom
|
|
150
|
+
|
|
151
|
+
Both scenes zoom-blur in opposite directions with per-channel radial offset (chromatic aberration). From zooms outward, to zooms inward from tight.
|
|
152
|
+
|
|
153
|
+
```glsl
|
|
154
|
+
void main() {
|
|
155
|
+
vec2 d = v_uv - vec2(.5);
|
|
156
|
+
float fromS = u_progress * .08;
|
|
157
|
+
float toS = (1. - u_progress) * .06;
|
|
158
|
+
float fr = 0., fg = 0., fb = 0.;
|
|
159
|
+
for (int i = 0; i < 12; i++) {
|
|
160
|
+
float f = float(i) / 12.;
|
|
161
|
+
fr += texture2D(u_from, v_uv - d * (fromS * 1.06) * f).r;
|
|
162
|
+
fg += texture2D(u_from, v_uv - d * fromS * f).g;
|
|
163
|
+
fb += texture2D(u_from, v_uv - d * (fromS * .94) * f).b;
|
|
164
|
+
}
|
|
165
|
+
vec3 fromBl = vec3(fr, fg, fb) / 12.;
|
|
166
|
+
float tr = 0., tg = 0., tb = 0.;
|
|
167
|
+
for (int i = 0; i < 12; i++) {
|
|
168
|
+
float f = float(i) / 12.;
|
|
169
|
+
tr += texture2D(u_to, v_uv + d * (toS * 1.06) * f).r;
|
|
170
|
+
tg += texture2D(u_to, v_uv + d * toS * f).g;
|
|
171
|
+
tb += texture2D(u_to, v_uv + d * (toS * .94) * f).b;
|
|
172
|
+
}
|
|
173
|
+
vec3 toBl = vec3(tr, tg, tb) / 12.;
|
|
174
|
+
gl_FragColor = vec4(mix(fromBl, toBl, u_progress), 1.);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Chromatic Radial Split
|
|
179
|
+
|
|
180
|
+
Both scenes' RGB channels separate/converge radially. From-scene splits outward, to-scene converges inward.
|
|
181
|
+
|
|
182
|
+
```glsl
|
|
183
|
+
void main() {
|
|
184
|
+
vec2 c = v_uv - .5;
|
|
185
|
+
float fromShift = u_progress * .06;
|
|
186
|
+
float fr = texture2D(u_from, clamp(v_uv + c * fromShift, 0., 1.)).r;
|
|
187
|
+
float fg = texture2D(u_from, v_uv).g;
|
|
188
|
+
float fb = texture2D(u_from, clamp(v_uv - c * fromShift, 0., 1.)).b;
|
|
189
|
+
vec3 fromSplit = vec3(fr, fg, fb);
|
|
190
|
+
float toShift = (1. - u_progress) * .06;
|
|
191
|
+
float tr = texture2D(u_to, clamp(v_uv - c * toShift, 0., 1.)).r;
|
|
192
|
+
float tg = texture2D(u_to, v_uv).g;
|
|
193
|
+
float tb = texture2D(u_to, clamp(v_uv + c * toShift, 0., 1.)).b;
|
|
194
|
+
vec3 toSplit = vec3(tr, tg, tb);
|
|
195
|
+
gl_FragColor = vec4(mix(fromSplit, toSplit, u_progress), 1.);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Glitch (shader)
|
|
200
|
+
|
|
201
|
+
Scan lines + block scramble + chromatic aberration + brightness flicker + color posterization. More aggressive than the CSS glitch.
|
|
202
|
+
|
|
203
|
+
```glsl
|
|
204
|
+
float rand(vec2 co) {
|
|
205
|
+
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
|
|
206
|
+
}
|
|
207
|
+
void main() {
|
|
208
|
+
float inten = u_progress * (1. - u_progress) * 4.;
|
|
209
|
+
float lineY = floor(v_uv.y * 60.) / 60.;
|
|
210
|
+
float lineDisp = (rand(vec2(lineY, floor(u_progress * 17.))) - .5) * .18 * inten;
|
|
211
|
+
vec2 block = floor(v_uv * vec2(12., 8.));
|
|
212
|
+
float br = rand(block + vec2(floor(u_progress * 11.)));
|
|
213
|
+
float ba = step(.83, br) * inten;
|
|
214
|
+
vec2 bd = (vec2(rand(block * 2.1), rand(block * 3.7)) - .5) * .35 * ba;
|
|
215
|
+
vec2 uv = clamp(v_uv + vec2(lineDisp, 0.) + bd, 0., 1.);
|
|
216
|
+
float shift = inten * .035;
|
|
217
|
+
float r = texture2D(u_from, uv + vec2(shift, 0.)).r;
|
|
218
|
+
float g = texture2D(u_from, uv).g;
|
|
219
|
+
float b = texture2D(u_from, uv - vec2(shift, 0.)).b;
|
|
220
|
+
vec3 col = vec3(r, g, b);
|
|
221
|
+
col -= step(.5, fract(v_uv.y * u_resolution.y * .5)) * .05 * inten;
|
|
222
|
+
col *= 1. + (rand(vec2(floor(u_progress * 23.))) - .5) * .3 * inten;
|
|
223
|
+
float levels = mix(256., 8., inten * .5);
|
|
224
|
+
col = floor(col * levels) / levels;
|
|
225
|
+
gl_FragColor = mix(vec4(col, 1.), texture2D(u_to, v_uv), u_progress);
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Swirl Vortex
|
|
230
|
+
|
|
231
|
+
Both scenes swirl in opposite directions with FBM-warped spiral path.
|
|
232
|
+
|
|
233
|
+
```glsl
|
|
234
|
+
// Requires: NQ
|
|
235
|
+
void main() {
|
|
236
|
+
vec2 uv = v_uv - .5;
|
|
237
|
+
float dist = length(uv);
|
|
238
|
+
float warp = fbm(v_uv * 4.) * .5;
|
|
239
|
+
float fromAng = u_progress * (1. - dist) * 10. + warp * u_progress * 3.;
|
|
240
|
+
float fs = sin(fromAng), fc = cos(fromAng);
|
|
241
|
+
vec2 fromUv = clamp(vec2(uv.x*fc - uv.y*fs, uv.x*fs + uv.y*fc) + .5, 0., 1.);
|
|
242
|
+
float toAng = -(1. - u_progress) * (1. - dist) * 10.
|
|
243
|
+
- warp * (1. - u_progress) * 3.;
|
|
244
|
+
float ts = sin(toAng), tc = cos(toAng);
|
|
245
|
+
vec2 toUv = clamp(vec2(uv.x*tc - uv.y*ts, uv.x*ts + uv.y*tc) + .5, 0., 1.);
|
|
246
|
+
vec4 A = texture2D(u_from, fromUv);
|
|
247
|
+
vec4 B = texture2D(u_to, toUv);
|
|
248
|
+
gl_FragColor = mix(A, B, u_progress);
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Thermal Distortion
|
|
253
|
+
|
|
254
|
+
FBM-driven heat shimmer rising from bottom. Warps both scenes with sine displacement modulated by noise. Slight warm overexposure haze.
|
|
255
|
+
|
|
256
|
+
```glsl
|
|
257
|
+
// Requires: NQ
|
|
258
|
+
void main() {
|
|
259
|
+
float heat = u_progress * 1.5;
|
|
260
|
+
float yFade = smoothstep(1., 0., v_uv.y);
|
|
261
|
+
float shimmer = sin(v_uv.y * 40. + fbm(v_uv * 6.) * 8.)
|
|
262
|
+
* fbm(v_uv * 3. + vec2(0., u_progress * 2.));
|
|
263
|
+
float dispX = shimmer * heat * .03 * yFade;
|
|
264
|
+
vec2 fromUv = clamp(v_uv + vec2(dispX, 0.), 0., 1.);
|
|
265
|
+
vec4 A = texture2D(u_from, fromUv);
|
|
266
|
+
float invShimmer = sin(v_uv.y * 40. + fbm(v_uv * 6. + 3.) * 8.)
|
|
267
|
+
* fbm(v_uv * 3. + vec2(3., u_progress * 2.));
|
|
268
|
+
float dispX2 = invShimmer * (1. - u_progress) * .03 * yFade;
|
|
269
|
+
vec2 toUv = clamp(v_uv + vec2(dispX2, 0.), 0., 1.);
|
|
270
|
+
vec4 B = texture2D(u_to, toUv);
|
|
271
|
+
float haze = heat * yFade * .15 * (1. - u_progress);
|
|
272
|
+
gl_FragColor = vec4(mix(A.rgb, B.rgb, u_progress)
|
|
273
|
+
+ vec3(1., .9, .7) * haze, 1.);
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Flash Through White
|
|
278
|
+
|
|
279
|
+
Both scenes brighten to white midpoint. Works on dark backgrounds where color-dip-to-black is invisible.
|
|
280
|
+
|
|
281
|
+
```glsl
|
|
282
|
+
void main() {
|
|
283
|
+
vec4 A = texture2D(u_from, v_uv), B = texture2D(u_to, v_uv);
|
|
284
|
+
float toWhite = smoothstep(0., .45, u_progress);
|
|
285
|
+
vec3 fromC = mix(A.rgb, vec3(1.), toWhite);
|
|
286
|
+
float fromWhite = 1. - smoothstep(.5, 1., u_progress);
|
|
287
|
+
vec3 toC = mix(B.rgb, vec3(1.), fromWhite);
|
|
288
|
+
gl_FragColor = vec4(mix(fromC, toC, smoothstep(.35, .65, u_progress)), 1.);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Cross-Warp Morph
|
|
293
|
+
|
|
294
|
+
Both scenes displace along a shared FBM noise field in opposite directions. Noise-driven blend boundary. Neither scene just sits there.
|
|
295
|
+
|
|
296
|
+
```glsl
|
|
297
|
+
// Requires: NQ
|
|
298
|
+
void main() {
|
|
299
|
+
vec2 disp = vec2(fbm(v_uv * 3.), fbm(v_uv * 3. + vec2(7.3, 3.7))) - .5;
|
|
300
|
+
vec2 fromUv = clamp(v_uv + disp * u_progress * .5, 0., 1.);
|
|
301
|
+
vec2 toUv = clamp(v_uv - disp * (1. - u_progress) * .5, 0., 1.);
|
|
302
|
+
vec4 A = texture2D(u_from, fromUv);
|
|
303
|
+
vec4 B = texture2D(u_to, toUv);
|
|
304
|
+
float n = fbm(v_uv * 4. + vec2(3.1, 1.7));
|
|
305
|
+
float blend = smoothstep(.4, .6, n + u_progress * 1.2 - .6);
|
|
306
|
+
gl_FragColor = mix(A, B, blend);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Light Leak (shader)
|
|
311
|
+
|
|
312
|
+
Beer-Lambert exponential falloff + ACES tone mapping + directional flare streak. More physically accurate than the CSS overlay version.
|
|
313
|
+
|
|
314
|
+
```glsl
|
|
315
|
+
vec3 aces(vec3 x) {
|
|
316
|
+
return clamp((x * (2.51 * x + .03)) / (x * (2.43 * x + .59) + .14), 0., 1.);
|
|
317
|
+
}
|
|
318
|
+
void main() {
|
|
319
|
+
vec4 A = texture2D(u_from, v_uv), B = texture2D(u_to, v_uv);
|
|
320
|
+
vec2 lp = vec2(1.3, -.2);
|
|
321
|
+
float dist = length(v_uv - lp);
|
|
322
|
+
float leak = clamp(exp(-dist * 1.8) * u_progress * 4., 0., 1.);
|
|
323
|
+
vec3 warmColor = mix(vec3(1., .5, .15), vec3(1., .9, .75), dist * .7);
|
|
324
|
+
float flare = exp(-abs(v_uv.y - (-.2 + v_uv.x * .3)) * 15.) * leak * .3;
|
|
325
|
+
vec3 overexposed = A.rgb + warmColor * leak * 3. + vec3(1., .8, .5) * flare;
|
|
326
|
+
overexposed = aces(overexposed);
|
|
327
|
+
gl_FragColor = vec4(mix(overexposed, B.rgb, smoothstep(.15, .85, u_progress)), 1.);
|
|
328
|
+
}
|
|
329
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Scene Transitions
|
|
2
|
+
|
|
3
|
+
A transition tells the viewer how two scenes relate. A crossfade says "this continues." A push slide says "next point." A flash cut says "wake up." A blur crossfade says "drift with me." Choose transitions that match what the content is doing emotionally, not just technically.
|
|
4
|
+
|
|
5
|
+
## Energy → Primary Transition
|
|
6
|
+
|
|
7
|
+
| Energy | Primary | Accent for key moments | Duration | Easing |
|
|
8
|
+
| ---------------------------------------- | ---------------------------- | ------------------------------ | --------- | ---------------------- |
|
|
9
|
+
| **Calm** (wellness, brand story, luxury) | Blur crossfade, focus pull | Light leak, circle iris | 0.5-0.8s | `sine.inOut`, `power1` |
|
|
10
|
+
| **Medium** (corporate, SaaS, explainer) | Push slide, staggered blocks | Squeeze, vertical push | 0.3-0.5s | `power2`, `power3` |
|
|
11
|
+
| **High** (promos, sports, music, launch) | Flash cut, zoom through | Staggered blocks, gravity drop | 0.15-0.3s | `power4`, `expo` |
|
|
12
|
+
|
|
13
|
+
Pick ONE primary (60-70% of scene changes) + 1-2 accents. Never use a different transition for every scene.
|
|
14
|
+
|
|
15
|
+
## Mood → Transition Type
|
|
16
|
+
|
|
17
|
+
Think about what the transition _communicates_, not just what it looks like.
|
|
18
|
+
|
|
19
|
+
| Mood | Transitions | Why it works |
|
|
20
|
+
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
+
| **Warm / inviting** | Light leak, blur crossfade, focus pull, film burn, light leak (shader), thermal distortion | Soft edges, warm color washes. Nothing sharp or mechanical. The transition feels like sunlight. |
|
|
22
|
+
| **Cold / clinical** | Squeeze, zoom out, blinds, shutter, grid dissolve, gravitational lens | Content transforms mechanically — compressed, shrunk, sliced, gridded. Zoom out creates clinical distance. No softness. |
|
|
23
|
+
| **Editorial / magazine** | Push slide, vertical push, diagonal split, shutter, whip pan | Like turning a page or slicing a layout. Clean directional movement. Whip pan is a fast editorial camera move. |
|
|
24
|
+
| **Tech / futuristic** | Grid dissolve, staggered blocks, blinds, chromatic aberration, glitch (shader), chromatic split (shader) | Grid dissolve is the core "data" transition. Shader glitch adds posterization + scan lines. |
|
|
25
|
+
| **Tense / edgy** | Glitch, VHS, chromatic aberration, flash cut, ripple, ridged burn, glitch (shader) | Instability, distortion, digital breakdown. Ridged burn adds sharp lightning-crack edges. |
|
|
26
|
+
| **Playful / fun** | Elastic push, 3D flip, circle iris, morph circle, clock wipe, ripple waves, swirl vortex | Overshoot, bounce, rotation, expansion. Swirl vortex adds organic spiral distortion. |
|
|
27
|
+
| **Dramatic / cinematic** | Zoom through, zoom out, gravity drop, overexposure, diagonal split, color dip to black, cinematic zoom (shader), gravitational lens, domain warp, flash through white | Scale, weight, light extremes. Shader transitions add per-pixel depth. |
|
|
28
|
+
| **Premium / luxury** | Focus pull, blur crossfade, color dip to black, slow crossfade, cross-warp morph, thermal distortion | Restraint. Cross-warp morph flows both scenes into each other organically. |
|
|
29
|
+
| **Retro / analog** | Film burn, light leak, VHS, clock wipe | Organic imperfection. Warm color bleeds, scan line displacement. Clock wipe evokes broadcast TV. |
|
|
30
|
+
|
|
31
|
+
## Narrative Position
|
|
32
|
+
|
|
33
|
+
| Position | Use | Why |
|
|
34
|
+
| -------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
35
|
+
| **Opening** | Your most distinctive transition. Match the mood. 0.4-0.6s | Sets the visual language for the entire piece. |
|
|
36
|
+
| **Between related points** | Your primary transition. Consistent. 0.3s | Don't distract — the content is continuing. |
|
|
37
|
+
| **Topic change** | Something different from your primary. Staggered blocks, shutter, squeeze. | Signals "new section" — the viewer's brain resets. |
|
|
38
|
+
| **Climax / hero reveal** | Your boldest accent. Fastest or most dramatic. | This is the payoff — spend your best transition here. |
|
|
39
|
+
| **Wind-down** | Return to gentle. Blur crossfade, crossfade. 0.5-0.7s | Let the viewer exhale after the climax. |
|
|
40
|
+
| **Outro** | Slowest, simplest. Crossfade, color dip to black. 0.6-1.0s | Closure. Don't introduce new energy at the end. |
|
|
41
|
+
|
|
42
|
+
## Blur Intensity by Energy
|
|
43
|
+
|
|
44
|
+
| Energy | Blur | Duration | Hold at peak |
|
|
45
|
+
| ---------- | ------- | -------- | ------------ |
|
|
46
|
+
| **Calm** | 20-30px | 0.8-1.2s | 0.3-0.5s |
|
|
47
|
+
| **Medium** | 8-15px | 0.4-0.6s | 0.1-0.2s |
|
|
48
|
+
| **High** | 3-6px | 0.2-0.3s | 0s |
|
|
49
|
+
|
|
50
|
+
## Presets
|
|
51
|
+
|
|
52
|
+
| Preset | Duration | Easing |
|
|
53
|
+
| ---------- | -------- | ----------------- |
|
|
54
|
+
| `snappy` | 0.2s | `power4.inOut` |
|
|
55
|
+
| `smooth` | 0.4s | `power2.inOut` |
|
|
56
|
+
| `gentle` | 0.6s | `sine.inOut` |
|
|
57
|
+
| `dramatic` | 0.5s | `power3.in` → out |
|
|
58
|
+
| `instant` | 0.15s | `expo.inOut` |
|
|
59
|
+
| `luxe` | 0.7s | `power1.inOut` |
|
|
60
|
+
|
|
61
|
+
## Implementation
|
|
62
|
+
|
|
63
|
+
Read [transitions/catalog.md](transitions/catalog.md) for GSAP code and hard rules for every transition type.
|
|
64
|
+
|
|
65
|
+
| Category | Transitions |
|
|
66
|
+
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
67
|
+
| Content-transforming | Push slide, vertical push, elastic push, squeeze, zoom through, zoom out, gravity drop, 3D flip |
|
|
68
|
+
| Reveal/mask | Circle iris, diamond iris, diagonal split, clock wipe, shutter |
|
|
69
|
+
| Dissolve | Crossfade, blur crossfade, focus pull, color dip |
|
|
70
|
+
| Cover | Staggered blocks, horizontal blinds, vertical blinds |
|
|
71
|
+
| Light | Light leak, overexposure burn, film burn |
|
|
72
|
+
| Distortion | Glitch, chromatic aberration, ripple, VHS tape |
|
|
73
|
+
| Pattern | Grid dissolve |
|
|
74
|
+
| Instant | Flash cut, morph circle |
|
|
75
|
+
| Shader (WebGL) | Domain warp, ridged burn, whip pan, SDF iris, ripple waves, gravitational lens, cinematic zoom, chromatic split, glitch, swirl vortex, thermal distortion, flash through white, cross-warp morph, light leak (shader) |
|
|
76
|
+
|
|
77
|
+
## Transitions That Don't Work in CSS
|
|
78
|
+
|
|
79
|
+
Avoid: star iris, tilt-shift, lens flare, hinge/door. See catalog.md for why.
|
|
80
|
+
|
|
81
|
+
## CSS vs Shader: When to Use Which
|
|
82
|
+
|
|
83
|
+
Most compositions should use **CSS/GSAP transitions** (the other categories above). They're simpler, lighter, and handle most needs. Use **shader transitions** only when you need an effect that CSS can't achieve:
|
|
84
|
+
|
|
85
|
+
| Use CSS/GSAP when | Use Shader when |
|
|
86
|
+
| ---------------------------------------------- | ----------------------------------------------- |
|
|
87
|
+
| Opacity, transform, clip-path, filter effects | Per-pixel noise dissolves, domain warping |
|
|
88
|
+
| Simple crossfades, wipes, slides | Both scenes actively morph into each other |
|
|
89
|
+
| No images/video in scenes (text + shapes only) | Live video needs to play through the transition |
|
|
90
|
+
| Quick to set up, no boilerplate | Willing to add WebGL setup layer (~200 lines) |
|
|
91
|
+
|
|
92
|
+
Shader transitions require setup boilerplate (canvas, scene capture, WebGL init). Read [transitions/shader-setup.md](transitions/shader-setup.md) for the complete code. The fragment shaders themselves are in the Shader section of [transitions/catalog.md](transitions/catalog.md).
|
|
93
|
+
|
|
94
|
+
## Visual Pattern Warning
|
|
95
|
+
|
|
96
|
+
Avoid transitions that create visible repeating geometric patterns — grids of tiles, hexagonal cells, uniform dot arrays, evenly-spaced blob circles. These look cheap and artificial regardless of the math behind them. Organic noise (FBM, domain warping) is good because it's irregular. Geometric repetition is bad because the eye instantly sees the grid.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Text-to-Speech
|
|
2
|
+
|
|
3
|
+
Generate speech audio locally using Kokoro-82M (no API key, runs on CPU).
|
|
4
|
+
|
|
5
|
+
## Voice Selection
|
|
6
|
+
|
|
7
|
+
Match voice to content. Default is `af_heart`.
|
|
8
|
+
|
|
9
|
+
| Content type | Voice | Why |
|
|
10
|
+
| ------------- | --------------------- | -------------------------- |
|
|
11
|
+
| Product demo | `af_heart`/`af_nova` | Warm, professional |
|
|
12
|
+
| Tutorial | `am_adam`/`bf_emma` | Neutral, easy to follow |
|
|
13
|
+
| Marketing | `af_sky`/`am_michael` | Energetic or authoritative |
|
|
14
|
+
| Documentation | `bf_emma`/`bm_george` | Clear British English |
|
|
15
|
+
| Casual | `af_heart`/`af_sky` | Approachable, natural |
|
|
16
|
+
|
|
17
|
+
Run `npx hyperframes tts --list` for all 54 voices (8 languages).
|
|
18
|
+
|
|
19
|
+
## Speed Tuning
|
|
20
|
+
|
|
21
|
+
- **0.7-0.8** — Tutorial, complex content
|
|
22
|
+
- **1.0** — Natural pace (default)
|
|
23
|
+
- **1.1-1.2** — Intros, upbeat content
|
|
24
|
+
- **1.5+** — Rarely appropriate
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx hyperframes tts "Your script here" --voice af_nova --output narration.wav
|
|
30
|
+
npx hyperframes tts script.txt --voice bf_emma --output narration.wav
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
In compositions:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<audio
|
|
37
|
+
id="narration"
|
|
38
|
+
data-start="0"
|
|
39
|
+
data-duration="auto"
|
|
40
|
+
data-track-index="2"
|
|
41
|
+
src="narration.wav"
|
|
42
|
+
data-volume="1"
|
|
43
|
+
></audio>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## TTS + Captions Workflow
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx hyperframes tts script.txt --voice af_heart --output narration.wav
|
|
50
|
+
npx hyperframes transcribe narration.wav # → transcript.json with word-level timestamps
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Requirements
|
|
54
|
+
|
|
55
|
+
- Python 3.8+ with `kokoro-onnx` and `soundfile`
|
|
56
|
+
- Model downloads on first use (~311 MB + ~27 MB voices, cached in `~/.cache/hyperframes/tts/`)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hyperframes-cli
|
|
3
|
+
description: HyperFrames CLI tool — hyperframes init, lint, preview, render, transcribe, tts, doctor, browser, info, upgrade, compositions, docs, benchmark. Use when scaffolding a project, linting or validating compositions, previewing in the studio, rendering to video, transcribing audio, generating TTS, or troubleshooting the HyperFrames environment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HyperFrames CLI
|
|
7
|
+
|
|
8
|
+
Everything runs through `npx hyperframes`. Requires Node.js >= 22 and FFmpeg.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Scaffold** — `npx hyperframes init my-video`
|
|
13
|
+
2. **Write** — author HTML composition (see the `hyperframes` skill)
|
|
14
|
+
3. **Lint** — `npx hyperframes lint`
|
|
15
|
+
4. **Preview** — `npx hyperframes preview`
|
|
16
|
+
5. **Render** — `npx hyperframes render`
|
|
17
|
+
|
|
18
|
+
Lint before preview — catches missing `data-composition-id`, overlapping tracks, unregistered timelines.
|
|
19
|
+
|
|
20
|
+
## Scaffolding
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx hyperframes init my-video # interactive wizard
|
|
24
|
+
npx hyperframes init my-video --template warm-grain # pick a template
|
|
25
|
+
npx hyperframes init my-video --video clip.mp4 # with video file
|
|
26
|
+
npx hyperframes init my-video --audio track.mp3 # with audio file
|
|
27
|
+
npx hyperframes init my-video --non-interactive # skip prompts (CI/agents)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Templates: `blank`, `warm-grain`, `play-mode`, `swiss-grid`, `vignelli`, `decision-tree`, `kinetic-type`, `product-promo`, `nyt-graph`.
|
|
31
|
+
|
|
32
|
+
`init` creates the right file structure, copies media, transcribes audio with Whisper, and installs AI coding skills. Use it instead of creating files by hand.
|
|
33
|
+
|
|
34
|
+
## Linting
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx hyperframes lint # current directory
|
|
38
|
+
npx hyperframes lint ./my-project # specific project
|
|
39
|
+
npx hyperframes lint --verbose # info-level findings
|
|
40
|
+
npx hyperframes lint --json # machine-readable
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Lints `index.html` and all files in `compositions/`. Reports errors (must fix), warnings (should fix), and info (with `--verbose`).
|
|
44
|
+
|
|
45
|
+
## Previewing
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx hyperframes preview # serve current directory
|
|
49
|
+
npx hyperframes preview --port 4567 # custom port (default 3002)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Hot-reloads on file changes. Opens the studio in your browser automatically.
|
|
53
|
+
|
|
54
|
+
## Rendering
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx hyperframes render # standard MP4
|
|
58
|
+
npx hyperframes render --output final.mp4 # named output
|
|
59
|
+
npx hyperframes render --quality draft # fast iteration
|
|
60
|
+
npx hyperframes render --fps 60 --quality high # final delivery
|
|
61
|
+
npx hyperframes render --format webm # transparent WebM
|
|
62
|
+
npx hyperframes render --docker # byte-identical
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Flag | Options | Default | Notes |
|
|
66
|
+
| -------------- | --------------------- | -------------------------- | --------------------------- |
|
|
67
|
+
| `--output` | path | renders/name_timestamp.mp4 | Output path |
|
|
68
|
+
| `--fps` | 24, 30, 60 | 30 | 60fps doubles render time |
|
|
69
|
+
| `--quality` | draft, standard, high | standard | draft for iterating |
|
|
70
|
+
| `--format` | mp4, webm | mp4 | WebM supports transparency |
|
|
71
|
+
| `--workers` | 1-8 or auto | auto | Each spawns Chrome |
|
|
72
|
+
| `--docker` | flag | off | Reproducible output |
|
|
73
|
+
| `--gpu` | flag | off | GPU-accelerated encoding |
|
|
74
|
+
| `--strict` | flag | off | Fail on lint errors |
|
|
75
|
+
| `--strict-all` | flag | off | Fail on errors AND warnings |
|
|
76
|
+
|
|
77
|
+
**Quality guidance:** `draft` while iterating, `standard` for review, `high` for final delivery.
|
|
78
|
+
|
|
79
|
+
## Transcription
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx hyperframes transcribe audio.mp3
|
|
83
|
+
npx hyperframes transcribe video.mp4 --model medium.en --language en
|
|
84
|
+
npx hyperframes transcribe subtitles.srt # import existing
|
|
85
|
+
npx hyperframes transcribe subtitles.vtt
|
|
86
|
+
npx hyperframes transcribe openai-response.json
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Text-to-Speech
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx hyperframes tts "Text here" --voice af_nova --output narration.wav
|
|
93
|
+
npx hyperframes tts script.txt --voice bf_emma
|
|
94
|
+
npx hyperframes tts --list # show all voices
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Troubleshooting
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npx hyperframes doctor # check environment (Chrome, FFmpeg, Node, memory)
|
|
101
|
+
npx hyperframes browser # manage bundled Chrome
|
|
102
|
+
npx hyperframes info # version and environment details
|
|
103
|
+
npx hyperframes upgrade # check for updates
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Run `doctor` first if rendering fails. Common issues: missing FFmpeg, missing Chrome, low memory.
|
|
107
|
+
|
|
108
|
+
## Other
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npx hyperframes compositions # list compositions in project
|
|
112
|
+
npx hyperframes docs # open documentation
|
|
113
|
+
npx hyperframes benchmark . # benchmark render performance
|
|
114
|
+
```
|