shaders-cursor-ripples について
既存ページの内容を保ちながら、画像に Shaders の CursorRipples 効果を加えるコーディングスキルです。アクセシブルなフォールバックも扱います。
主な機能
- 01フレームワーク別の Shaders インポート
- 02カーソル連動の画像変形
- 03WebGPU と動きの設定確認
- 04フォールバック付き遅延読み込み
- 05レイヤー構成と検証の手順
活用シーン
- 01既存画像へのリップル効果の追加
- 02独自スポットライト表示の置き換え
- 03WebGPU 非対応時のメディア維持
- 04動きの軽減設定とポインター動作の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mengto/ skills --skill shaders-cursor-ripplesインストール後、Claude Code で/shaders-cursor-ripplesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
REFERENCES.mdagents/openai.yamlassets/react/cursor-ripple-media.csscursor-ripple-shader.tsx詳細
Shaders Cursor Ripples
基本契約
- 既存のページ、コンテンツ、意味的な画像を維持します。
shadersをインストールし、使用中のフレームワークのサブパスからインポートします。- 1 つの
Shaderキャンバスを通して元画像をレンダリングします。 ImageTextureの後にCursorRipplesを配置し、その画像を後処理します。- ルートの
toneMapping="aces"を維持します。 - カーソルの追跡は Shaders に任せます。カスタムのスポットライト座標、放射状マスク、重複した表示画像、ポインターアニメーションループは削除します。
- アクセシブルな読み込み時および WebGPU 非対応時のフォールバックとして、キャンバスの下に実際の画像を 1 つ配置します。
- 視差効果を抑える設定が有効な場合と WebGPU 非対応時は、シェーダーを無効にします。
- ライブラリによって初期ページバンドルが肥大化しないよう、シェーダーコードを遅延読み込みします。
ユーザーがシェーダー効果だけを求めている場合は、参考デザインのリボン、ブロブ、グロー、タイポグラフィ、レイアウト、コピー、色、またはアイデンティティを流用しないでください。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 を実行します。その後、実際のブラウザーで次の点を検証します。
canvas[data-renderer="shaders"]が1つだけ存在することを確認します。- シェーダーが ready クラスに到達し、フォールバック画像が表示されたままであることを確認します。
- メディア内の複数の位置にポインターを移動します。切り離された円が現れず、歪みがその軌跡に沿って動く必要があります。
- リンクとコントロールがクリックできることを確認します。
- コンソールにエラーや警告がないことを確認します。
- WebGPU が利用できない場合や、動きを減らす設定が有効な場合も、静的画像が表示されたままであることを確認します。
- 古い
data-reveal-hoverレイヤーや放射状マスクレイヤーが存在しないことを確認します。 - キャンバスの初期化後に、モバイルとデスクトップでの切り抜きを確認します。
失敗の診断
- キャンバスは存在するが空白になる: ラッパーの寸法がゼロではないこと、画像 URL が同一オリジンであるか CORS で読み取れることを確認します。
- 画像は描画されるが波紋が出ない:
CursorRipplesをImageTextureの後に置きます。子要素/入力サーフェスが必要です。 - 波紋の位置がずれる: 手動のポインター変換を削除し、変換された祖先要素によってキャンバスの境界が変わっていないか確認します。
- SSR 中にページがクラッシュする: シェーダーをクライアント専用の遅延読み込みコンポーネントに移します。
- 読み込み時に画像がちらつく: フォールバックを維持し、
onReadyの後にのみシェーダーをフェードインさせます。 - 初期バンドルが大きくなる: Shaders のインポートが遅延モジュール内だけにあることを確認します。
- エフェクトがボタン操作を妨げる: キャンバスをポインターイベントを透過するようにし、コントロールをより高いスタッキングレイヤーに置きます。
引き継ぎ
影響を受けるメディア、Shaders パッケージのバージョン、フォールバックの動作、動きを減らす設定時の動作、ビルド/テストの結果、実際の操作による検証結果を報告します。ローカルでエフェクトが正常に動作する状態と、公開済みのデプロイを区別してください。