プロジェクト構成

FrameScript の生成プロジェクトは「Studio 本体」と「自分が書く作品コード」が同居している。 どこをいじってよくて、どこをいじってはいけないかを最初に押さえる。

ディレクトリ全体図

framescript-project/
.
├── 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 するのが定番。

project/project.tsx(成長後の例)
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」と呼んでいるのはここ

render/backend/

書き出し時の挙動が気になったときに見るところ。普段はブラックボックスで OK。

assets/

画像・音声・フォントを置く。プロジェクト内のパスは "assets/foo.mp4" のような 相対指定で参照する。

AGENTS.md

ルートの AGENTS.md にはsrc/ は基本いじらない」と 書いてある。AI エージェント(Codex / Claude Code 等)に作業させる時は、 最初に AGENTS.md を読ませてからタスクを渡すと、変なところを書き換えられにくい。