mcpField
S
svg-stroke-reveal

svg-stroke-reveal

github.com/rheinmirデザイン・UI1075 回インストール2 週間前に更新
リポジトリ

svg-stroke-reveal について

svg-stroke-revealは、ウェブプロジェクトにSVGの線が描かれる効果を加えるスキルです。ビューポート進入時に一度だけ再生するモードと、スクロール進捗に連動するモードを、標準のHTML、CSS、JSで実装できます。

主な機能

  1. 01SVGの線を段階的に表示
  2. 02ビューポート進入時に一度再生
  3. 03スクロール進捗に連動した描画
  4. 04モーション軽減設定への対応
  5. 05標準のHTML、CSS、JSを使用

活用シーン

  1. 01ロゴを画面内で描画
  2. 02署名やアイコンの描画を一度再生
  3. 03スクロールに合わせてルート図を表示

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rheinmir/setup --skill svg-stroke-reveal

インストール後、Claude Code で/svg-stroke-revealを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
demo.html
svg-stroke-reveal.css
svg-stroke-reveal.js

詳細

スキル:svg-stroke-reveal

Vanilla HTML/CSS/JS コンポーネント — SVG 内の <path> の線が、手で描いているように徐々に描画されます。ビューポートを通過するスクロール量(%)に応じて描画するか、ビューポートに入ったときに一度だけ描画します。外部ライブラリ(Anime.js、GSAP)は使用しません。

WHAT

目的とコンテキスト
  • 目的: SVG 内の <path> の線を、スクロール量(%)に応じて、またはビューポートに入ったときに一度だけ徐々に描画します(stroke-dasharray/dashoffset)。外部ライブラリを使わないバニラ実装で、デフォルトでは Rheinmir/uiux-asset のオリジナルをそのまま使用します。
  • トリガー(使用するタイミング):
    • ロゴ/署名/アイコンを、ビューポートに入ったときに「徐々に描画」するエフェクトが必要な場合(1 回だけ実行)。
    • 折れ線グラフ、行程図、ルート線を、スクロールの進行に応じて継続的に「描画」する必要がある場合(実際のスクロール位置に連動し、1 回だけ実行するものではありません)。
    • ユーザーが「スクロール時に SVG を描画」「svg stroke draw」「ロゴを徐々に描画」「path animation reveal」「stroke-dashoffset」または /svg-stroke-reveal と指定した場合。
  • 対象外: 一般的な 7 つのスクロールエフェクト(opacity/translate reveal、stagger text、highlight、nav co、scroll-to-top、scrollspy、parallax)には使用しません。これらは skills/scroll-effects の対象です。アウトラインに変換していない <text> にも使用しません(Rules を参照)。
メンタルモデル

[data-svgr] > <path>×N → getTotalLength() → dasharray = dashoffset = length (非表示) → mode "once"(IO で一度だけ + CSS transition)または mode "scroll"(IO でフラグを有効化 + 1 つの listener rAF で progress に応じて dashoffset を更新)→ reduce-motion:dashoffset = 0 を即時設定

