モーションで映像を作る
モーション とは、ナレーションや解説付き動画のためのルック(見た目と動き)を文章化したものです。映画の見た目(地面、色、タイポグラフィ)と動き(要素の出現、変化、消失の仕方)を定義します。ストーリー、脚本、シーン、タイミングなど、映像そのものは含みません。あなたがストーリーを用意し、モーションが見た目と動きを決定します。フォーマットは SPEC.md (motion/0.5) です。モーションは、その ID、作成者の GitHub 名、スラッグによって識別されます:@iamsuosi/lab-notebook。motionhub では、すべての ID に両方が存在します。
モーションはディレクトリです:
| ファイル | そこから取得するもの |
|---|---|
motion.json | スコープとスラッグ(合わせて ID)、バージョン、名前、一行説明、作者、ライセンス。lang は MOTION.md の言語。fit はそのモーションの用途。 |
MOTION.md | 言葉で書かれたルック。常に 5 つのセクション: Essence(本質)、Colour(色)、Type(タイポグラフィ)、Motion(動き)、Avoid(避けるべきこと)。フォーマットの定義: https://github.com/motionhub-dev/motions/blob/main/SPEC.md#5-motionmd |
tokens.json | W3C デザイントークンとしての正確な値: color(色)、font(フォント)、多くの場合 duration(時間)と cubicBezier(イージング) |
poster.jpg | そのモーションで作られた映像の1フレーム |
CREDITS.md | 必要とされるすべてのフォントとアセットと、そのライセンスおよびソース |
react/ | React エンジン用のモーションのコンポーネント(セクション5): parts/(部品)、それらが assets/ でインポートするファイル、および各コンポーネントの画像が previews/ にあります |
<tool>/ | 他のツール向けの既製パーツ。使用していないツールのディレクトリは無視してください |
モーションは単一のファイルである場合もあります:spec、name、tokens をフロントマターに持つ MOTION.md で、短い形式(floor: "#E8D5B7")です。これは tokens.json と同じ内容を表し、コンポーネント、ポスター、クレジットは含みません。
1. モーションを選ぶ
- 誰かが名前を指定した場合(名前、ID、または
motionhub.dev/m/<id>リンク): それを使用します。 - プロジェクトにモーションがある場合: プロジェクトルートの
MOTION.md、またはmotion/MOTION.mdがあればそれを使用し、セクション3へ進みます。プロジェクトに複数のモーションがmotions/に格納されている場合があります:motionhub からのコピーはmotions/@<scope>/<slug>/に、独自のものはmotions/<name>/にあります。各シーンが計画されているモーションを使用します。計画に明記されていない場合は、どれを使用するか尋ねてください。プロジェクトにはframe.mdやdesign.mdなどの他のデザインファイルが含まれることもあります。モーションが映像の見た目と動きを決定します。モーションが定義していない部分については他のファイルに従い、矛盾があればユーザーに伝えてください。 - それ以外の場合 検索します:
npx @motionhub/cli search <words>(単語なしで全てリスト表示)、またはインデックスhttps://motionhub.dev/api/motions.jsonを読み取ります。各行にはslug(ID)、name(名前)、line(一行説明)、fit(用途)、catalogs(カタログ)、tags(タグ)、lang(言語)、poster(ポスター)、package(パッケージ)があり、パスはhttps://motionhub.devからの相対パスです。映像の形式から始めます:catalogsはモーションが属するカタログを指定します(explainers、data、stories、tutorials、breakdowns、およびユーザーが持参した動画に描画するためのfootage。これはユーザーが持っている場合のみ提供します。https://motionhub.dev/api/catalogs.jsonに一覧があります)。次に、主題とメディアをfitと照合します。fit.forは適している対象を、fit.notは苦手な対象を示します。その映像の主題に特化して作られたモーションは、汎用的なモーションよりも良い選択です。ポスターと共に 2~3 個提案し、ユーザーに選んでもらいます。ユーザーから依頼された場合にのみ、自分で選択します。
2. 取得する
モーション全体をプロジェクトにコピーして、映像が作成されたバージョンを維持します:
npx @motionhub/cli get <id> # ./motions/<id>/ に、インデックスの SHA-256 と照合してコピー、motions.lock.json に記録
npx @motionhub/cli get # motions.lock.json に記録されている全てのモーションを、プロジェクトにそれがあり不足している場合に取得
映像は、パートごとやシーン種類ごとに複数のモーションで作成される場合があります。それぞれを取得し、./motions/ 内に並置します。./motions/@<scope>/ 内のコピーは決して変更しないでください。適応させる場合は、./motions/<name>/ にコピーしてそこで変更します。
Node がない場合:https://motionhub.dev/m/<id>/<version>.tgz をダウンロードし、行の package.sha256 と照合して、展開します。シェルがない場合、https://motionhub.dev/m/<id>/MOTION.md、tokens.json、motion.json、CREDITS.md を一つずつ取得します。
3. 全体を読む
何かを描画する前に MOTION.md を全て読み、tokens.json も併せて読みます(フロントマターに tokens がある場合はそれも)。作業言語に一致する MOTION.<lang>.md がある場合は、それを読んでも構いません。MOTION.md にない内容は含まれません。
4. 映像を作る
- 値は正確です。 すべての色、フォントフェイス、時間、イージングは、モーションのトークンから名前で取得し、使用するエンジンの用語で表現します。フォントトークンはスタックです。そのフェイスを順に使用します。色を目視で近似しないでください。
- Essence(本質)がすべてのフレームを決定します。 各フレームは Essence で名付けられた特性を持たなければならず、モーションがそうでないと述べている領域に逸脱してはなりません。
- Colour(色)と Type(タイポグラフィ)はパレットではなく役割です。 各トークンは、そのセクションで指定された目的にのみ使用します。何も色付けされていないものは、着色しないままにします。
- Motion(動き)はタイミングです。 要素は指定された方法で、指定されたナレーションや音楽に合わせて出現、変化、消失します。動かないと指定されたものは、静止したままにします。
- Avoid(避けるべきこと)は拘束力があります。 作業を完了する前に、映像を Avoid のすべてのポイントに対して確認します。
- 数値をでっち上げないでください。 映像内のすべての図、日付、カウントは、ユーザーのストーリーまたはユーザーが提供したソースからのものです。欠落している場合は、目に見えるプレースホルダーを残し、その旨を伝えます。
- ストーリーはあなたのものです。 各シーンを、この映像が伝える内容に基づいてレイアウトします。ポスターやサンプルの主題、言葉、レイアウトをコピーしないでください。
- コンポーネントはショートカットです。 モーションに
react/または使用中のツール用のディレクトリがある場合は、そのパーツを使用します(セクション5)。ただし、言葉とトークンが依然として優先されます。
5. 使用するエンジンにおいて
モーションに react/ がある場合、ルックを再描画する代わりにそのコンポーネントを使用します。これらは @motionhub/runtime のみをインポートする React コンポーネントであり、バインディングによって使用するエンジンに時間とトークンが渡されます:
| エンジン | バインディング | 方法 |
|---|---|---|
| Remotion | npm i @motionhub/remotion | コンポジションを <MotionProvider tokens={tokens}>(import tokens from '../motions/<id>/tokens.json')でラップし、<MotionFonts /> を追加し、../motions/<id>/react/parts/<file>.tsx からコンポーネントをインポートします。複数のモーションがある場合は、各シーンを @motionhub/runtime の <MotionScope tokens> でラップします |
| HyperFrames | npm i @motionhub/hyperframes、次に npx motionhub-hyperframes --out assets/motion(./motions/ 内のすべてのモーションに対して) | assets/motion/motion.css と motion.js を読み込みます。Motion.mount(el, (t) => [...]) で GSAP タイムラインから Motion.components を描画します。複数のモーションがある場合は、それぞれが Motions[<id>] になります |
最初にバインディングの README を読んでください。各コンポーネントの meta は、その目的(purpose)、説明(line)、適合性(fits)、および各パラメータの意味を示します。react/previews/<file>.jpg でコンポーネントの外観を確認できます。使用する場合にのみコンポーネントのコードを読んでください。タイプが progress のパラメータは 0 から 1 の間で変化します。エンジン内で、それを必要とする言葉に合わせてアニメーションさせます。3D で描画するコンポーネントは three をインポートするため、インストールが必要です。Caption(@motionhub/runtime から)は、モーションのキャプションスキンで音声のラインを描画します。各シーンをストーリーに合わせてレイアウトします。コンポーネントはルックであり、映像そのものではありません。
それ以外の場合、またはコンポーネントが描画しないものについては:トークンは DTCG 値であり、npx @motionhub/cli tokens --out tokens.json で単一ファイルのモーションからトークンを出力し、バインディングやテーマとして使用できます。各トークンをエンジン独自の形式に一度だけ、一箇所(テーマモジュール)で変換し、名前でどこでも使用します:
- 色:
$value.hex。 - フォント:
$valueはスタックです。CSS のfont-familyはその名前を順に、各々引用符で囲み、最後にジェネリックを置きます。 - 時間:
$valueは{value, unit}で、s(秒)またはms(ミリ秒)です。フレームを数えるエンジンは、秒にフレームレートを掛けて丸めます。 - イージング (
cubicBezier):$valueは[x1, y1, x2, y2]で、CSS のcubic-bezier(x1, y1, x2, y2)と同じ曲線です。イージング機能のないエンジンはサンプリングします。
| エンジン | テーマ | タイミング |
|---|---|---|
| Remotion | @motionhub/remotion の useMotion()。または、色とフォントスタックをエクスポートする theme.ts。最初のフレームの前に @remotion/google-fonts または @remotion/fonts でフォントフェイスを読み込みます | const {fps} = useVideoConfig()。時間は Math.round(seconds * fps) フレーム。interpolate(frame, [start, start + frames], [0, 1], {easing: Easing.bezier(x1, y1, x2, y2), extrapolateLeft: 'clamp', extrapolateRight: 'clamp'})。オーバーシュートがモーションによって要求されていないため、spring() よりもモーションの曲線を使用した interpolate を推奨します |
| HTML と CSS | :root のカスタムプロパティ(--color-ink: #1B2A47) | 時間と cubic-bezier(...) を使用した transition または animation。Web Animations API は同じ easing 文字列を受け入れます |
| GSAP | 同じカスタムプロパティ | 秒単位の duration。CustomEase.create('arrive', 'M0,0 C x1,y1 x2,y2 1,1') による曲線 |
モーションに使用中のエンジン用のディレクトリ(remotion/ など)もある場合、そのパーツがコンポーネントに追加されます。最初にその README を読んでください。
6. フォントとクレジット
CREDITS.mdで指定されたフォントフェイスを、そのソースから、そのライセンスに基づいてインストールします。利用できない場合は、同じ役割で最も近いオープンフェイスを使用し、その旨をユーザーに伝えます。CREDITS.mdで指定されたアセットは、そのライセンスに基づき、要求されたクレジットを付与して使用します。license.textはモーションの言葉、トークン、画像をカバーします。CC-BY-4.0とCC-BY-SA-4.0はクレジットを要求します。映像の説明またはエンドクレジットに次のような行を追加します: Look: Ink Scroll by SuoSi, motionhub.dev/m/@iamsuosi/ink-scroll, CC BY 4.0.license.codeはツールディレクトリ内のコードをカバーします。
7. 変更と、自分自身のルックの共有
1 つの映像のために、モーションを自由に適応させます。その場合は、自分自身のコピー(./motions/<name>/)で行います。変更されたコピーは元のバージョンではなくなります。同じ ID とバージョンで公開しないでください。
ユーザーが作成したルックを公開するには(ユーザーが依頼した場合のみ):
npx @motionhub/cli init <slug> --github <their GitHub login>で、必要なすべてのファイルが入力された./motions/<slug>/が、モーション@<their login>/<slug>として作成されます(ユーザーにログインを尋ねてください。gh でサインインしている場合、--githubは省略可能です)。- 映像ではなく、ユーザーのプロジェクトからルックを取得します。テーマの色とフォントフェイスを
tokens.jsonに(プロジェクトが使用する時間と曲線と共に)。MOTION.mdは 5 つのセクションで、このルックを共有するすべての映像に共通することを記述し、この映像のストーリーについては何も記述しません。CREDITS.mdは、すべてのフォントフェイスとアセットをライセンスと共に指定します。motion.jsonのfitは正直に記述します。3 つの無関係な主題を扱える場合のみgeneral、それ以外は対象の主題を指定したtopic、またはユーザー自身の映像に重ねる場合はoverlayとします。 poster.jpg:ユーザーの映像の 1 フレーム。JPEG 形式で、幅 960 ~ 3840 ピクセル、最大 500 KB とします(Remotion の場合:npx remotion still <composition> poster.jpg --frame=<n> --image-format=jpeg)。- オプションで、再利用可能なコンポーネントを、CONTRIBUTING.md の説明に従って
react/parts/に配置します。reactと@motionhub/runtimeのみをインポートし(Remotion では、Remotion の代わりに@motionhub/runtimeからuseTime()とuseVideoConfig()を使用)、変化する部分を props として受け取り、この映像のストーリーを含まない React コンポーネントです。 - ユーザーの承諾を得たら、
npx @motionhub/cli share motions/<slug> --waitを実行します。このコマンドは、プルリクエストで実行されるチェックを実行し、motionhub.dev にアップロードします。git、gh、GitHub トークンは必要ありません。ユーザーにリンクと、表示されたコードを、そのままの形で提供します。ユーザーはリンクを開き、GitHub でサインインし、モーションを確認し、コードを入力して DCO を証明すると、motionhub がユーザー名でプルリクエストを開きます。コマンドはプルリクエストのアドレスを出力するので、それもユーザーに提供します。コードを入力したり、ユーザーに代わって送信したりしないでください。ユーザーが gh を使った独自のフォークを希望する場合、npx @motionhub/cli share motions/<slug> --prで対応します。
単一ファイルのモーションも、ステップ1 から同じ方法で公開します。その後、npx @motionhub/cli tokens --out motions/<slug>/tokens.json で値を書き出し、その name と lang を motion.json に、ボディをフロントマターなしで motions/<slug>/MOTION.md に配置します。motion.json、CREDITS.md、poster.jpg の残りの部分は以下と同様に記入します。
ユーザーが公開したモーションの新しいバージョンを公開するには(ユーザーが「このプロジェクトから @/ の新しいバージョンを公開して」と依頼した場合のみ):
- モーションを入手します。ユーザー自身のコピーが
./motions/<name>/にある場合、またはnpx @motionhub/cli get @<scope>/<slug>を実行し、./motions/@<scope>/<slug>/を./motions/<slug>/にコピーしてそこで変更する場合。 MOTION.mdがルックであると述べていることに従い、ユーザーのプロジェクトから必要な変更を行います。新しいルックは新しいモーションです。motion.jsonのversionを公開されたバージョンより上げます。修正の場合はパッチ、コンポーネントやセクションの追加はマイナー、そのモーションで既に作成された映像が互換性を失う変更はメジャーとします。公開されたバージョンは決して変更されません。npx @motionhub/cli share <dir> --waitを上記と同様に実行します。ユーザーがリンクを開いて送信します。そのモーションのプルリクエストが既に開いている場合、新しいバージョンが追加されます。変更できるのはモーションの作者の 1 人だけです。別の作者が共有すると、独自のプルリクエストが開かれます。--waitは最大 30 分待機します。
プルリクエストのレビューコメントに基づいてモーションを変更するには、コメントを読み(https://api.github.com/repos/motionhub-dev/motions/issues/<n>/comments および .../pulls/<n>/comments、トークン不要)、要求された変更を行い、再度同じ方法で共有します。
他の人のモーションを基に構築するには、自分自身のスコープで公開し、motion.json の basedOn にそのモーションを指定します([{"id": "@iamsuosi/lab-notebook", "version": "1.0.2"}])。CREDITS.md で何を取り、何を変更したかを記述します。元のモーションを変更できるのはその作者だけです。
8. 引き渡す前に確認する
モーションに poster.jpg がある場合は、作成した映像の 1 フレームをそれと並べます。同じ地面、同じ役割の同じ色、同じフォントフェイスであることを確認します。次に、Essence と Avoid を映像に対して再度読み、適合しない点を修正します。