mcpField
S
shaders-cursor-ripples

shaders-cursor-ripples

github.com/mengtoデザイン・UI7.1k1.4k 回インストール3 日前に更新
リポジトリ

shaders-cursor-ripples について

既存ページの内容を保ちながら、画像に Shaders の CursorRipples 効果を加えるコーディングスキルです。アクセシブルなフォールバックも扱います。

主な機能

  1. 01フレームワーク別の Shaders インポート
  2. 02カーソル連動の画像変形
  3. 03WebGPU と動きの設定確認
  4. 04フォールバック付き遅延読み込み
  5. 05レイヤー構成と検証の手順

活用シーン

  1. 01既存画像へのリップル効果の追加
  2. 02独自スポットライト表示の置き換え
  3. 03WebGPU 非対応時のメディア維持
  4. 04動きの軽減設定とポインター動作の確認

インストール

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

$npx skills add https://github.com/mengto/skills --skill shaders-cursor-ripples

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

同梱ファイル

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

REFERENCES.md
agents/
openai.yaml
assets/react/
cursor-ripple-media.css
cursor-ripple-shader.tsx

詳細

Shaders Cursor Ripples

基本契約

  1. 既存のページ、コンテンツ、意味的な画像を維持します。
  2. shaders をインストールし、使用中のフレームワークのサブパスからインポートします。
  3. 1 つの Shader キャンバスを通して元画像をレンダリングします。
  4. ImageTexture の後に CursorRipples を配置し、その画像を後処理します。
  5. ルートの toneMapping="aces" を維持します。
  6. カーソルの追跡は Shaders に任せます。カスタムのスポットライト座標、放射状マスク、重複した表示画像、ポインターアニメーションループは削除します。
  7. アクセシブルな読み込み時および WebGPU 非対応時のフォールバックとして、キャンバスの下に実際の画像を 1 つ配置します。
  8. 視差効果を抑える設定が有効な場合と WebGPU 非対応時は、シェーダーを無効にします。
  9. ライブラリによって初期ページバンドルが肥大化しないよう、シェーダーコードを遅延読み込みします。

ユーザーがシェーダー効果だけを求めている場合は、参考デザインのリボン、ブロブ、グロー、タイポグラフィ、レイアウト、コピー、色、またはアイデンティティを流用しないでください。Shaders の Water コンポーネントで代用しないでください。CursorRipples はインタラクティブな画像変位効果です。

編集前の確認

  • 実際のメディアラッパー、画像 URL、クロップ、オーバーレイ、z-index、既存のモーションを確認します。
  • ラッパーに 0 ではない描画幅と描画高さがあることを確認します。
  • data-reveal-hover、mask-image: radial-gradient、重複した画像、requestAnimationFrame、手動のポインターリスナーなど、古い表示コードを検索します。
  • シェーダーキャンバスと競合しない限り、無関係な視差効果や表示時のモーションは維持します。
  • パッケージが変更されている可能性がある場合は、インストール済みの shaders のバージョンと現在のフレームワーク API を確認します。

インストール

npm install shaders

shaders/react、shaders/vue、shaders/svelte、または shaders/solid からインポートします。Vite プロジェクトでは、shaders を optimizeDeps.exclude に追加しないでください。CommonJS の依存関係には Vite の事前バンドルが必要です。通常、optimizeDeps の設定は不要です。

商用リリースの前に、Shaders の最新のライセンス条項を確認してください。

必須の構成

以下のコンポーネント順序と値を維持します。

<Shader toneMapping="aces">
  <ImageTexture url={imageUrl} objectFit="cover" />
  <CursorRipples decay={7.3} radius={0.6} />
</Shader>

intensity、chromaticSplit、または edges を調整する前に、これをベースラインとして使用します。ユーザーから参考デザインの生成アートワークを明示的に求められない限り、SolidColor、Blob、Form3D、GaborNoise、Glow、またはその他のジェネレーターを追加しないでください。

React では、assets/react/cursor-ripple-shader.tsx と assets/react/cursor-ripple-media.css をコピーして調整します。

クライアントとフォールバックのパターン

ブラウザーで WebGPU が利用可能で、モーションが許可されていることを確認してから、シェーダーをマウントします。

const CursorRippleShader = lazy(() => import("./cursor-ripple-shader"));

const [shaderEnabled, setShaderEnabled] = useState(false);
const [shaderReady, setShaderReady] = useState(false);

useEffect(() => {
  const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)");

  const sync = () => {
    const enabled = "gpu" in navigator && !reduceMotion.matches;
    setShaderEnabled(enabled);
    if (!enabled) setShaderReady(false);
  };

  sync();
  reduceMotion.addEventListener("change", sync);
  return () => reduceMotion.removeEventListener("change", sync);
}, []);

ラッパー内に意味的な画像を残し、その上に遅延読み込みするシェーダーを重ねます。

