Manga-style dialog video creator. Write scripts with [Speaker]: text{command}<effect>(#color) and export MP4 videos with typewriter text reveal, animated dialog boxes, speaker color/position assignment, and optional Three.js 3D backgrounds.
Built with Astro, Hyperframes, GSAP, and Three.js.
bun install
bun run dev # dev server at localhost:4321
bun run build # production build to dist/Open the app, type a script in the editor, and click Export Video.
[Speaker]: dialog text with {commands} <effects> (#colors)
NOTE: scene note text
ANIGO: key=value key=value
| Command | Default | Effect |
|---|---|---|
{pause} |
500ms | Inline typewriter pause — splits text into chunks |
{pause N} |
N ms | Custom inline pause |
{stop} |
1500ms | Line-level dramatic gap |
{suddenstop} |
800ms | Line-level short dramatic gap |
{fast} |
2× speed | Doubles typewriter speed |
{slow} |
0.5× speed | Halves typewriter speed |
{yell} |
— | Uppercases all dialog text |
{yeld-pause} |
— | Uppercases text + 500ms pause between each word |
{trembling} |
— | Shakes the dialog box |
{fade N} |
— | Fades out over N ms |
| Effect | Description |
|---|---|
<slide> |
Slide entrance (direction depends on position) |
<jump> |
Bounce entrance motion |
Sets the text/border color for the line. Can appear inline:
[Joe]: Hello (#ff5599)world
| Speaker | Behavior |
|---|---|
Narrator / Narrador |
No typewriter/slide — just fades in at bottom-center, white |
Note / Nota |
Dialog-like speaker at top-center, gray |
Override schema properties via dot-path access:
ANIGO: dialogBox.maxWidth=600 timing.charsPerSec=20
src/
├── parser/ # Script parsing
│ ├── types.ts # Data model
│ ├── parse.ts # Script → ParsedScript
│ ├── assign.ts # Speaker color/position assignment
│ └── index.ts # Barrel exports
├── composition/ # Video composition generation
│ ├── schema.ts # CompositionSchema + defaults + overrides
│ ├── timing.ts # Duration/pause/typing time computations
│ └── generate.ts # ParsedScript → self-contained HTML
├── components/ # React UI
│ ├── App.tsx # Root — editor + preview layout
│ ├── CommandReference.tsx
│ ├── ParsedPreview.tsx
│ └── ExportPanel.tsx
├── lib/
│ ├── run-hyperframes.ts # Spawns hyperframes render CLI
│ └── use-debounce.ts # Debounce hook
├── pages/
│ ├── index.astro # SPA entry point
│ └── api/render.ts # POST /api/render endpoint
└── styles/
└── global.css # Tailwind CSS 4 import
Script → parseScript() → generateComposition() → .hyperframes-tmp/<uuid>/index.html
↓
bunx hyperframes render [dir]
↓
public/output/<uuid>.mp4
The generated HTML is a self-contained composition with:
- CSS for 9-position dialog box grid layout
- Three.js background scene (configurable via schema)
- GSAP timeline with per-clip animations (typewriter clipPath reveal, slide, jump, trembling, fade)
The CompositionSchema in src/composition/schema.ts is the single source of truth for all visual/timing/animation properties. Defaults:
| Path | Default | Description |
|---|---|---|
timing.charsPerSec |
15 | Base typewriter speed |
timing.minDisplaySec |
2.0 | Minimum line display time |
timing.holdSec |
1.0 | Extra hold after typing |
layout.margin |
40 | Screen edge margin (px) |
layout.gridColumns |
3 | Grid divisions for positioning |
dialogBox.maxWidth |
420 | Max dialog box width (px) |
dialogBox.bgAlpha |
0.4 | Background opacity |
animations.slide.duration |
0.5 | Slide entrance duration (s) |
animations.trembling.count |
6 | Shake steps |
notes.durationSec |
4.0 | Note display time |
three.scene.background |
#000000 | 3D scene background |
{
"scriptText": "[Narrator]: Hello\n[Joe]: Hi{pause} how are you?",
"width": 1920,
"height": 1080,
"fps": 30
}Returns:
{ "url": "/output/<uuid>.mp4" }| Command | Action |
|---|---|
bun run dev |
Start Astro dev server |
bun run build |
Build for production |
bun run preview |
Preview production build |
bunx hyperframes render [dir] |
Render HTML composition to MP4 |
- No audio support (first-version scope)
- No images/video/media beyond dialog boxes and Three.js background
- Three.js canvas resolution hardcoded to 1920×1080 in generated HTML
- Generated HTML loads GSAP and Three.js from CDN (no offline render)
src/templates/scene.htmlis legacy/unused- No timeline preview or per-line timing adjustment in UI yet
MIT — © Bytes4Run