mcpField
T
threejs-particle-morph

threejs-particle-morph

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

threejs-particle-morph について

threejs-particle-morphは、スクロールに合わせて粒子が画像やロゴに集まり、逆方向のスクロールで再び散らばるウェブ効果を作るThree.jsスキルです。元画像のピクセルをサンプリングして粒子の目標位置を作り、粒子関連の設定を調整できます。

主な機能

  1. 01画像ピクセルから粒子の目標を生成
  2. 02スクロール進捗に応じて粒子が集合
  3. 03逆スクロールで粒子が分散
  4. 04粒子数とサンプリング設定を変更
  5. 05リソースのクリーンアップ方法を提供

活用シーン

  1. 01スクロールに合わせてポートフォリオのロゴを形成
  2. 02粒子で画像を組み立てるスクロール効果
  3. 03逆スクロールで画像を分解

インストール

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

$npx skills add https://github.com/rheinmir/setup --skill threejs-particle-morph

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

同梱ファイル

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

assets/
demo.css
demo.html
demo.js

詳細

スキル:threejs-particle-morph

純粋な Three.js コンポーネントです。3D 空間にランダムに散らばった数千個のパーティクルが、ページのスクロールに合わせて徐々に集まり、ピクセルからサンプリングした画像になり、逆方向にスクロールすると再び散らばります。

WHAT

目的とコンテキスト
  • 目的: Three.js のパーティクルクラウド(THREE.Points + BufferGeometry)を構築します。スクロールの進行度に合わせてランダムな位置から画像/ロゴへ集まり、逆方向にスクロールすると再び散らばります。元の実装をそのままコピーするのを優先し、assets/ のバニラ版は代替手段です。
  • 使用するタイミング:
    • スクロールすると「画像が粒子から組み上がる」演出を加えたいヒーローセクション/ポートフォリオ。
    • ユーザーが「particle image」「粒子が画像に集まる」「point cloud morph」「three.js particle scroll」と言った場合。
  • 対象外: ズームとブラーによる滑らかな画像遷移には使用しません(これは blur の用途です。単一の plane にシェーダーを適用し、個々のパーティクルはありません)。また、WebGL を必要としない軽いスクロールエフェクトにも使用しません(これは scroll-effects の用途です)。作者の元のコードを書き直してはいけません。
メンタルモデル

元画像 → 非表示 canvas(sampleResolution)→ getImageData + stride + alphaThreshold → ターゲット(+ 色) · 開始位置はランダム → スクロール → targetProgress → progress(減衰)→ position = lerp(starts, targets, progress) → PointsMaterial で描画

