CSSとJSで作る、カーソルに追従する光の残像

ホバー

CSSとJSで作る、カーソルに追従する光の残像

投稿日2026/02/18

更新日2026/2/10

ヒーローセクションに、手触りのある動きを足したい。

このサンプルは、画面全体のキャンバス上に発光チューブを描画し、カーソルの動きに合わせて軌跡が追従するトレーサー演出です。クリックで配色がランダムに変わるため、触って楽しい「インタラクティブ背景」として使えます。

Preview プレビュー

Code コード

<div id="kumonosu-app">
	<canvas id="kumonosu-canvas"></canvas>
	<div class="kumonosu-hero">
		<h1>KUMONOSU<br>TRACER</h1>
	</div>
</div>
body, html, #kumonosu-app {
	margin: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
	background-color: #000;
}
body {
	touch-action: none;
}
#kumonosu-app {
	font-family: "Montserrat", sans-serif;
}
.kumonosu-hero {
	position: relative;
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	pointer-events: none;
	/* マウスイベントをキャンバスに透過 */
}
h1 {
	margin: 0;
	padding: 0;
	color: white;
	text-shadow: 0 0 20px rgba(0, 0, 0, 1);
	line-height: 1.1;
	user-select: none;
	font-size: 80px;
	font-weight: 700;
	text-transform: uppercase;
	text-align: center;
}
#kumonosu-canvas {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	overflow: hidden;
}
/* モバイル対応の調整 */
@media (max-width: 600px) {
	h1 {
		font-size: 40px;
	}
}
// Licence CC BY-NC-SA 4.0
import TubesCursor from "https://cdn.jsdelivr.net/npm/threejs-components@0.0.19/build/cursors/tubes1.min.js"

// エフェクトの初期化
// getElementById の引数も変更後の ID に合わせています
const app = TubesCursor(document.getElementById('kumonosu-canvas'), {
    tubes: {
        // 初期の色指定(赤と青)
        colors: ["#ff0000", "#0000ff", "#ff0055"],
        lights: {
            intensity: 200,
            colors: ["#ff0000", "#0066ff", "#ff3300", "#0000ff"]
        }
    }
})

// クリック時に色をランダムに変更
document.body.addEventListener('click', () => {
    const colors = randomColors(3)
    const lightsColors = randomColors(4)
    app.tubes.setColors(colors)
    app.tubes.setLightsColors(lightsColors)
})

function randomColors (count) {
    return new Array(count)
        .fill(0)
        .map(() => "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0'))
}

Explanation 詳しい説明

仕様

画面いっぱいに固定したcanvasに、外部ライブラリ(TubesCursor)で3Dチューブのカーソルエフェクトを描画しています。

テキストは別レイヤーに置き、pointer-events: noneで入力をキャンバスへ透過させているため、マウス操作は背景エフェクト側が受け取れます。

初期状態ではチューブ色(tubes.colors)とライト色(tubes.lights.colors)を赤/青系で設定し、クリック時にランダムカラー配列を生成して差し替えています。

色変更はapp.tubes.setColors()app.tubes.setLightsColors()で即時反映されます。

  • フルスクリーンcanvasにチューブエフェクトを描画
  • テキストは上レイヤー、入力はキャンバスへ透過
  • 初期配色は赤/青系、クリックでランダム配色に変更
  • チューブ色とライト色を別々に更新できる

カスタム

見た目の印象は「色」「光の強さ」「文字の見せ方」で決まります。まずは配色とライト強度を触ると変化が分かりやすいです。

  • 初期配色:tubes.colors / tubes.lights.colors
  • 明るさ:tubes.lights.intensity(強すぎると白飛びしやすい)
  • クリック時の色数:randomColors(3) / randomColors(4)の引数
  • 文字の存在感:h1text-shadowやサイズ(モバイルは40px)

ランダムを完全ランダムではなく、ブランドカラー寄せにしたい場合は、候補色の配列から選ぶ方式に変えるのが扱いやすいです。

注意点

この演出はWebGL依存のため、WebGL非対応環境では動きません。

また、フルスクリーンで常時描画するため、低スペック端末では負荷が上がる可能性があります。必要なら、一定時間操作がないときに弱める/停止するなどの工夫が有効です。

クリックで色を完全ランダムにしているため、組み合わせによっては文字が読みにくくなることがあります。

見やすさを優先する場合は、ライト色の彩度を抑える/明度の上限を決めるなど制限を入れると安定します。

  • WebGL依存(非対応環境では不可)
  • 常時描画なので端末性能の影響が出やすい
  • 完全ランダム配色は可読性が落ちる場合がある(制限推奨)