洗濯ロープヒーロー は何をしますか?
ウェブサイトの最初の画面:上部にブランドのバーとナビゲーション、1色のフレーズが入った大きな見出し、導入文、1~2個のボタンと小さな注意書き、その横に空に張られた洗濯ロープが配置されます。ロープには木製ピンで留められた綿布が掛けられ、ブランド独自のポスター(名前、1行の小さなテキスト、2つの大きな単語、仕様欄、小さな棒グラフ)が印刷されています。時々そよ風が布を持ち上げ、雲が背後を漂います。
触れるように設計されています。布の上にポインターを移動させると指先でへこみます。押してドラッグすると、布が手につられて動きます:角を引き上げたり、ロープの上に折り返したり、手前に伸ばしたり。離すと布は落ち、揺れて、静止します。スマートフォンでは指で同じ操作ができ、布を掴んでいる間はページはスクロールしません。布はシミュレーションされています(伸び、せん断、曲げの制約で結ばれた粒子グリッドが固定120Hzで更新)。そのため、常に同じアニメーションを再生するのではなく、掴んだ場所に応じて布のように振る舞います。
ヒーローと印刷内容をhero.jsonで記述します。ビルドはすべてをチェックし、out/index.html(1ファイルにまとめられたページ全体)とout/embed.html(既存サイトに貼り付けるセクション)を書き出します。シミュレーションは静止状態から固定ステップで動作するため、record.mjsでフレームごとに進めることができます:動画では描画されたポインターが角を引き、離し、布の上を指先でなぞる様子が映し出され、訪問者ができる操作をどのマシンでも同じように示します。
これではないもの:布は破れたり、絡まったり、ロープから吹き飛んだりしません(自己衝突はないので、強く折りたたむと貫通して落下します)。印刷はあなたの言葉からページが描画するもので、アップロードした写真ではありません。
必要なもの
- Node.js 18以降。インストールは不要です。
- Chrome、Chromium、またはEdge:チェックと録画用(スクリプトが自動検出します。見つからない場合は
CHROME_PATHを設定してください)。 - ffmpeg:動画用(
brew install ffmpeg、winget install ffmpeg、apt install ffmpeg、またはFFMPEG_PATHを設定)。 - ページを開く際のインターネットアクセス:three.jsとフォントはjsDelivrから固定バージョンで整合性ハッシュ付きで読み込まれます。アクセスがない場合、訪問者には静止画(同じロープと布が平面的に描画されたもの)とシステムフォントが表示されます。ページは動作します。
このスキルのフォルダは<skill>以下です:このSKILL.mdがあるフォルダです。
手順
1. ブランドとテキストを収集する
相手に尋ねるか、現在のサイトで以下を見つけてください:
- 名前、ロゴのSVGファイル(正方形に近いもの。プレーンなもので、スクリプトなし)。ない場合は、3文字以内でモノグラムを作成します。
- 色:背景色(空の地平線の色でもあります。テキストの色はこれに対して7:1のコントラスト比が必要)、1つのアクセント色。明るい青は濃いテキストで正午の空になります。濃いネイビーやプラムは、薄いテキストと低く暖かい太陽で夕暮れの空になります。
- フォント:見出しと布の大きな単語用のディスプレイ書体、残り用の書体。これらは固定されて検証済みで読み込まれます:Space Grotesk、Inter、Instrument Sans、Instrument Serif、DM Sans、Manrope、Fraunces、Sora、Outfit、Bricolage Grotesque、IBM Plex Sans、JetBrains Mono、Plus Jakarta Sans、Newsreader、Playfair Display。他のGoogle Fontsファミリーも(固定されずに)動作します。
- ページ上のテキスト:色付けするフレーズを含む数語の見出し、それが何で誰のためのものかを説明する1~2文、メインボタンとオプションのセカンダリボタン(リンク先)、最大5つのナビゲーションリンクとバーのボタン。見出しの上の小さなバッジとボタンの下の注意書きはオプションです。
- 布上のテキスト:上部に印刷する名前(製品とバージョンが多い)、その下の1行の小さなテキスト、2~4個の大きな単語(2行が最適)、最大6つの短い仕様ペア(ラベルと値)、グラフのキャプション、コーナー用のWebアドレス。
すべての名前、数字、主張、日付は相手から得てください。スペックや数値を発明しないでください。代わりにスペックを省略してください。グラフの棒はデータではなくシードから描かれる装飾です:数字を主張しないキャプションをつけるか、オフにしてください。
2. hero.jsonを書く
近い例フォルダをコピーしてすべてを置き換えてください:examples/paperwind/(メモアプリ、明るい正午の空、4つのピン)またはexamples/halden/(リネンブランド、夕暮れの空、3つのピン、より正方形の布)。
| フィールド | 説明 | 制限 |
|---|---|---|
brand.name、brand.href | 左上の名前とリンク先(デフォルトは/) | 28 |
brand.logo | hero.jsonの隣にある.svgファイル。ページにインライン化されます。または3文字までのモノグラム | – |
nav[] | 最大5つの{ "label"、"href" }をピル型で(スマホでは非表示) | 18 |
action | 右上のボタン、{ "label"、"href" }。falseでなし | 22 |
hero.badge | 見出し上の小さな大文字の行 | 40 |
hero.title | 見出し。*phrase*でアクセント色に。\nで改行(最大3行) | 72 |
hero.lede | 何で誰のためのものか。インラインマークダウン:code、links、bold、italic | 220 |
hero.actions[] | 1~2個の{ "label"、"href" }:最初が矢印付きの塗りつぶしメインボタン、2番目がアウトラインボタン | 26 |
hero.note | ボタンの下の小さな行 | 90 |
hero.align | left(ロープと布は右側、デフォルト)またはright(ミラー)。centerは布をコピーの後ろに置きます(非推奨) | – |
theme.background、theme.ink、theme.accent | 16進数カラー。inkはbackgroundに対して7:1のコントラストが必要 | – |
theme.mode | lightまたはdark。省略時は背景から自動判別 | – |
theme.fonts | { "display"、"body"、"weight" }:ファミリー名(falseでシステムフォント)と見出しのウェイト(300~800、デフォルト500) | – |
theme.scrim | 0~1:コピーの後ろの空を背景色でどの程度薄めるか。デフォルト0.3 | – |
effect | 空、ロープ、布(以下を参照) | – |
motion.speed | 0.25~2、デフォルト1:すべての動きの速度 | – |
motion.pointer | true(デフォルト) | – |
meta | 検索とプレビュー用のtitle(70)とdescription(170)。urlとimage(完全なhttpsアドレス)、lang(デフォルトen) | – |
印刷内容(effect):printTitleまたはprintHeadlineの少なくとも一方が必要です。
| 設定 | 制限 | デフォルト | 説明 |
|---|---|---|---|
printTitle | 28文字 | なし | 印刷の上部にある名前 |
printLine | 64文字 | なし | 名前の下の1行の小さなテキスト |
printHeadline | 48文字 | なし | 大きな単語。\nで改行。列に収まるように縮小されます |
printSpecs | 0~6個の{ "label"、"value" }、12文字と14文字 | なし | 右側の仕様欄。ラベルは大文字で印刷 |
printChart | true / false | true | スペックの下の小さな棒グラフ。最も高い棒がtheme.accent色に |
printChartLabel | 32文字 | なし | グラフの下のキャプション |
printFoot | 40文字 | なし | 下部コーナーの小さなテキスト(例:Webアドレス) |
cloth | 色 | #ecebe6 | 綿布の色 |
printInk | 色 | #15181d | 印刷の色。clothに対して7:1のコントラストが必要 |
シーン(effect)、すべての設定はオプション:
| 設定 | 範囲 | デフォルト | 説明 |
|---|---|---|---|
seed | 1~9999 | 7 | 雲とグラフの棒のシード |
skyTop | 色 | ライトモードは#5f9be0、ダークモードは背景を暗くした色 | ヒーローの上部の空の色 |
skyBottom | 色 | theme.background | 地平線の空の色 |
clouds | 0~1 | 0.6 | 空の雲の量。0は晴天 |
cloudColor | 色 | ライトモードは白、ダークモードは柔らかい紫がかった灰色 | 雲の色 |
drift | 0~1 | 0.35 | 雲の流れる速さ |
light | day、dusk | ライトモードはday、ダークモードはdusk | 真上からの真昼の太陽、または低く暖かい太陽と涼しい空の光 |
aspect | 0.8~1.7 | 1.35 | 布の幅対高さの比率 |
pegs | 2~6 | 4 | 上端に沿った木製ピンの数 |
peg | 色 | #c39a64 | ピンの色 |
rope | 色 | ライトモードは#6f6a62、ダークモードは#cfc6b8 | ロープの色 |
breeze | 0~1 | 0.45 | そよ風が布を持ち上げる強さ |
weave | 0~1 | 0.5 | 近くで平織りがどの程度見えるか |
poke | 0~1 | 1 | ポインターの下のへこみの深さ。0でオフ |
drag | true / false | true | 訪問者が布を掴んで引っ張れるようにする |
size | 0.6~1 | 0.76 | コピーの横のスペースのうち布が占める割合(引っ張る余地を残す) |
hint | 40文字 | "押す · 引く · 離す" | ワイドスクリーンで遠くの下部コーナーにある小さなキャプションで、訪問者に触れられることを知らせます。" · "で部分を区切ります。空の文字列でなし |
作成のヒント:ページ上の見出しと布の大きな単語は異なる内容にしてください。布はポスターのように読まれるので、単語は少なく大きく保ちます。2~3の仕様ペアが6つより読みやすいです。ブランドが軽やかさ、飛ぶ、乾く、吊るすといった遊び心のあるフレーズを持っているなら、布がその場所です。
3. ビルド
node <skill>/scripts/build.mjs hero.json out
hero.jsonの問題(不足フィールド、文字数超過、範囲外の設定、コントラスト不足、布に印刷が薄すぎるなど)をすべて一度にリストアップし、修正されるまで何も書き出しません。その後、使用した設定と確認すべき点(アクセント色を暗くして見出しが4.5:1で読めるようにしたなど)を表示します。
out/index.html(CSS、スクリプト、ロゴ、静止画をインライン化)、out/embed.html、out/assets/logo.svg(タブアイコン)を書き出します。
4. チェック
node <skill>/scripts/check.mjs out/index.html
ページを390、768、1024、1440ピクセルで読み込み、各解像度で「ok」と表示する必要があります:画面より広いものや途切れているものがない、背景の空に対するすべてのテキスト行のコントラストが読める、すべてのリンクとボタンに名前がある、h1が1つ。・でマークされた行は確認が必要ですが、失敗にはなりません。
5. 見て、触る
node <skill>/scripts/record.mjs out/index.html --still 1.6 --size 1440x900
node <skill>/scripts/record.mjs out/index.html --still 3.5 --size 1440x900
node <skill>/scripts/record.mjs out/index.html --still 1.6 --size 390x844 --scale 2
node <skill>/scripts/screenshot.mjs out/index.html
1つ目は静止時の布、2つ目は引き中の状態(スクリプト化された手が角を持ち上げている)、3つ目はスマートフォンです。それらを見てください:布全体が周囲に余裕を持って画面に収まっているか、印刷が読めるか、ピンがロープに乗っているか? screenshot.mjsはGPUなしでChromeを実行するので、WebGLがない場合やネットワークが失敗した場合に訪問者に表示される静止画(out/screens/内)を表示します。それも読めるか確認してください。
その後、ブラウザでout/index.htmlを開いて遊んでください:ホバー、押す、角をロープの上に引っ張る、離す。スマートフォンでは指でドラッグし、布の横をスワイプしたときにページがスクロールするか確認してください。
6. 動画を録画する
node <skill>/scripts/record.mjs out/index.html --seconds 10
ヒーローを10秒間、30fps、1920×1080でステップ実行し、out/preview.mp4とout/poster.png(3.5秒のフレーム、中途半端な引き)を書き出します。動画では、描画されたポインターが2.2秒で下の角を掴み、手前に引き上げ、4.4秒で離し、6秒から布の上を指先でなぞります。オプション:--size 1080x1350(縦長)、--size 1080x1920、--fps 60、--poster 1.6。フレームはどのマシンでも同じです(録画は常に0から開始します)。
7. 公開する
- ページとして:
out/index.htmlとout/assets/を任意の静的ホスト(Cloudflare Pages、Netlify、Vercel、GitHub Pages、S3)にアップロードします。meta.imageとしてout/poster.png(または1200×630にトリミングしたもの)をサイトと一緒にアップロードします。 - 既存サイトに埋め込む:
out/embed.htmlをヒーローが表示される場所に貼り付けます。すべては#mh-washing-lineのスコープ下にあります。フォントの<link>は必要に応じて<head>に移動できます。サイトに既に<script type="importmap">がある場合は、埋め込みのimportsとintegrityエントリをマージします。セクションはビューポート全体の高さです。--mh-heightを設定して(例:style="--mh-height:760px")高さを調整します。Reactや他のフレームワークでは、マークアップをコンポーネントに、<script>タグをページに配置するか、iframeでレンダリングします。 - 印刷内容を変更するには、
hero.jsonを編集して再度ビルドします。
トラブルシューティング
build: fix hero.json first:各行がフィールド名と変更内容を示します。色の問題は動作する色を提案します。- 布が端で切れている:
sizeを下げるか、布をより正方形にします(aspectを1に近づける)。 - 布の大きな単語が小さい:仕様欄の横に収まるように縮小されます。単語を減らすか、
\nを使用するか、スペックを減らしてグラフをなしにします(単語が全幅を使用します)。 - 布が落ち着かない、または羽ばたきすぎる:
breezeを下げます。 - へこみが強すぎる、または弱すぎる:
pokeを調整します(0でオフ。ドラッグは動作します)。 record: the effect didn't start:ページが静止画にフォールバックしました:ChromeがjsDelivrからthree.jsを読み込めなかった(接続またはプロキシを確認)か、WebGLがありません。ffmpeg not found:インストールするかFFMPEG_PATHを設定します。- 訪問者に静止した布が表示される:ブラウザでWebGLがオフになっているかCDNがブロックされている(平面画像)、またはモーション削減が要求されています(動かない静止状態の布の1フレーム)。これは設計によるものです。
- スマートフォンでページがスクロールしない:指が布を掴んでいる間だけスクロールが止まります。布の横をスワイプしてください。布がスマートフォンの画面を埋めている場合は、
sizeを下げます。
ファイル
scripts/build.mjs、scripts/record.mjs:実行するスクリプト。Motion Heroesキットを呼び出します。scripts/kit/:すべてのMotion Heroesスキルで共有されるキット:ビルドとチェック(build.mjs)、セクションのCSS(shell.css)、ブラウザランタイム(runtime.js:クロック、一時停止、ピクセル比、モーション削減、フォールバック)、レコーダー(record.mjs、cdp.mjs)、固定されたthree.jsとフォント(three.json、fonts.json)、それらを説明するKIT.md。scripts/effect/:洗濯ロープそのもの:effect.mjs(設定、チェック、静止画)、effect.js(空のシェーダー
…
[truncated for translation]