入力と出力の契約
フィールド必須?意味
In元画像/ロゴ(imageUrl)いいえ指定がない場合 → デモがサンプル用に非表示 canvas へサンプルテキストを自動描画します
InparticleCount、particleSize、sampleResolution、alphaThresholdいいえParticleMorph の初期化パラメーター
Inプロジェクトの制約(外部ライブラリを導入できるか)はい元の実装(デフォルト)を使うか、assets/ のバニラ版を使うかを決定します
Outプロジェクト内のコンポーネントはい元のファイルをそのままコピー(クレジットコメントを保持)するか、assets/demo.* を適応したもの。destroy() を備えます
Out検証結果はいprogress 0/0.5/1 のスクリーンショットと、エラーのないコンソール
ルールと機能
  • RULE-01 (MUST):パフォーマンス:パーティクル数を増やすほど、CPU(毎フレーム position を書き換えるループ)と GPU の負荷が高くなります。ミドルレンジのマシンで推奨される安全な上限は 5,000~10,000 個以下です。particleCount を増やす前に、DevTools の Performance/FPS メーターで測定してください。推測で判断してはいけません。特に、大きくて細部の多い画像用にパーティクルを追加する場合は注意してください(sampleResolution を上げると、init() 時のサンプリングコストも増えます。一度だけ実行されます)。
  • RULE-02 (MUST):Three.js(three)は npm でインストールし(npm install three)、本番環境ではバンドラー経由でインポートしてください。デモはバンドラーなしで単独実行するため、CDN(unpkg.com/[email protected])を指す importmap を使用します。blur がかつて行っていたように、バージョンを固定した古い CDN 版を使用してはいけません。実際のプロジェクトに組み込む際は、<script type="importmap"> を削除し、npm install three を実行して、import * as THREE from 'three' をバンドラー経由のインポートに変更してください。
  • RULE-03 (SHOULD):_buildSamples() の alphaThreshold/明るさフィルターは、透明または暗い背景のピクセルを除外します。透明な背景の画像(PNG ロゴ)は、単色の背景画像(JPEG)よりすっきりした結果になります。単色背景の画像は、事前に切り抜かない限り背景も含めてサンプリングされます。
  • RULE-04 (MUST):playwright-verify で検証してください。3 つの位置までスクロールし、progress 0/0.5/1 のスクリーンショットを撮影します。コンソールも確認してください(WebGL コンテキストのエラーは、通常は明示的な JS エラーを投げずに発生します)。
  • RULE-05 (MUST):まず元の実装を使用し、ファイルをそのままコピーしてください。書き直してはいけません。先頭行のクレジットコメントを保持し、コンテンツ/画像/色だけを変更してください。ローカルでは HTTP 経由で実行し、file:// は使用しないでください。
  • 機能:公開されている外部リポジトリからアセットを読み取り/コピーする。フロントエンドのファイルをプロジェクトに書き込む。HTTP 経由でページを起動し、ヘッドレスブラウザーでスクリーンショットを撮影してコンソールを確認する。
失敗時の境界
  • 元のリンクを開けない/外部ライブラリを取得できない → assets/ のバニラ版を使用します(分岐 B01)。
  • particleCount を増やした際に FPS が低下する → これ以上の増加は blocked とし、再測定して 5,000~10,000 個以下を維持します。
  • コンソールに WebGL コンテキストエラーが表示される(通常は目立たずに発生) → 検証は failed です。引き渡してはいけません。
  • 単色背景の画像で背景までサンプリングされる → 事前に切り抜くか、透明な背景の PNG を使用してください。

HOW

メインワークフロー
手順種類入力アクション出力/終了条件失敗時/次の手順
W01判断プロジェクトの制約使用するソースを選択します。元の Rheinmir/uiux-asset(デフォルト)か、vanilla 版の assets/選択したソース外部ライブラリを追加しない場合 → B01
W02エフェクト実行リンク+コード実行リンクを開いてエフェクトを確認し、.html ファイル全体(+_assets/)をプロジェクトにコピーしますプロジェクト内のファイル、著作権表示コメントあり—
W03エフェクトファイル内容/画像/色のみを変更します(vanilla 版では imageUrl/particleCount/particleSize も変更します)適応済みコンポーネント—
W04決定的HTTP 経由のページplaywright-verify で検証します。progress 0/0.5/1 のスクリーンショットを撮影し、コンソールを確認します画像 3 枚+コンソールにエラーなしWebGL/FPS の問題 → 修正して W03 を繰り返します
W05エフェクト実際のプロジェクト本番用に組み込みます。importmap を削除し、npm install three を実行して、bundler 経由で import しますビルドが実行される—

各手順の詳細(W01~W05 の信頼できる情報源):

元のバージョン — 先に使用(ファイル全体をコピーし、書き直さないでください)

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

元の Pen — 作者リンク
Scroll-Driven Particle WebGL Image Matrix — ycw実行 · コード
GSAP ScrollSmoother and Three.js — cmalven実行 · コード
GSAP ScrollTrigger Disintegration Effect — dev_loop実行 · コード

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

Assets

assets/demo.html + assets/demo.css + assets/demo.js — 内容を確認してから適応します(ParticleMorph の初期化時に imageUrl、particleCount、particleSize を変更します)。Demo は imageUrl が渡されない場合に、非表示の canvas にサンプル文字列を自動描画してサンプリングするため、画像やネットワーク接続がなくてもすぐに実行できます。

