avatar について
物体を、単色のシルエットとカプセル形の目で構成するアニメーションキャラクターにするスキルです。視線、ムード、ページへの反応、動きを抑える設定、表示確認の実装を案内します。
主な機能
- 01単色シルエットと2つの目を描画
- 02視線、まばたき、呼吸、体の動きをアニメーション化
- 03数値化した目の形でムードを定義
- 04ページ入力に応じたキャラクター反応
- 05画面外で停止し動きを抑える設定に対応
- 06コンタクトシートで動きを確認
活用シーン
- 01物体をアニメーションキャラクターにする
- 02ポインターに反応するキャラクターをページに追加
- 03ムードやテーマごとの表示と動きを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ playful-design/ router --skill avatarインストール後、Claude Code で/avatarを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
face.jsLICENSEsheet.jsagents/openai.yaml詳細
アバター
このスキルは、オブジェクトを小さな生きたキャラクターに変えます。カプセル形の目が2つある単色のシルエットを描き、ひとつのループで全身を動かして、視線を向けたり、まばたきしたり、呼吸したり、反応したりします。
計測した目と、決して止まらない体
face.jsにある視線、目、まばたきの値は、参考映像から計測した正確な値です。アイドル状態以外の表情は、調整の出発点です。目が動いているのに体が止まっているキャラクターは、設計上の問題です。
参考資料の収集はgatherの担当です。参考アニメーションをフレームごとに分解するのはdeconstructの担当です。シルエットのバリエーションを提案するのはprototypeの担当です。インターフェースの動きと300msの予算はmotionの担当であり、キャラクターの体の動きではありません。フレームコストはframesの担当です。結果を開くのはverifyの担当です。
1. 参考資料を調べる
ユーザーが参考キャラクターを指定したら、そのソースを開き、録画を10fpsでコマ送りして確認します。フレームから目の大きさ、傾き、間隔、まばたきのタイミングを計測します。参考資料を一目見ただけでキャラクターを描くのは、avatar-measure-the-referenceに該当します。
計測した値はそのまま使います。目の間隔の15.5°を15°に丸めたり、180msのまばたきを200msに丸めたりするのは、avatar-keep-the-measurementsに該当します。参考資料が指定されていない場合は、face.jsを出発点にします。
2. シルエットを描く
オブジェクトを、彩度の高い1色で塗った単色の形に単純化します。輪郭線、陰影、口、鼻を加えるのは、avatar-flat-silhouetteに該当します。
通常は28〜40pxの、実際に使われるサイズでも判別できるようにします。14×17のviewBoxなど、小さなグリッド上に描き、viewBoxを図形にぴったり合わせて切り取ります。まぶたのように単独で動く部分には、それぞれ独自のパスを用意します。
輪郭だけでオブジェクトが分かる視点を選びます。容器や道具なら側面、デバイスなら正面です。役割や趣味が指定された場合は、最も象徴的なオブジェクトを1つ描きます。細部がないと何を描いたか分からない視点は、avatar-iconic-viewに該当します。
顔がある部分を主要な塊にします。その部分をその場で大きくし、headの楕円と目幅1つ分の余白が、落ち着いた単色の塗りの上に収まるようにします。幸せな目はアイドル状態の目のほぼ2倍の幅になるため、最も幅広い表情に合わせて大きさを決めます。顔を置くためにブロックを追加したり、目を縮めて収めたりするのは、avatar-face-part-leadsに該当します。
その他の各パーツは、塗りつぶし部分ではなく、内側の空間も含めた輪郭を基準に大きさを決めます。顔のある部分より明確に小さくし、認識に必要な範囲だけ外側に伸ばします。カップと同じ高さの取っ手は、avatar-size-by-outlineに該当します。
首、ふた、縁など、オブジェクトを特徴づけるわずかな段差だけを残し、それ以外の細部はすべて省きます。重なり合ってひとつの輪郭を作る、1〜7個の柔らかな基本図形で形を組み立てます。
すべての接合部は、明確な段差か滑らかなつながりにします。段差は目幅の半分以上とし、滑らかにつなげる場合は、一方の辺をまっすぐ続け、内側の角を隠します。2点で接合するパーツは、両方の点で接合したままにします。輪郭がほぼ揃って細長い隙間や切れ込みができるのは、avatar-clean-joinsに該当します。
穴を開けるのは、マグカップの取っ手やリングなど、実際に開口部がある場合に限ります。塗りつぶしで開口部が塞がれないよう、輪郭に沿って穴を通します。スロット、ボタン、装飾的な切り抜きは、avatar-holes-are-openingsに該当します。
おもちゃのようなプロポーションを保ちます。目の幅より細い部分を作らず、すべての角を丸め、先細りの先端は柔らかく仕上げます。葉や炎などの有機的なパーツは、その曲線と向きを保ちます。極細の線、鋭い先端、楕円形に平たくした葉は、avatar-toy-proportionsに該当します。
塊の重心を中央に置き、平らか、緩やかに丸みを帯びた底面で立たせます。その後、静止時と傾いている途中の両方で、全体の形を28pxで確認します。別のオブジェクトに見えたり、形が崩れて見えたりする場合は、上記のルールをすべて守っていても、パーツのバランスを調整するか、視点を変えます。
色は--avatar-bodyと--avatar-eyesの2つの変数で設定し、両方のテーマで確認します。パスに直接塗りの色を書き込むのは、avatar-colour-variablesに該当します。
3. 球体の上に目を配置する
横幅の約2.2倍の高さがある白いカプセルを2つ、顔の高い位置で右寄りに配置します。頭を約12°傾け、バックスラッシュのように傾けます。
目は顔の背後にある球体の上に配置します。ヨー、ピッチ、ロールで位置を決めるため、端に近づくにつれて細くなり、背後に回るにつれて見えなくなります。顔の上を平面的に滑る目は avatar-eyes-on-a-sphere です。face.js の drawEyes が投影を行います。
体を動かすグループ内で、両目をシルエットのパスでクリップします。輪郭からはみ出して描画される目は avatar-clip-to-the-body です。
4. 体全体に生命を吹き込む
何も静止しません。視線は複数のサイン波を重ねて漂い、1.5〜4sごとに新しい場所へ視線を移します。大きく視線を移すときはまばたきもします。イベントの合間に視線が静止する状態は avatar-never-still です。
まばたきは180msかけて行い、その最初の45%で目を閉じます。まばたきの間隔は1.9〜4.6sで、そのうち18%は二連続です。一定間隔のまばたきは avatar-irregular-blinks です。
体は3.4s周期で1.2%膨らみ、わずかに浮き上がり、視線より少し遅れて視線の方向へ傾きます。目が落ち着くまでの時間は約60ms、体は220msです。体が静止したまま目だけが動く状態は avatar-whole-body です。
5. 目の形から気分を表現する
気分は、目の幅、高さ、傾き、間隔、開き具合、視線のオフセットを表す数値を1行にまとめたものです。約90msかけて指数関数的なイーズアウトで気分をブレンドし、オーバーシュートはしません。気分ごとに別の描画へ切り替える方法は avatar-moods-as-numbers です。
まず、通常、注目、興奮、喜び、眠そう、睡眠中から始めます。このオブジェクトだけができる動きを1つか2つ加えます。たとえば、跳ねた後に遅れて動くまぶたなどです。独自の動きがないキャラクターは avatar-object-move です。
6. リアクションを接続する
各リアクションは、ページからの入力に応答します。
- ポインターが6s間離れていた後に戻ってきます。目が1.1sかけて背後を360°回転し、その後ポインターを追います。
- ポインターが主要なアクションの上に留まります。目を大きく開き、体を少し弾ませます。
- ユーザーがアクションまたはキャラクターを押します。スクワッシュとストレッチを加えながら750ms跳ね、その後、目を細めてうれしそうに戻ります。
- 24s間何も起こりません。眠そうになり、30sでゆっくり深呼吸しながら眠り、回転して目を覚まします。
視線を追う範囲をヨー±45°に制限し、目が顔の上に留まるようにします。また、追跡ではタッチポインターを無視します。周囲のページに反応しないキャラクターは avatar-react-to-the-page です。
キャラクターがページのメインのおもちゃである場合は、距離にも反応させられます。640px以内では好奇心を示し、260px以内では警戒し、100px以内では身を引きます。片方の目をつつくと、もう片方は開いたまま、つつかれた目を閉じます。
7. 1つのループで実行する
1つの requestAnimationFrame ループで face.js の createAvatar を進め、refを通じてSVG属性を書き換えます。タブに戻ったときに動きが飛ばないよう、ステップを64msで上限設定します。フレームごとの状態更新は frames に記述します。
IntersectionObserver を使い、キャラクターが画面内にある間だけループを実行します。画面外でもループを実行し続ける状態は avatar-pause-offscreen です。
restingEyes を使ってサーバー側で静止ポーズを描画し、最初の描画から目が表示されるようにします。ハイドレーション時に顔が突然表示される状態は avatar-render-the-rest です。
prefers-reduced-motion: reduce の場合、キャラクターは静止ポーズを保ち、ループを開始しません。それでも視線を移したり跳ねたりするキャラクターは avatar-still-when-reduced です。キャラクターは装飾用のため、SVGには aria-hidden="true" を指定します。
8. コンタクトシートで検証する
1枚のスクリーンショットでは動きを確認できず、非表示のタブではループがスロットルされます。ブラウザーの評価呼び出しから sheet.js を実行し、続けて window.__avatarSheet.start({ selector }) を呼び出します。
ポインターイベントで各ムードを再現します。アイドル、進入、ホバー、押下、離脱の順です。window.__avatarSheet.stop() を呼び出して、レイアウトされたシートのスクリーンショットを撮ります。証拠として提示する静止フレームは avatar-contact-sheet です。
結果に warning がある場合、タブが非表示だったかループが停止したことを示しており、フレームが繰り返されたり、間隔が広がったりしています。タブを表示したまま、もう一度サンプリングします。スリープには入力なしで30s必要なため、単独で一度サンプリングしてください。
最後に、両方のテーマでキャラクターを製品版のサイズにしてから、window.__avatarSheet.clear() を呼び出します。
ペア
各チェックはペアになっています。問題のある行の隣に、それを置き換える行を示します。
| ルール | 問題のある例 | 置き換え |
|---|---|---|
avatar-measure-the-reference | 参考画像を一度見ただけで配置した目 | 10fpsのフレームを基にサイズ、傾き、間隔、まばたきを測定 |
avatar-keep-the-measurements | きれいに見えるよう丸めた split: 15 | 測定値どおりの split: 15.5 |
avatar-flat-silhouette | 輪郭、陰影、笑顔を付けたカップ | 1つの単色の形と2つの目 |
avatar-iconic-view | 正面から見たジョウロ。箱のように見えます | 側面図。注ぎ口と取っ手でそれと分かります |
avatar-face-part-leads | 目を載せるためマグカップに貼り付けた板、または半分のサイズの目 | 頭とその余白が収まるまでカップを広げる |
avatar-size-by-outline | カップと同じ高さの細い取っ手の輪 | カップより明らかに小さい、コンパクトな取っ手 |
avatar-clean-joins | カップより0.3単位はみ出した蓋の縁が、細い隙間を残す | 目の幅の半分の段差、または縁をぴったり合わせる |
avatar-holes-are-openings | コイン用またはボタン用の切り抜きスロット | 取っ手のように、物体が開いている箇所だけに穴を設ける |
avatar-toy-proportions | 髪の毛のように細い茎と鋭い葉先 | 目の幅以上のパーツ、丸い角、柔らかな先端 |
avatar-colour-variables | パス内の fill="#c27a3e" | テーマごとに設定する fill="var(--avatar-body)" |
avatar-eyes-on-a-sphere | 両目に translate(dx, dy) を適用 | yaw、pitch、rollから drawEyes(face, gaze, lid, head) を描画 |
avatar-clip-to-the-body | 大きく横を向いたとき、目が輪郭からはみ出す | 目を胴体パスの clipPath 内に収める |
avatar-never-still | まばたきの合間に目が静止する | レイヤー状の揺れと、1.5–4sごとの視線移動 |
avatar-irregular-blinks | animation: blink 5s infinite | 180msのまばたきを1.9–4.6s間隔で行い、18%の割合で二度まばたきする |
avatar-whole-body | 目だけが動く | 視線から220ms遅れて、体が呼吸し、浮かび、傾く |
avatar-moods-as-numbers | {happy ? <HappyFace /> : <Face />} | happy: { eyes: pair(0.522, 0.217, 18) } を90msかけてブレンド |
avatar-object-move | ただの塊のように動くカップ | ホップのワンテンポ後に蓋が持ち上がる |
avatar-react-to-the-page | ポインターの動作にかかわらず同じアイドルループ | 進入時に回転、追従、ホバー時に目を見開き、押下時に跳ね、離れるとスリープ |
avatar-pause-offscreen | 画面下で動き続けるループ | IntersectionObserver で開始・停止するループ |
avatar-render-the-rest | ハイドレーション後に目が表示される | サーバーHTML内の restingEyes(head) |
avatar-still-when-reduced | 動きを減らす設定でも視線を動かし、跳ねる | 静止ポーズにしてループを行わない |
avatar-contact-sheet | アイドルポーズのスクリーンショット1枚 | すべてのムードを通した sheet.js シート。その後、両方のテーマで製品版サイズを表示 |
レポート
重大度。 HIGH は、胴体がまったく動かない、目がシルエットからはみ出す、または動きを減らす設定時にも動く場合です。目が平らにスライドする、まばたきが固定されている、ムード別の絵が入れ替わっている、画面外でループする、反応がない、またはスクリーンショット1枚だけで根拠を示している場合は MEDIUM です。オブジェクトの名前を明示していないビュー、窮屈な顔、または大きすぎる二次パーツも MEDIUM です。丸められた測定値、パス内の塗りつぶし、突然表示される待機ポーズ、または固有の動きがないキャラクターは LOW です。接合部の細い隙間、装飾的な穴、または極細のパーツも LOW です。
形式。 根本原因ごとに指摘事項を1つ記載します。
file:line - [rule-id] what is wrong
続けて Rule | Count | Severity のサマリーを記載します。HIGH が1つでも残っている場合は Block、それ以外は Approve とします。開けなかった、または手順を進めて確認できなかった参照には Not verified と記載します。