Figma ストーリーボード → シーンモーションデザイン
ストーリーボードは、一連の静的 1920×1080 フレームです。あなたの仕事は、それらの間をタイムラインが移動する1つのシーンを生成することです。モーションのほとんどはデザインに既に存在しています — 発明するのではなく、それを復元してください。
コードを実行できない場合? このレシピで「ジェネレータースクリプトを作成する」と書かれている箇所では、代わりに
picsart_scene_patchでシーンを構築し、変更のたびにpicsart_scene_query_layoutで同じ不変条件を固定してください(以下の「コマンド」を参照)。方法は同一で、実行面が異なるだけです。
フロー
- ツリーを一度だけ読む — ユーザーが Figma Connector を通じてストーリーボードを共有している場合、ページのフレームツリーを一度だけ読み取ります。すべてのフレーム、レイヤー、名前、ボックスが返されます。以下のすべてはこれに基づいています。フレームごとにボードを探索しないでください。
- ビートを計画する — 作成を開始する前に、ビートテーブルを書き留めます(以下参照)。
- ユーザーが共有したデザインから各要素を個別のレイヤーとして抽出する:ソースの測定値から編集可能なシェイプジオメトリを構築し、既存のレイヤーの CSS 塗りつぶし、シャドウ、グラデーション塗装には
picsart_scene_import_figma_paintを使用します。テキストはライブのままにします。自動シェープノード変換はここでは公開されていません。サポートされていない処理や、真にレイヤー化できないソースに対してのみ画像を使用します。抽出 を参照。 - ジオメトリからシーンを構築し、すべてのルールを固定する。 コードを実行できる場合は、各ルールが
assertになるようにジェネレータースクリプト(手書きの JSON ではない)を作成します。実行できない場合は、picsart_scene_patchでシーンを構築し、picsart_scene_query_layoutで同じ不変条件を固定します。ジオメトリはメタデータから取得し、目視では判断しません。 - 数値で検証し、エクスポートします。
ステップ 3~5 はシーンごとに1回、順番に実行されます。このループが方法です。
単一の静的フレーム
リクエストが単一フレーム(静止画、ストア画像、カード)の場合、ストーリーボードはありません。ビートをスキップし、そのフレームを静止シーンとして構築します。
- ユーザーが共有した Figma Connector を通じて選択されたフレームを読み取ります。 そのサイズが
composition.widthとheight、塗りつぶしがcomposition.backgroundとなり、短いduration(1)で十分です。 - ペイント順に子ごとに1レイヤー(ツリーの最初の子が一番下)。レイヤーの
positionは、フレーム内のボックスの中心[x + width/2, y + height/2]です。レイヤーはその中心を軸に回転およびスケーリングされます。ネストされた子をフレームに対してクロスチェックします。一部のグループは子をグループに対して相対的に格納します(references/figma-extraction.md)。 - 各子は編集可能な状態を保つメディアで:シェイプジオメトリを作成し、
picsart_scene_import_figma_paintで CSS ペイントを適用します。テキストはライブテキストとして、各 IMAGE 塗りつぶしは元のビットマップ上のメディアレイヤーとして扱います — ノードのexportは透明度をフレームの背景にフラット化するため、絶対に使用しません。scaleModeに従います(FILL→cover、FIT→contain、CROP→cover+crop、TILE→表現不可。テーブルとクロップの計算は references/figma-extraction.md の「画像塗りつぶし」を参照)。各画像は最初にアップロードします。Figma アセット URL は期限切れになります。 - クリップまたはフェードを1つとして行うローカルグループは、通常はインラインの
compositionレイヤーです。 意図的に再利用可能で個別に所有されるコンポーネントである場合にのみ、シーン参照を使用します。 - 数値で検証し、次に1つの完全な画像で確認します。
picsart_scene_query_layoutを0で実行:すべてのboxが Figma のボックスと 1 ピクセル以内で一致すること。cropのないトップレベルの画像は、デザインが示す通りにdrawn:そのボックスとsourceCropを持ちます。グループ内の画像はclippedBoxを読み取ります。これはグループが表示を許可する部分です。 次に、明示的なtimesとresolutionを作成寸法に設定したpicsart_scene_contact_sheetを1回実行します。サムネイルは 2 ピクセルの線と小さなテキストをドロップします。
レイヤー、スクリーンではない
シーンは可動レイヤーの合成であり、フラットなスクリーンのモンタージュではありません。デザインはレイヤーとして提供されます。それらを分離可能に保ち、それぞれが独立して動けるようにします。これが、スクリーンショットをクロスフェードするのではなく、シーンを構築するすべての理由です。
- 再構築し、ラスタライズしない。 ユーザーが共有したデザインから編集可能な
shapeジオメトリを構築します。picsart_scene_import_figma_paintで CSS ペイントをその既存のレイヤーに適用します。完全な Figma デザインノードのインポートはここではサポートされていません。コーナー、パス、配置を編集可能に保ち、テキストはライブのままにします。これらを PNG や SVG にフラット化すると、パーツの独立したアニメーションができなくなります。 - ユーザーの Figma Connector を通じて共有されたデザインからアセットを取得する場合、子の代わりに親フレームを決して取得しないでください。 動くのは子です。
- 画像へのフラット化は最後の手段です — 真にレイヤー化されていないソース(ラスタライズされたアセット、レイヤーアクセス不可)に対してのみ使用します。フォールバックする場合は、その旨を明確に述べてください。
- references/figma-extraction.md にある「忠実な外観のためのノードのエクスポート」という習慣は、全体として取り込むことを既に選択した1つの要素の忠実性に関するものです。これを「すべてをラスタライズする」に一般化しないでください。
シーンごとに、順番に構築する
これは以下の個別のルールよりも重要です。タイムライン全体を作成してから提示しないでください。また、最初に印象的な中間のビートをプロトタイプ作成しないでください。中央で設計されたモーションには結合するものがないため、破棄されます。
最初のフレームから開始し、順方向に進みます。シーンごとに:
- 編集可能なレイヤーだけでなく、意味的なモーションユニットで分割します。 コントロール、そのラベル、アイコンは通常、1つの配置オーナーを共有します。意図的な状態変更の場合にのみ、子ローカルモーションを追加します。静止は、欠陥ではなく、有用な階層構造と読み取り時間です。グループ化、パネルの成長、リフローには、リンク要素モーション(
picsart_scene_recipeで取得、名前linked-element-motion)を使用します。 - 既に構築されたものに追加することでモーションを作成します。 コードを実行できる場合はジェネレーターに追加し、実行できない場合は同じシーンにパッチを適用します。決して最初からやり直さないでください。初期のビートの定数とチェックはすべて残り、新しいビートが確定したビートを静かに壊すことはありません。
- そのビートをレンダリングし、独自の時間ウィンドウでビデオとして表示します。 モーションは静止画やコンタクトシートでは確認できません。
- 指示を受け、再レンダリングします。 1つのビートで数回のパスを想定します。指示は数値ではなく質として届きます。「よりスナップに」、「タイルを分離」、「その要素はノイズなので削除」など。それぞれはタイミング、ずらし、または要素の在庫に対応し、新しいデザインには対応しません。
- 次に、次のシーンへの結合を独自の明示的なステップとして設計します。 シーンは見た目が正しくなった時点では完了しません。その終了と次のシーンの開始が合意された時点で完了します。結合はストーリーボードに含まれていない部分であるため、指示が最も具体的になる場所(「ズームアウトし、次のシーンはカメラから、ズームインされた状態ではなく到着する」)であり、推測が最も無駄になる場所です。
自律的な反復が許可されている場合、これらを内部検証ゲートとして使用し、すべてのビートで承認を要求するのではなく、意味のあるマイルストーンを示します。大規模なタイムラインの場合は、大規模シーンアセンブリ(picsart_scene_recipe で取得、名前 large-scene-assembly)を使用して、コンポーネントを個別に編集可能に保ちます。
その後でのみ次に進みます。ビートテーブルは進行に合わせて更新し続けてください。これは合意された内容の記録であり、ビルドが完了するずっと前にタイムラインは長くなります。
ストーリーボードを読む
- キャンバスの x 順が時間順です。 フレームは左から右に配置されています。名前ではなく
xでソートします。 - フレーム名は嘘をつきますが、順序は嘘をつきません。 重複した名前はよくあります(デザイナーがフレームを複製し、番号を付け直すのを忘れます)。1つが欠落していると結論付ける前に、フレームを番号と照合します。
- 重複した名前のフレームは、通常、1つのビートの A→B ポーズです。 レイヤーセットを比較します。同じ子で異なるトランスフォームは、デザイナーがモーションをデルタとしてエンコードしたことを意味します。そのモーションは測定可能であり、あなたが行わなければならない設計上の決定ではありません。
- ユーザーの Figma Connector を通じてデザインが提供される場合、フレームは一度に1つずつキャプチャします。ボード全体を一度にキャプチャすると、幅が高さよりもはるかに広くなり、細長くなります。
本当にあなたが設計するもの:滞留、イージング、およびペアになっていないフレーム間の結合。
ペアになっていない結合ごとに、モーションシーン連続性(picsart_scene_recipe で取得、名前 motion-scene-continuity)を使用して意味的関係を命名し、永続レイヤー、カタログトランジション、ハードカット、クロスフェード、またはカスタムトランジションを、メカニクスを記述する前に選択します。このストーリーボードワークフローは、ペアになったデザインフレームによって暗示されるモーションの復元を依然として所有します。連続性は、それらの境界における関係と表現のみを所有します。
トランスフォームを解決し、選択しない
未知のピボット C を中心とした一様スケール s は、p → C + s(p − C) をマッピングします。したがって、1組の対応する座標ペアがピボットを固定します:
C = (p2 − s·p1) / (1 − s)
任意の要素のサイズ比から s を取得し、C を解き、次にそれを2番目の独立した要素に対してチェックします。1ピクセルの何分の1か以内で一致すれば、デザイナーの実際のトランスフォームを取得したことになります。不一致は、要素が独自に移動したことを意味し、独自の処理が必要です。
ビートテーブルを書き留めます — 測定されたデルタ、解決されたピボット、時間配分。数値を含む9つの振り付けビートは、スクロールバックでは保持されず、レンダリングと比較したくなります。
モーションルール
完全な詳細と計算例:references/motion-rules.md。ビートが正しく読めるかどうかを決定するルール:
- リジッド vs 独立。 真に独立したオブジェクト(グリッドタイル、ステッカー)に対してのみ、位置/スケールをずらします。カード、ロックアップ、またはパーツを持つオブジェクトは、1つのジオメトリクロックを共有する必要があります。そうしないと、そのパーツが飛行中に位置がずれます。代わりにフェードにずらしを入れます。
- フェードは、1つのジェスチャとして読めるように、モーションと同時に終了する必要があります。 フェードが移動よりも先に終了すると、目は2つのイベントを見ます。イージングカーブも一致させます。
- フラットフレームレンダリングでは、ズームインは安全ですが、平行移動は安全ではありません。 スケールアップで端が露出することはありません。平行移動は画像自体の後端を露出させます。
- サイズエントリトラベル 先頭部分がキャンバスのすぐ外から始まるようにします。トラベル
≥ canvas − leftmost_x。小さすぎると画面上で開始し、大きすぎると無駄な時間になります。 - 終了は加速します(
ease_in)。2つのオブジェクトに異なるスパンを与えて、差動加速を実現します。 - 選択クロームは排他的です — 2つのマーキーを同時に表示せず、そのビートよりも長く存続してはいけません。要素ステップのスパンが重なる場合、要素は操作中に選択を失います。
オーサリングを変えるレンダリングの事実
- 不透明度は線形光で合成されます。 エンコードされた sRGB 値をスケーリングしません。測定された明るさにヒットするには、ガンマを介して変換します:
opacity = linear(target) / linear(source)。 - 不透明度は、黒い背景に対する暗さのコントロールにすぎません。 明るい背景では、背景が透けて見えるため、暗い被写体が明るくなります。本当の減光には、被写体の不透明度ではなく、上部に暗いスクリムが必要です。
anchorは非中心ピボットを提供します(レイヤーの左上からのレイヤーローカルピクセル)。コーナーピボットスケーリングに使用します。たとえば、選択ボックスの左上を中心にスケーリングして、右下のハンドルをドラッグしているように読み取らせます。位置キーフレームでピボットを偽装しないでください。- 文字ごとのテキストアニメーションは組み込まれています。 テキストレイヤーの
content.animations[]は、After Effects アニメーター + 範囲セレクターです。basedOn: "character"、さらにちらつき用のrandomizeOrder/randomizeSeedがあります。異なるシードでエントリをスタックすると、同期してビートを刻みません。アクティブなスパンは[start + offset, end + offset]です。狭いウィンドウは、offset: 1 − endでその遠端をテキストの末尾に固定するか、offset: 1 − start(startが 0 の場合のみ1 − w/1。それ以外では使用しない)ですべてのグリフをクリアします。ランプ形状の FULL ウィンドウ(start:0,end:1)は、代わりにテキストの幅とまったく同じ1つのランプです。offsetを-1 → 1にスイープすると、各グリフは一度にすべて切り替わるのではなく、位置によってずらされてスイープの半分にイージングします。計算例については、picsart_scene_capabilitiesのtextAnimationAuthoring.rawSelectorを参照してください。 - インライン SVG は、
#をパーセントエンコードして URL エンコードする必要があります。 生の#は URI フラグメントを開始し、最初の16進カラーで SVG を切り詰めます。 - イージングを測定し、プリセット名を信頼しないでください。 キーフレームウィンドウの 25%/75% で値をサンプリングし、曲線が意図したものであることを確認します。
数値で検証する
縮小されたコンタクトシートを目視で確認すると、誤ったアラームが発生します。これは、測定によって反証される位置エラーを確実に報告します。フル解像度でフレームを比較するか、測定します。
picsart_scene_validateは構造のみをチェックします。レイヤーが何もレンダリングしないシーンでもパスします。picsart_scene_query_layoutはレンダリングせずにボックスを解決します。これを使用して、レンダリングに時間を費やす前に、Figma の数値に対してジオメトリを確認します。これはジオメトリのみです。解決されたボックスは、コンテンツがデコードされるかどうかについては何も示しません。- キャンバス上に何もないギャップを見つけるには、
times: [t1, t2, …]とresolutionをシーンのcomposition.widthおよびcomposition.heightに設定したpicsart_scene_contact_sheetで疑わしい時間を確認します。小さなロゴだけを保持するフレームは、一目で空に見えることがあります。ギャップと呼ぶ前に確認してください。 - コードを実行できる場所では、不変条件を ジェネレーター にアサートとして入れます(解決されたピボットの一致、十分なトラベル、一度に1つの選択、妥当な境界)。これらは、静止画が隠す回帰をキャッチします。
コマンド
コードを実行できる場合は、同じジェネレーターとセルフチェックを維持します。それ以外の場合は、制限された picsart_scene_patch 編集を使用します。picsart_scene_validate で検証し、picsart_scene_query_layout でイベントジオメトリをクエリし、times: [t1, t2](呼び出しあたり最大8回の時間)と resolution をシーンの composition.width および composition.height に設定した picsart_scene_contact_sheet を使用してフル解像度の静止画を検査します。モーションのクレームについては、連続エクスポートビデオを検査します。
ジェネレーターなしでは、各ステップで不変条件を固定するために picsart_scene_patch と picsart_scene_query_layout に依存します。