プロジェクト構成
FrameScript の生成プロジェクトは「Studio 本体」と「自分が書く作品コード」が同居している。 どこをいじってよくて、どこをいじってはいけないかを最初に押さえる。
ディレクトリ全体図
.
├── project/ ← ここを編集する(作品コード)
│ ├── project.tsx - PROJECT_SETTINGS と PROJECT を export
│ └── keyframes.ts - 自作のキーフレーム DSL(任意)
├── sample/ ← サンプルシーン(雛形・参考)
│ ├── Scene1.tsx
│ ├── Transition1.tsx
│ └── ...
├── src/ ← FrameScript 本体(基本さわらない)
│ ├── lib/ - Clip / Timeline / Frame / Animation / Media
│ ├── ui/ - Studio UI
│ ├── render/ - レンダラ側のエントリ
│ └── ...
├── backend/ ← Rust 製の decode サーバ
├── render/ ← headless Chromium を駆動するレンダラ
├── electron/ ← Electron のメインプロセス
├── assets/ ← 画像/音声/フォント など
├── package.json
└── ... (vite/tsconfig 各種)
自作のシーン・コンポーネントは project/ 配下に置く。
src/ 配下は本体で、改造したい意図がない限りいじらない(FrameScript の更新で衝突する)。
役割の細かい話
project/project.tsx
動画の入口。PROJECT_SETTINGS(解像度・FPS)と
PROJECT(ツリー全体)を export する。
ここで <TimeLine> 直下にクリップを並べる。シーンが増えてきたら
project/scenes/Scene1.tsx のようにファイルを切って import するのが定番。
import { Clip } from "../src/lib/clip"
import { seconds } from "../src/lib/frame"
import { Project, type ProjectSettings } from "../src/lib/project"
import { TimeLine } from "../src/lib/timeline"
import Scene1 from "../sample/Scene1"
import Scene2 from "../sample/Scene2"
export const PROJECT_SETTINGS: ProjectSettings = {
name: "sample-animation",
width: 500,
height: 500,
fps: 60,
}
export const PROJECT = () => (
<Project>
<TimeLine>
<Clip start={seconds(0)} duration={seconds(3)} label="Scene1">
<Scene1 />
</Clip>
<Clip start={seconds(3)} duration={seconds(3)} label="Scene2">
<Scene2 />
</Clip>
</TimeLine>
</Project>
)
project/keyframes.ts(自作 DSL)
サンプルプロジェクトには CSS の @keyframes 風に
ステップを書ける独自ヘルパーが付いてくる。
本体の API ではなく、プロジェクト内のユーティリティなので、
必要なければ消して良い。便利なのでそのまま使うのもアリ。
await keyframes(ctx, {
duration: seconds(1),
easing: easeInOutCubic,
vars: { ty, rot },
steps: {
"0%": { ty: -250, rot: 15 },
"20%": { ty: 0, rot: 0 },
"40%": { ty: -30, rot: -15 },
"60%": { ty: 0, rot: 0 },
"80%": { ty: -15, rot: 5 },
"100%": { ty: 0, rot: 0 },
},
})
sample/
生成プロジェクトに付いてくるサンプル。Scene1〜4 と Transition1〜3 が並んでいて、
動くお手本として参考になる。
ここに自分のシーンを足してもいいし、project/scenes/ を新設して移植してもいい。
src/lib/
本体ライブラリ。useAnimation や <Clip> などはここから import する。
このノートで「FrameScript の API」と呼んでいるのはここ。
animation.ts/animation/functions.ts— 変数・イージングclip.tsx— Clip / ClipStatic / Serial / ClipSequencetimeline.tsx— TimeLine と登録ロジックframe.tsx— currentFrame コンテキスト、seconds()video//sound//image.tsx— メディアcharacter/— PSD キャラクター・対話シナリオwebgl/— Three.js / WebGL ヘルパーlayout/fill-frame.tsx— フレーム全体を覆うコンテナ
render/ と backend/
書き出し時の挙動が気になったときに見るところ。普段はブラックボックスで OK。
render/—vite.render.config.tsでビルドされる、headless 実行用のエントリ。backend/— 動画・音声のデコード/波形生成を担う Rust サーバ。
assets/
画像・音声・フォントを置く。プロジェクト内のパスは "assets/foo.mp4" のような
相対指定で参照する。
AGENTS.md
ルートの AGENTS.md には「src/ は基本いじらない」と
書いてある。AI エージェント(Codex / Claude Code 等)に作業させる時は、
最初に AGENTS.md を読ませてからタスクを渡すと、変なところを書き換えられにくい。