入力と出力の契約
FieldRequired?意味
Inプロジェクトの実際の SVG(線のある <path>)はい<text> は事前にアウトラインに変換する必要があります
Inmode once または scrollはいロゴ/署名 → once;グラフ/行程 → scroll
Inプロジェクトの design.mdいいえ存在する場合は、それに合わせてカラー トークンを変更します
Out[data-svgr] を付与した SVG + プロジェクト内の CSS/JSはいオリジナルファイルをそのままコピーするか、assets/ に合わせて調整します
Outplaywright-verify による検証の証拠はいスクロール時の前/中/後の画像 + once は 1 回だけトリガーされること
ルールと機能
  • RULE-01 (MUST):getTotalLength() は path の内部座標で測定され、CSS transform の影響を受けません。ただし、dasharray の設定後に、path を含む要素を transform: scale(sx, sy) で拡大縮小し、sx != sy(2 軸で不均等に拡大縮小)にすると、描画速度が px 単位で 2 軸間で歪みます。アニメーションは元の length に沿って進む一方で、表示は縦横比が変わるためです。常に viewBox + width/height でサイズを設定し、path を持つ要素自体への、軸ごとに異なる CSS scale は避けてください。
  • RULE-02 (MUST):<text> は stroke-draw できません。[data-svgr] を適用する前に、文字/フォントを実際のアウトライン <path> に変換する必要があります(Illustrator の「Create Outlines」、Figma の「Flatten」、または font-to-path 変換ツール)。<text> に直接適用しても、<text> には getTotalLength() がないため何も起こりません。
  • RULE-03 (MUST):mode "once" は CSS transition を使います(滑らかで CPU 負荷が低い)。mode "scroll" は、スクロール位置と正確に同期させるため、JS でフレームごとに dashoffset を直接設定します。この 2 つの方法を逆にしないでください。
  • RULE-04 (MUST):mode ごとに個別の IntersectionObserver を 1 つずつ使います(once と scroll のロジックを 1 つの observer にまとめないでください。動作が異なるためです。once は 1 回で unobserve し、scroll はフラグを継続的に切り替えます)。また、ページ上の mode "scroll" のすべての SVG で共有する、rAF でスロットリングする scroll listener は 1 つだけにします。SVG ごとに個別の scroll listener を複数設定しないでください。
  • RULE-05 (MUST):playwright-verify で検証します。mode "scroll" の SVG をスクロールして通過する際、dashoffset が徐々に減少することが分かるように前/中/後の画像を撮影します。また、何度スクロールして出入りしても mode "once" の SVG が 1 回だけトリガーされることを assert します。
  • 機能:オリジナルの取得(web/git)+ asset スキル + design.md の読み込み;HTML/CSS/JS の対象プロジェクトへの書き込み;ヘッドレスブラウザーを実行して検証。
失敗の境界
  • アウトラインに変換していない <text> に適用 → 何も起こりません:blocked。先に <path> への変換を依頼してください(RULE-02)。
  • path を含む要素が CSS によって軸ごとに異なる倍率で拡大縮小される → 描画速度が歪みます:failed。サイズ設定を viewBox + width/height に変更してください(RULE-01)。
  • 検証の assert が失敗(dashoffset が徐々に減少しない、once が再度トリガーされる)→ failed。修正してから再検証してください。

HOW

メインワークフロー
StepTypeInputsActionOutputs/exitFailure/next
W01judgmentSVG + 要件mode を once と scroll のどちらかに選択します。SVG がすでに <path> か(<text> ではないか)確認しますmode<text> → 変換するまでブロック
W02effect元の Pen テーブル実行リンクを開き、.html ファイルを丸ごと(+ _assets/)プロジェクトにコピーして、著作権表示コメントを残しますプロジェクト内の元ファイル外部ライブラリを追加できない場合 → B01
W03effectファイル + 実際の SVG + design.md内容/画像/色のみを変更します(path の d= を置換)適用済み SVG—
W04deterministicHTTP 経由で実行するページplaywright-verify で検証します(RULE-05)画像 + assert赤 → 修正して W04 を繰り返す
分岐
IDKindGuard動作Skip / failureRejoin
B01conditional_requiredプロジェクトで外部ライブラリを追加できない(元のバージョン)vanilla の簡易版 assets/ を使用します(Reference — Assets を参照)。読み込んでから ADAPT します—W04
B02conditional_requiredprefers-reduced-motion: reduce初期化時に strokeDashoffset = 0 にし、observer/listener を省略します—W04
検証と停止条件

W04 で決定論的な assert を実行します(scroll モード:画像の前/中/後で dashoffset が段階的に減少すること、once モード:スクロールで画面外に出て戻っても trigger は 1 回のみ)。目視で確認する項目:滑らかさ、線を描く順序。assert が緑になったら停止します。

