cut-the-curve について
cut-the-curveは、GSAPでHTML動画をアニメーション化するエージェント向けの技法カタログです。速度を合わせるシーン遷移に加え、単語単位の連鎖やシーン内のグループ移動を扱います。
主な機能
- 017種類の遷移・動作技法
- 02速度を合わせたシーンカット
- 03ズームとブラーによるカット
- 04単語単位のウォーターフォール遷移
- 05ウォーターフォール入場とグループ移動
活用シーン
- 01シーン境界の遷移選び
- 02動画ビート間のテキストアニメーション
- 03タイトルやリストの導入
- 04コンテンツを見せるグループ移動
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ heygen-com/ hyperframes --skill cut-the-curveインストール後、Claude Code で/cut-the-curveを入力して読み込まれたか確認します。
詳細
カーブを切る — テクニックカタログ
5 つの SEAM テクニックに共通する原則は 1 つです。速度がピークに達したところでカットし、カットの前後で方向と速度を一致させます — さらに、シーン内で使う 2 つのテクニック(§6 の到着、§7 のスライド)もあります。
シームの法則 — ベクトルの法則、カレント、台帳、Seam Gate — は motion-doctrine に記載されています。まずそちらを読んでください。このスキルではパラメーターと仕組みを説明します。
GSAP コードテンプレート(ワーカー + レジストリ)はすべて examples/gsap-implementation.md にあります。
カタログ
| # | テクニック | スコープ | 軸 | 用途 |
|---|---|---|---|---|
| 1 | Zoom-Through(前進) | シーン内のテキスト切り替え | Z、視聴者に向かう | 同じ考えをさらに深めていく |
| 2 | Inverse Zoom-Through | 到着/成果のビート | Z、視聴者から遠ざかる | より大きなものを登場させる |
| 3 | Cut the Curve | シーン間 | X / Y | 標準の境界、映像のカレント |
| 4 | Waterfall Cut | テキスト間のシーム | X、単語ごと | 大きなテキストのビート間で単語単位に引き継ぐ |
| 5 | Rack-Focus Blur-Cut | 同一サーフェスの状態切り替え | X / Y / Z | SEAM で見せたい唯一のカット — DSLR のフォーカス送りを思わせる華やかな効果 |
| 6 | Waterfall Entry | シーン内の到着(シームなし) | Y、下から | タイトルカード、セグメントの冒頭、リストの導入 |
| 7 | Nudge Curve | シーン内のグループスライド(シームなし) | X / Y | 配置済みのグループを移動してスペースを作る |
Z 方向は符号で決まる
Z 軸では、「同じ軸」だけでは不十分です。カットをまたいで d(scale)/dt の符号を一致させる必要があります。
| Z ベクトル | 出口のスケール | 入り口のスケール | バリアント |
|---|---|---|---|
| Push(前進) | 拡大 1 → 1.2 | 拡大 0.75 → 1 | zoom-through |
| Pull(後退) | 縮小 1 → 0.8 | 縮小 1.25 → 1 | inverse zoom-through |
禁止されるミラー表現:後退する出口に、小さい状態から拡大する入り口で応えるパターン(Pull が Push に反転するもの — 小さい状態からの拡大は要素の入り口として一般的なため、よく起こります)、および Push の出口に、拡大した状態から縮小する動きで応えるパターン。これはシームウィンドウ(カット + 約 0.5 秒)中における、ラッパーのトゥイーンだけでなく、入ってくるシーン自体の入り口にも適用されます。入ってくるフレームの構成を維持するか、符号が一致するようにその入り口を作成してください。Seam Gate のルール 7 に従って確認します。
ぼかしのロジック(すべての Z バリアント)
| 対象 | ピークのぼかし | 理由 |
|---|---|---|
| テキストスケール(見出し、単語グループ) | 10px | 20px では文字形状がにじみ、カットが速度ではなくグリッチに見えるため |
| 全画面サーフェス(ウィンドウ、カード、スクリーンショット) | 18–20px | 大きなサーフェスに弱いぼかしをかけると、レンダリングの乱れに見えるため |
切り替えフレームの両側でピークのぼかしを同じにします。ぼかすのはラッパーであり、子要素ではありません。
1. ズームスルー(前進)
Z 軸の速度を合わせたカットです。**両方のテキストが同時に表示されることはありません。**すべて拡大します。退出するテキストはカメラに向かって加速し、最もぼけた瞬間にハードスワップで切り替わり、入ってくるテキストは焦点面まで拡大し続けます。見出しや短いフレーズに限ります。合計約 0.4 秒です。
| フェーズ | スケール | ぼかし | 不透明度 | イージング | 時間 |
|---|---|---|---|---|---|
| 退出 | 1 → 1.2 | 0 → 10px | 1 → 0.15 | power3.in(不透明度は別の none tween) | 0.2s |
カット(tl.set) | in: 0.75 | 10px | out: 0 / in: 0.15 | — | — |
| 入場 | 0.75 → 1 | 10 → 0px | 0.15 → 1 | expo.out | 0.5s |
退出時の不透明度は、必ず独立した線形 tween にしてください。power3.in では不透明度が長時間ほぼ 1 のままになります。
入場時は、すべてのプロパティに expo.out を適用します。
2. 逆ズームスルー(後退)
引き戻しのミラーです。退出する要素は後退し、入ってくる要素は(カメラのすぐ後ろにあるかのように)特大サイズで現れ、焦点面まで縮小します。すべて縮小します。到着や見せ場のビート、つまり決めの一行、巨大な返信、静止した終了状態などに使用し、通常の境界には使用しないでください。合計約 0.7 秒です(退出 30%/入場 70%)。
| フェーズ | スケール | ぼかし | 不透明度 | イージング | 時間 |
|---|---|---|---|---|---|
| 退出 | 1 → 0.8 | 0 → 10px | 1 → 0.15 | power3.in(不透明度は別の none tween) | 約 0.2s |
カット(tl.set) | in: 1.25 | 10px | out: 0 / in: 0.15 | — | — |
| 入場 | 1.25 → 1 | 10 → 0px | 0.15 → 1 | expo.out | 約 0.5s |
ぼかしはテキストのスケールに対して 10px にします。両側がフルブリードのサーフェスの場合に限り、18~20px にします。
**符号の扱い:**入ってくるシーンは、縮小するラッパー内に合成済みフレームとして現れます。継ぎ目の時間帯に、小さい状態から拡大して入る演出は使いません。段階的な入場は、縮小が落ち着いた後に行うか、1 以上から始めて縮小させます。
3. カーブカット(シーン境界のデフォルト)
X/Y 軸の速度を合わせたカットです。映画全体のアクセントではなく、現在の場面におけるすべてのシーン間の境界でのデフォルトです。退出する主役要素は一方向に加速し、動きの途中でカットが入り、入ってくる主役要素は同じ方向に動き続けて減速します。合計約 0.6 秒です。方向は LEFT/RIGHT/UP/DOWN(デフォルトは LEFT)です。
**移動量の一部のみ:**フレームの約 12%(1920 の場合、約 230px)です。画面外まで完全に移動させることはありません。
| 方向 | 退出 | 入場の開始 → 終了 |
|---|---|---|
| 左 | x: 0 → −230 | x: +230 → 0 |
| 右 | x: 0 → +230 | x: −230 → 0 |
| 上 | y: 0 → −230 | y: +230 → 0 |
| 下 | y: 0 → +230 | y: −230 → 0 |
仕組み:
- **ミラーリングしたイージング:**退出は
power4.in、入場はpower4.outを使用し、距離と時間を同じにします。これにより、1 つのpower4.inOutの半分ずつとなり、カット時の速度が正確に一致します。 - **フェードの工夫:**退出側の不透明度は、移動の約 25~30%の時点で変化を完了させます(フェードは約 0.18~0.3 秒、移動は 0.3~0.34 秒)。入場側は、移動経路の中ほどで不透明度約 0.35 から始めます。最後にフェードアウトする要素がカットと同時に消えるように調整してください。何も動かない隙間があると、間延びして見えます。
- 退出は 0.2~0.4 秒、入場は退出と同じか、それ以上にします。ぼかしは任意で 8~10px です。
- ステージの背景:
#rootは不透明にする必要があります (background: var(--canvas-deep, var(--canvas, #000)))。ウィンドウの途中でカットすると、不透明度の合計が 1 未満になる時間帯が生じ、そのままでは画面が白くフラッシュします(seam-craftを参照)。
push-slide もありますが、移動量の一部のみという要件と、動きの途中でのフェーズ切り替えに反するため、カーブカットを優先してください。
4. ウォーターフォールカット(単語単位のカーブカット)
単語単位でカーブカットします。テキストからテキストへの切れ目で、最も強い左方向のカットです。 退出する単語はそれぞれ独自のカーブで加速し、入ってくる単語は動きの途中から連鎖します。視線が切れ目を越えて波に乗るような演出です。
対象範囲: 1つの複数ビートのコンポジション内(フレーム全体に重ねた .beat レイヤー)のワーカーが作成します。レジストリ/インジェクターの種類ではありません。クリップのラッパーではなく、単語の範囲をトゥイーンします。テキストビートのブロックの開始時と終了時には、通常のレジストリトランジションを使用します。2~3個のトランジションの予算には含めません。
| パラメーター | 値 | 理由 |
|---|---|---|
| 移動量 | ±230px(フレームの約12%) | 移動量を抑えつつ速度を出すことで、フレーム全体を押し出すより強い効果が得られます |
| 退出 | 0.34s power4.in | 加速そのものがカットになります |
| 退出時のフェード | 0.18s、x と同時に開始 | 移動量の約25~30%に達するまでに単語が消えるため、にじみません |
| 退出時のスタッガー | 読み順に +0.022s | 行がブロックごとスライドするのではなく、剥がれるように退出します |
| 入場 | 0.3s power4.out | コンポジットの後半に合わせ、速度を揃えます |
| 入場時の開始不透明度 | 0.35 | 軌道の中間点から点火します。0→1の二値変化ではポップして見えます |
| 入場間隔 | 0.05s × 0.84の減衰 | 加速する連鎖で、最終的に一体としてまとまります |
ルール:
- 連鎖ごとに方向は1つにし、流れに乗せます。逆方向のズームは連鎖の到着ビートに限ります。
- ビルド時にすべての単語を
x: +230, opacity: 0に設定します。immediateRender: falseだけでは、開始していない単語が静止状態で見えてしまいます。 - 短い最初のビートは、行全体を退出させてもかまいません。フェードをカットの約0.02s前に終えると、次の単語が点火する瞬間にも前の単語がまだ流れており、間が空きません。
- transform/opacity のみ(シークセーフ)。不透明なステージの背景を適用します。
5. ラックフォーカス・ブラーカット(見えるカット)
カットが目に見える唯一のバリエーションです。デフォーカスのブラーを急激に強めて1フレームのハードな切り替えを隠す、ハンドヘルド一眼レフカメラのフォーカス送りのような演出です。同じビジュアルテーマ内で、同じサーフェスの状態を切り替える際に、ときどきアクセントとして使います。デフォルトの境界にはしないでください。
他との違い:退出側はカットまで完全に不透明なままです(ブラーが切り替えを隠すため、早い段階でフェードさせません)。イージングには power2.in/power2.out を使います(勢いではなく、柔らかな光学効果を表現します)。
ルール:
- 物語上のビートに限り、約8秒に1回以下の頻度で発生させます。字幕の途中やホールド中は使いません。
- ブラーがピーク(6px以上。ピークは8~12px、最大でも16~18px以下)に達した時点で切り替えます。ピークに向かう途中で切り替えると、カットが見えてしまいます。
- 控えめなスケール(約1.06)で、レンズのブリージング効果を演出します。
- 両側で方向を揃えます。ベクトルの法則は変わりません。入場の時間は退出以上にします。
- ラッパーにブラーを適用します。1つの要素に対して、1つのトゥイーンでブラーと不透明度を同時にアニメーションさせないでください(ヘッドレス合成の不具合が発生します)。
<video>に直接ブラーを適用せず、ラッパーで包んでください。
6. ウォーターフォールエントリー(シーン内への登場 — シームではありません)
段階的な登場のカスケードです。単語や要素が下から勢いよく入ってきます(方向は一貫させます)。 それぞれが前の要素の着地前に動き始め、加速する波がまとまりのあるレイアウトに収束します。 タイトルカード、セグメントのオープニング、リストや機能の紹介に使います。シームに対応するのは §4です。ルールを混同しないでください。
| §6 エントリー(登場) | §4 ウォーターフォールカット(シーム) | |
|---|---|---|
| 不透明度 | エントリー時に tl.set でバイナリの 0→1 — フェードは使いません | 経路の途中、0.35 で点灯 — フェードが速度の仕掛けです |
| 既定の軸 | Y、下から | X、流れに乗って |
| 退場方向 | なし | power4.in のミラー反転で単語が徐々に退場 |
振り付け:
- 順番に並べず、重ねる — 次の要素は、前の要素が着地する前後 2 フレーム以内に動き始めます。 カスケードが進むにつれて間隔を縮め、最後の要素はスナップさせます。
- 重さに応じて速度を変える — 重い要素やアンカー要素は、より大きな距離をより長く移動します。 軽い単語や句読点はタイトにスナップさせます。
| パラメーター | アンカー/重い要素 | 通常の単語 | 軽い要素/句読点 |
|---|---|---|---|
| Y オフセット | 60–80px | 40–50px | 30–48px |
| 継続時間 | 0.16–0.20s | 0.13–0.16s | 0.10–0.13s |
| 重なり | 0–2f の間隔 | 1f の重なり | 1–2f の重なり |
- イージングは
power4.out(さらにスナップさせる場合は expo.out)を使います。エントリーで.inOutは使いません。 - 1 回のカスケードでは方向を 1 つに統一します。
- 最終単語をフラグメントに分割してクライマックスを伸ばします。フラグメントはより遠くまで移動します。
- 着地後、グループは通常、次のビートのために場所を空けるようスライドします — これは §7 です。
7. ナッジカーブ(シーン内のグループスライド — シームではありません)
まとまりのあるグループ(単語の行、カードのスタック、リスト)を、コンテンツの表示や場所を空けるために、
ゆっくりから速く、そしてゆっくりへと再配置します。組み込みのイージングだけでは実現できません —
power4.inOut は急停止します。1 つのプロパティに 3 つのトゥイーンを連ねます。
| フェーズ | イージング | 距離 | 時間 | 感触 |
|---|---|---|---|---|
| 1 ランプイン | power3.in | 約 10% | 約 20% | ほとんど動かず、動きは感じられるものの衝撃はありません |
| 2 バースト | none(線形) | 約 65% | 約 18% | 平均 px/frame の約 2 倍 — 意図的な動きです |
| 3 テール | power4.out | 約 25% | 約 62% | 減速しながら静止するまで進み、急停止を抑えます |
ルール:
- テールの時間はランプインの時間の 3 倍以上にします。それでも急停止する場合は、距離ではなくテールの時間を延ばすか、
power5.outを使います。 - フェーズ 2 は線形のままにします。イージングを加えると、バーストのコントラストが失われます。
- フェーズ 2 の間に新しいコンテンツを表示します。バーストによって表示の瞬間が目立たなくなります。
- 垂直方向も同じ比率にします。距離は比例して調整し、時間の比率は維持します。
バリエーションの選択
| ズームスルー | インバースズーム | カーブを切る | ウォーターフォールカット | |
|---|---|---|---|---|
| 適用範囲 | シーン内のテキスト切り替え | 到着/決めの瞬間 | シーン間 | テキスト間の継ぎ目 |
| Z の符号/軸 | 拡大(プッシュ) | 縮小(プル) | X/Y | X、単語ごと |
| 移動/スケール | 1→1.2、その後 0.75→1 | 1→0.8、その後 1.25→1 | ±230px | ±230px |
| ピーク時のぼかし | テキスト 10px/全画面 18~20px | テキスト 10px/全画面 18~20px | 8~10px、任意 | なし |
| イージング | power3.in/expo.out | power3.in/expo.out | power4.in/power4.out | power4.in/power4.out |
| 印象 | 進んでいく | 到着する | 横方向に運ばれる | 継ぎ目を横切る波 |
アンチパターン
| 避けること | 代わりに行うこと |
|---|---|
| ズームスルー中に2つのテキストが同時に見える | ぼかしが最大になるタイミングでハードカットし、テキストは一度に1つだけ表示する |
| テキストサイズの被写体に20pxのぼかしを適用する | テキストは10px、フルフレームの場合に限り18〜20pxを使用する |
| 逆ズームで退出 → 小さい状態から拡大して登場(または押し出し → 大きくなってから縮小) | スケール速度の符号を合わせ、カット±0.1sで確認する |
| Zシームのラッパーツイーンの下で、次のコンポーネント自体のスケールアップイントロを実行する | 構成を整えて登場させる。シームが落ち着いてから登場させるか、符号を合わせる |
| 切り替え時にぼかしや不透明度が一致しない | カットフレームで値を同一にする |
緩やかな登場イージング(power2.out) | 退出を反映する:power4.out / expo.out |
| 画面外まで完全に退出・登場させる | 一部だけ移動(約12%)し、早めにフェードする |
カットのどちらかで.inOutイージングを使う | power4.in / power4.outを対称に使う |
| カットよりかなり前に、単独の要素をフェードさせる | フェードをカットの約0.02s前に終えるか、単語カスケードを使う |
| ウォーターフォールカスケードで間隔を一定にする | 単語ごとに間隔を×0.84に縮める |
| 本文にズームスルーを使う | 見出しと短いフレーズに限る |
| カットザカーブなしでシーンをカットする | これを標準の境界として使う |
| 反対方向の境界を連続させる | 現在の方向を1つにし、予約したベクトルは意味の表現に使う |
ウィンドウ途中のカットで、#rootの背景を塗らない | 不透明なステージの地色を設定する |
| 登場をキューに入れる(それぞれが前の動きが落ち着くまで待つ) | ±1〜2フレーム重ねる。カスケードはキューではなく波 |
| カスケードの各要素に同じオフセット/時間を使う | 重みに応じて変える。アンカーは遠くまで移動し、句読点は素早く切り替える |
| §6の登場で不透明度を徐々にフェードさせる | tl.setで0→1に切り替える。フェードはスナップを損なう(シームカットではフェードし、登場ではフェードしない) |
グループスライドに単一のイージング(power4.inOut、slow())を使う | §7の3段階チェーンを使う |
| ナッジの後半をランプインの3倍未満にする | 距離ではなく、後半の時間を延ばす |
コード
すべてのGSAPテンプレート(workerが作成したバージョン、レジストリのgsap_template、カットザカーブとズームの組み合わせ、ウォーターフォールのDOM/CSS/JS、ラックフォーカス)は、
examples/gsap-implementation.mdにあります。