仕組み
  • 画像のサンプリング:元画像(または手描きのキャンバス)を、サイズが sampleResolution の非表示の <canvas> に描画し、getImageData() を読み取ります。ピクセルを間引きながら走査します(stride は、希望する particleCount と総ピクセル数から算出します)。すべてのピクセルを取得するのは負荷が高すぎるため避けます。十分に明るく、透明ではない(alphaThreshold)ピクセルを、ターゲット座標と RGB カラーとして保持します。
  • パーティクル:サンプリングした各座標が、THREE.Points(BufferGeometry の position 属性)内の 1 つのパーティクルになります。初期位置(starts)は、広い空間内にランダムに配置します(「爆発」状態)。ターゲット位置(targets)はサンプリングしたピクセル座標です。これらは個別の 2 つの Float32Array に並行して保存します(GPU の属性 2 つではありません)。
  • スクロール → 進行度:スクロールリスナーは 1 つだけ使用し、rAF でスロットリングします(GSAP/ScrollTrigger は使用しません。このデモでは、gsap-scrolltrigger-pin との依存関係の重複を避けるため、意図的にプレーンな実装にしています)。scrollY / (scrollHeight - innerHeight) から targetProgress を算出します。
  • 各フレームの Lerp:単純なダンピングで progress を targetProgress に徐々に近づけます(scrollY 自体を直接アニメーションするわけではありません)。その後、各要素について position[i] = lerp(starts[i], targets[i], progress) を設定し、geometry.attributes.position.needsUpdate = true にします。
  • 色とサイズ:PointsMaterial({ size, sizeAttenuation: true, vertexColors: true }) を使用します。元画像の色は静的な color 属性で保持します(構築時に一度だけ設定し、進行度に応じて変更しません)。
  • クリーンアップ:destroy() メソッドを持つクラスとして実装します。requestAnimationFrame をキャンセルし、scroll/resize リスナーを削除して、geometry.dispose()、material.dispose()、renderer.dispose() を呼び出します。
ブランチ
ID種類条件動作スキップ/失敗再合流
B01conditional_requiredプロジェクトで外部ライブラリを使用できないassets/demo.html + assets/demo.css + assets/demo.js を使用し、ParticleMorph の初期化パラメーターを適用します—W04
B02capability_optionalオフライン用の一式が必要git clone --depth 1 https://github.com/Rheinmir/uiux-assetギャラリーにネットワーク接続できる場合 → スキップW02
検証と終了条件

実際に実行して確認します:playwright-verify でスクロール位置 3 か所のスクリーンショットを撮影し、コンソールを読み取ります(WebGL のエラーは通知されないことがよくあります)。パフォーマンスは DevTools Performance/FPS メーターで測定し、推測しません。目視で確認し、progress 1 で画像が正しい形にまとまり、progress 0 で散らばることを確認します。画像 3 点が正しく、コンソールに問題がなければ終了します。

例
  • 適切な例: スクロール時に PNG ロゴがまとまるポートフォリオのヒーローセクションが必要 → ギャラリーから scroll-driven-particle-webgl-image-matrix.html をそのままコピーし、クレジットコメントを残してロゴ画像を変更します → 0/0.5/1 でスクリーンショットを撮影し、粒子が散らばった状態 → 中間状態 → 完成したロゴになることと、コンソールに問題がないことを確認します。
  • 境界/失敗例: プロジェクトで外部 CDN ライブラリが禁止されている → assets/demo.js を使用します。particleCount を 30.000 にすると FPS が低下する → 測定結果に基づいて ≤ 10.000 に下げ、再度検証します。
  • 境界例: ユーザーが、1 つの平面上でズームブラーを使って画像 A→B に切り替えたい → このスキルは使わず、blur に切り替えます。

由来

コメント