例
  • 成功例:「画面に入るとロゴが徐々に描画される」→ 4 つの path を持つロゴに data-svgr="once" を設定 → viewport の 30% に入ると順番に描画されます(DOM 順に 160ms の stagger)。画面外にスクロールして戻っても再描画されません。
  • 境界/失敗例: 署名が script フォントの <text> → getTotalLength() がなく、何も描画されません → 停止し、[data-svgr] を適用する前に、アウトラインに変換(Figma の「Flatten」)して <path> にするよう依頼します。
Reference — 元のバージョン — 先に使用(ファイルを丸ごとコピーし、書き直さない)

作者のオリジナルコードは一字一句そのまま、外部リポジトリ Rheinmir/uiux-asset にあります(公開 CodePen = MIT)。実際に動作するギャラリー:https://rheinmir.github.io/uiux-asset/scroll-effects/ 。 手順:実行リンクを開いて実際のエフェクトを確認 → .html ファイルを丸ごと(参照先にある場合は _assets/ フォルダーも)プロジェクトにコピー → 先頭行の著作権表示コメントを残す → 内容/画像/色のみを変更します。ローカルでは HTTP 経由で実行し、file:// は使用しないでください。 オフラインで一式が必要な場合は、git clone --depth 1 https://github.com/Rheinmir/uiux-asset を実行します。

元の Pen — 作者リンク
Interactive Cicada Genomics Landing Page — alyona-mysiura実行 · コード
Scroll-Driven SVG Map Editorial Gallery — knyttneve実行 · コード
Scroll-Driven Godzilla Walk-and-Destroy Animation — creativeocean実行 · コード

このスキルの assets/ は、自作の vanilla 簡易版です。プロジェクトで外部ライブラリを追加できない場合に使用してください。通常は上記の元のバージョンを使用します。

Reference — Assets

assets/demo.html + assets/svg-stroke-reveal.css + assets/svg-stroke-reveal.js — 読み込んでから、プロジェクトの実際の SVG に合わせて ADAPT します(path の d= を置換し、design.md があれば色のトークンを変更します)。そのまま機械的にコピーしないでください。

リファレンス — 仕組み
  • [data-svgr] 内の各 <path> に対して、初期化時に JS が path.getTotalLength() を呼び出し、インラインの style.strokeDasharray = length と style.strokeDashoffset = length を設定します → 線が完全に非表示になります(ダッシュの長さを path の全長と同じにし、offset でダッシュ全体を外側へ押し出します)。
  • Mode data-svgr="once"(1回のみ発動するしきい値 — ロゴ/署名):しきい値 0.3 の IntersectionObserver を使います。ビューポートに入ると、すべての子 path の strokeDashoffset = 0 を設定します → CSS の transition: stroke-dashoffset が1回だけ実行されます → 発動後すぐに unobserve するため、スクロールして一度外れて再び入っても繰り返しません。
  • Mode data-svgr="scroll"(連続的な進捗 — グラフ/道のり):IntersectionObserver は「ビューポート内にある」フラグのオン/オフだけを切り替えます。フラグがオンの間、rAF でスロットルしたスクロールリスナー(リスナーは1つだけ共有し、複数作成しません)が progress = (innerHeight - rect.top) / (innerHeight + rect.height) を 0..1 に制限して計算し、各フレームで strokeDashoffset = length * (1 - progress) を直接設定します。このモードでは CSS transition を使用しません(transition を使うと、線の描画が実際のスクロール位置に追従できなくなります)。
  • 子の <path> が多数ある複雑な path(線の多いロゴ、署名)では、mode "once" の stagger に transition-delay: calc(var(--svgr-i) * 160ms) を使い、JS が DOM 内の path の順番(最初の path が先に描画されます)に従って --svgr-i を割り当てます。
  • prefers-reduced-motion: reduce の場合 → JS は初期化時にすべての path の strokeDashoffset = 0 を即時設定し、両方の observer/listener をスキップします。アニメーションなしで全体の線をすぐに表示します。

Origin

コメント