<figure className="cursor-ripple-media">
  <img
    className="cursor-ripple-media__fallback"
    src={imageUrl}
    alt={meaningfulAlt}
    width={width}
    height={height}
  />

  {shaderEnabled ? (
    <Suspense fallback={null}>
      <CursorRippleShader
        imageUrl={imageUrl}
        ready={shaderReady}
        onReady={() => setShaderReady(true)}
      />
    </Suspense>
  ) : null}
</figure>

Next.js では、ssr: false を指定した動的インポートも有効です。シェーダーが onReady を呼び出すまで、フォールバックを非表示にしないでください。WebGPU の初期化に失敗しても、ページの内容が読み取れて、完全な状態を保てるようにします。

レイヤーのルール

  • メディアラッパーには position: relative、明示的なサイズ、overflow: hidden、isolation: isolate を指定します。
  • フォールバックの z-index は 0、キャンバスの z-index は 1 にします。
  • position: absolute; inset: 0; width: 100%; height: 100% を指定して、ラッパー全体を埋めます。
  • シェーダーレイヤーには pointer-events: none を指定します。Shaders はグローバルにリッスンし、キャンバスの境界を使ってポインター座標を変換します。
  • シェーダーのラッパーには aria-hidden="true" を設定し、アクセシブルな名前はフォールバック画像に持たせます。
  • 効果が操作を妨げないよう、コピー、リンク、コントロールはキャンバスより上に配置します。
  • フォールバックと ImageTexture で同じクロップを維持します。メディアを全幅表示する場合は objectFit="cover" を使用します。

失敗したスポットライトパターンの削除

古い実装は隠したままにせず、削除してください。

  • 2枚目の表示画像
  • 放射状の mask-image とカスタム表示変数
  • ポインター位置に連動するスモークやぼかしのオーバーレイ
  • コンポーネント内でポインターをイージングする requestAnimationFrame
  • フラッシュライト専用に作られた pointerenter、pointermove、pointerleave、およびリサイズ関連の処理
  • 廃止した表示レイヤーを参照する coarse-pointer ルール

両方のシステムを残すと、座標のずれ、GPU 負荷の増加、紛らわしいフォールバックが発生します。

パフォーマンスとモーション

  • WebGPU のチェック後にシェーダーモジュールを遅延読み込みします。
  • メディアパネル用のシェーダーキャンバスは1つだけにします。
  • ライブラリの onReady コールバックを使って、短時間の不透明度の切り替えを行います。
  • テレメトリが不要な場合は disableTelemetry を使用します。
  • キャンバスのサイズはアニメーションさせず、視差が必要な場合はサイズが安定した親要素をアニメーションさせます。
  • prefers-reduced-motion: reduce の場合は、シェーダーを無効化するかアンマウントします。
  • タッチレイアウトでも静的画像を使いやすくし、エフェクト内に重要な情報を配置しないでください。

検証

プロジェクトの lint、プロダクションビルド、レンダリングテスト、git diff --check を実行します。その後、実際のブラウザーで次の点を検証します。

  1. canvas[data-renderer="shaders"] が1つだけ存在することを確認します。
  2. シェーダーが ready クラスに到達し、フォールバック画像が表示されたままであることを確認します。
  3. メディア内の複数の位置にポインターを移動します。切り離された円が現れず、歪みがその軌跡に沿って動く必要があります。
  4. リンクとコントロールがクリックできることを確認します。
  5. コンソールにエラーや警告がないことを確認します。
  6. WebGPU が利用できない場合や、動きを減らす設定が有効な場合も、静的画像が表示されたままであることを確認します。
  7. 古い data-reveal-hover レイヤーや放射状マスクレイヤーが存在しないことを確認します。
  8. キャンバスの初期化後に、モバイルとデスクトップでの切り抜きを確認します。

失敗の診断

  • キャンバスは存在するが空白になる: ラッパーの寸法がゼロではないこと、画像 URL が同一オリジンであるか CORS で読み取れることを確認します。
  • 画像は描画されるが波紋が出ない: CursorRipples を ImageTexture の後に置きます。子要素/入力サーフェスが必要です。
  • 波紋の位置がずれる: 手動のポインター変換を削除し、変換された祖先要素によってキャンバスの境界が変わっていないか確認します。
  • SSR 中にページがクラッシュする: シェーダーをクライアント専用の遅延読み込みコンポーネントに移します。
  • 読み込み時に画像がちらつく: フォールバックを維持し、onReady の後にのみシェーダーをフェードインさせます。
  • 初期バンドルが大きくなる: Shaders のインポートが遅延モジュール内だけにあることを確認します。
  • エフェクトがボタン操作を妨げる: キャンバスをポインターイベントを透過するようにし、コントロールをより高いスタッキングレイヤーに置きます。

引き継ぎ

影響を受けるメディア、Shaders パッケージのバージョン、フォールバックの動作、動きを減らす設定時の動作、ビルド/テストの結果、実際の操作による検証結果を報告します。ローカルでエフェクトが正常に動作する状態と、公開済みのデプロイを区別してください。

コメント