マウスを動かすと桜が舞う。Webページに息づく小さな春
マウスを動かすだけで、画面に桜の花びらが舞い散る。そんな小さな演出をWebページに追加してみました。
実装してみると、意外と面白い。カーソルが動くたびに、淡いピンクの花びらがふわふわと落ちていく。技術的には単純な仕組みですが、見ていて心地よい。50あたりの年齢でも、こういう小さな仕掛けを作るのは楽しいものです。
作ったもの
マウスポインターに追従するように、桜の花びらが生成されます。一度に8枚の花びらが、ランダムな方向に回転しながら落下。3秒かけて消えていく演出です。タッチデバイスにも対応しています。
色やサイズを調整すると、印象が変わります。淡いピンクから濃いピンクまで、季節に合わせて変化させられます。
実装の流れ
基本構造
花びらはDOM要素として動的に生成します。div要素を作り、CSSで桜の形にスタイリング。位置はfixedで画面全体に固定します。
function createSakura(x, y) {
const numberOfPetals = 8;
for (let i = 0; i < numberOfPetals; i++) {
const petal = document.createElement('div');
petal.className = 'sakura-petal';
const offsetX = (Math.random() - 0.5) * 60;
const offsetY = (Math.random() - 0.5) * 60;
petal.style.position = 'fixed';
petal.style.left = `${x + offsetX}px`;
petal.style.top = `${y + offsetY}px`;
petal.style.pointerEvents = 'none';
document.body.appendChild(petal);
}
}
花びらの形状は、borderRadiusで角を丸めて、回転させます。15px 0pxという値で、桜らしい形になります。
アニメーションの仕組み
落下の動きは、CSSのtransitionで実現します。初期位置から、ランダムな方向に移動。同時に回転も加えます。
petal.style.width = '15px';
petal.style.height = '15px';
petal.style.backgroundColor = '#ffd7eb';
petal.style.borderRadius = '15px 0px';
petal.style.transform = `rotate(${Math.random() * 360}deg)`;
petal.style.transition = 'all 3s ease-out';
petal.style.opacity = '0.8';
requestAnimationFrame(() => {
petal.style.transform = `translate(${(Math.random() - 0.5) * 100}px, ${Math.random() * 200}px) rotate(${Math.random() * 720}deg)`;
petal.style.opacity = '0';
});
requestAnimationFrameを使うのは、ブラウザの描画タイミングに合わせるためです。これで滑らかな動きになります。
パフォーマンス最適化
最初の実装では、マウスを動かすたびに花びらを生成していました。すると、すぐに要素が増えすぎて、ブラウザが重くなります。
スロットリング(間引き処理)を追加しました。50ミリ秒に1回だけ、花びらを生成するようにします。
let isThrottled = false;
const throttleDelay = 50;
function handleMove(x, y) {
if (!isThrottled) {
isThrottled = true;
createSakura(x, y);
setTimeout(() => {
isThrottled = false;
}, throttleDelay);
}
}
これで、マウスを素早く動かしても、処理が追いつきます。
最初は100ミリ秒にしていました。間隔が長すぎて、マウスを動かしても花びらがなかなか生成されず、反応が鈍く感じました。滑らかさに欠けます。
次に、30ミリ秒にしてみました。反応は速くなりましたが、マウスを素早く動かすと処理が追いつかず、ブラウザが重くなる傾向がありました。
最終的に、50ミリ秒にしました。滑らかさとパフォーマンスのバランスが良く、実用的な値です。マウスを動かしても自然な反応があり、処理も重くなりません。
メモリ管理
生成した花びらは、3秒後に自動的に削除します。これを忘れると、メモリリークの原因になります。
setTimeout(() => {
if (petal.parentNode) {
document.body.removeChild(petal);
}
}, 3000);
parentNodeの存在確認は、念のためです。既に削除されている可能性があるためです。
タッチデバイス対応
スマートフォンやタブレットでも動作するよう、タッチイベントにも対応しました。
document.addEventListener('mousemove', function(event) {
handleMove(event.clientX, event.clientY);
});
document.addEventListener('touchmove', function(event) {
const touch = event.touches[0];
handleMove(touch.clientX, touch.clientY);
});
タッチイベントは、最初のタッチ点の座標を使います。これで、指を動かしたときに花びらが生成されます。
試行錯誤の過程
パラメータを調整する中で、いくつかの発見がありました。
最初は1回の生成で5枚にしていました。しかし、少し物足りない。8枚に増やすと、華やかになりました。10枚にすると、少し多すぎる印象です。8枚が、ほどよいバランスです。
アニメーション時間を2秒にすると、動きが速すぎます。5秒にすると、遅すぎて重く感じます。3秒が、自然な動きに見えます。
📝
NOTE
背景色が#ffd7ebの場合、白い背景では見えやすいですが、暗い背景では目立ちません。背景に合わせて、色を調整する必要があります。
応用のアイデア
同じ仕組みを使って、季節ごとに変化させることもできます。春は桜、夏は青い花びら、秋は紅葉、冬は雪。季節感を演出できます。
色を変えるだけで、印象が大きく変わります。
システムフロー
全体の流れを整理すると、以下のようになります。
まとめ
マウスの動きに反応して、桜の花びらが舞い散る演出を実装しました。
- DOM要素を動的に生成し、CSSアニメーションで落下を表現
- スロットリングでパフォーマンスを最適化(50ミリ秒間隔)
- 3秒後に要素を削除してメモリを管理
- タッチデバイスにも対応
技術的には単純ですが、見ていて心地よい演出になります。季節感を演出したり、特別感を出したりするのに役立ちます。
使い方のポイント
- マウスを動かすだけで、自動的に花びらが生成されます
- パフォーマンスを考慮し、50ミリ秒間隔で生成されます
- 生成された花びらは3秒後に自動的に削除されます
- スマートフォンやタブレットでも、タッチ操作で動作します
さらに深く学ぶには