マウスカーソルに半透明のドットが追従してくるようなサイトを見かけたことはありませんか?
これを「マウスストーカー」というらしいのですが、今回はこのマウスストーカーをjQueryなしのJavaScriptで作る方法をメモしていきます。
ただ単にマウスカーソルにドットがついてくるだけだと味気ないので、リンク(アンカータグ)にマウスホバーすると、そのドットが大きくなって吸い付くような演出も加えたバージョンで実装してみました。
今回作っていくマウスストーカーは以下のものです。(PCでみてね)
See the Pen リンクに吸い付くマウスストーカー by ddryo (@ddryo-the-encoder) on CodePen.
まずは単純なマウスストーカーを作成してみよう
半透明なドットがマウスカーソルについてくるだけの、シンプルなマウスストーカーを作成してみます。
【デモ】シンプルなマウスストーカー
See the Pen マウスストーカー基礎編 (mouse stalker) by ddryo (@ddryo-the-encoder) on CodePen.
手順1:マウスストーカー用のdivタグをbody直下に配置しておく
HTML側には、マウスストーカーとなるdivタグを配置しておきます。
divタグの挿入場所はbody直下であればどこでもいいです。
例:body閉じタグ直前に配置しておく
<body>
<!-- コンテンツ -->
<div id="stalker"></div>
</body>
このdivタグには、お好きなIDやクラス名をつけておきましょう。
今回は例として、stalker
というIDをつけておきました。
divタグはjs側で作成してしまってもOK
以下のようにして、JS側でdivタグを生成してしまってもいいでしょう。
//マウスストーカー用のdivタグを作成
const stalker = document.createElement('div'); //divタグを作成
stalker.id = 'stalker'; //IDを付与
document.body.appendChild(stalker); //bodyの最後に挿入
手順2:CSSで黒いドットとして表現する
次に、CSSで先ほど配置したdivタグにスタイルをあてておきます。
CSSで半透明の黒いドットにする
#stalker {
pointer-events: none;
position: fixed;
top: -8px; //座標調節(カーソル位置と円の中心を合わせる)
left: -8px; //座標調節(カーソル位置と円の中心を合わせる)
width: 16px; //マウスストーカーの直径
height: 16px; //マウスストーカーの直径
background: rgba(0,0,0,0.5);
border-radius: 50%;
transform: translate(0,0);
transition: transform 0.2s; //ちょっと遅れてついてくるように
transition-timing-function: ease-out;
z-index: 999;
}
色や大きさは好きにいじってください。
今回は直径を16px
としています。
ポイントはtransition
transitionを設定しておくことで、JSでマウスの位置に追従させる時に少し遅れて付いてくるようになります。
動きはease-out
を指定して、ふわっと感を出しています。
この辺の数値なども、好きに変えてみてください。
手順3:JSでマウスストーカーの位置をマウスに合わせる
ここまでの準備で、直径16px
の半透明の黒いドットが配置できましたね。
あとはマウスの動き合わせてこのドットをカーソル位置に追従させてあげるだけです。
divタグをマウスカーソルに追従させる
//マウスストーカー用のdivを取得
const stalker = document.getElementById('stalker');
//上記のdivタグをマウスに追従させる処理
document.addEventListener('mousemove', function (e) {
stalker.style.transform = 'translate(' + e.clientX + 'px, ' + e.clientY + 'px)';
});
これだけ!
コードの解説
ポイントとなる部分だけさらっと解説しておきます。
mousemove
イベントを使って、マウスが動いた時にそのマウスの座標を取得します。- その座標(
e.clientX
とe.clientY
)をマウスストーカーの位置(traslate(x,y)
)に指定
top
とleft
を直接動かしてもいいんですが、たしかtransform
を使った方が処理が軽かったはず...。
マウスストーカーがリンクに吸い付くような演出を加えてみる
さて、マウスストーカーの基本的な作成方法がわかったところで、応用版を作成してみましょう。
今回は、冒頭で紹介しているように、リンク(アンカータグ)にマウスホバーした時にマウスストーカーが吸い付いていくような演出を加えてみます。
この時、ドットが少し大きく、そして色も変わるような表現にしてみます。
手順1:HTMLはそのまま
HTMLに特に変更点はありません。先ほどの例と同じマウスストーカー用のdivタグを使います。
手順2:リンクに吸い付いた時のドットの色や大きさをCSSに追記する
CSS側は少し編集を加え、以下のようにしておきます。
リンクに吸い付くマウスストーカー用のCSS
#stalker {
pointer-events: none;
position: fixed;
top: -8px; //座標調節(カーソル位置と円の中心を合わせる)
left: -8px; //座標調節(カーソル位置と円の中心を合わせる)
width: 16px; //マウスストーカーの直径
height: 16px; //マウスストーカーの直径
background: rgba(0,0,0,0.5);
border-radius: 50%;
transition: transform 0.2s, top, 0.5s, left 0.5s, width .5s, height .5s, background-color .5s;
transition-timing-function: ease-out;
z-index: 999;
&.hov_{
top: -32px; //大きさに合わせて座標調節
left: -32px; //大きさに合わせて座標調節
width: 64px;
height: 64px;
transition: .5s;
background: rgba(255, 0, 0, 0.4);
}
}
色や大きさが変化するので、transition
プロパティを編集しています。
また、リンクホバー時にhov_
というクラス名をマウスストーカーに追加するので(次のステップでJS側から加えます)、その時のスタイルも追記しています。
手順3:JSでリンクにマウスホバーした時の処理も加える
最後に、JavaScript側でリンクにマウスホバーした時の処理も加えていきましょう。
編集後のスクリプト
//マウスストーカー用のdivを取得
const stalker = document.getElementById('stalker');
//aタグにホバー中かどうかの判別フラグ
let hovFlag = false;
//マウスに追従させる処理 (リンクに吸い付いてる時は除外する)
document.addEventListener('mousemove', function (e) {
if (!hovFlag) {
stalker.style.transform = 'translate(' + e.clientX + 'px, ' + e.clientY + 'px)';
}
});
//リンクへ吸い付く処理
const linkElem = document.querySelectorAll('a:not(.no_stick_)');
for (let i = 0; i < linkElem.length; i++) {
//マウスホバー時
linkElem[i].addEventListener('mouseover', function (e) {
hovFlag = true;
//マウスストーカーにクラスをつける
stalker.classList.add('hov_');
//マウスストーカーの位置をリンクの中心に固定
let rect = e.target.getBoundingClientRect();
let posX = rect.left + (rect.width / 2);
let posY = rect.top + (rect.height / 2);
stalker.style.transform = 'translate(' + posX + 'px, ' + posY + 'px)';
});
//マウスホバー解除時
linkElem[i].addEventListener('mouseout', function (e) {
hovFlag = false;
stalker.classList.remove('hov_');
});
}
ポイント解説
- リンクにホバー中かどうかを判定するための変数
hovFlag
を用意しておく - ドットをマウスに追従させる処理は、リンクにホバーしていない時だけ走らせる
- リンクのホバーに合わせて
hov_
というクラスを付け外しする - リンクにホバーしている間、ドットの位置はそのリンクの中心に固定する
getBoundingClientRect()
メソッドでリンクの座標と横幅・高さを取得
a:not(.no_stick_)
でリンク要素を取得することで、例外としてno_stick_
というクラス名がついているリンクでは上記の処理を加えない(この処理を加えるかどうかは任意でどうぞ)
おわりに - マウスカーソル自体を変更するとさらにイイ感じに
今回は「マウスストーカー」の実装部分だけを紹介しましたが、マウスカーソル自体も小さいドットにするとさらにイイ感じになると思います。