見出し画像

これは知っておきたいJavaScript講座 Vol.2 ~昔懐かしマウスストーカー~

昔懐かしマウスストーカー

システムツー・ワンのテクニカルシステムエンジニアの「じょん(日本人)」です。JSは簡単に環境を用意できるフロントエンドのアプリケーションなので結構好きです。むやみやたらと要素を動かしたくなります。

そんなこんななJavaScript講座の第2回目となる本日は、昔流行った?マウスストーカーのお話。


そもそもマウスストーカーって?


簡単に言えば、マウスカーソルをストーキング(追跡)する何かである。こんな感じにマウスカーソルに何かがついてくるサイトを見たことがないだろうか。
※降ってくる星はまた別のお話。

マウスストーカーを今更学ぶ意味


オシャレのためだけに今でも採用しているサイトは、もうあまり無いのではないかと思う。しかし、マウスカーソルを強調するために採用することはあるかもしれない。また、マウスストーカーの考え方は、要素をドラッグして移動させる、という動きの基本になる。

まずはついてくる要素を準備


<style>
    #stalker {
        --size: 20px;
        width: var(--size);
        height: var(--size);
        background-color: rgba(0, 0, 0, 0.5);
        position: absolute;
        clip-path: polygon(20% 0, 80% 0, 80% 50%, 100% 50%, 50% 100%, 0 50%, 20% 50%); 
    }
</style>

<div id="stalker">
</div>

今回はなんとなく下向きの矢印にする。

マウスの動きを検知する


マウスの動きを検知するため、mousemoveイベントをハンドリングする。

<script type="text/javascript">
    document.addEventListener('mousemove', event => {
        console.log(event);
    });
</script>

とりあえずはコンソールにイベントを出してみる。

マウスをぐりぐりするとものすごい勢いでイベントが発火し、座標情報が更新されているのが見て取れる。

マウスストーカーの位置を設定する


<script type="text/javascript">
    const stalker = document.querySelector('#stalker');
    document.addEventListener('mousemove', event => {
        stalker.style.left = `${event.pageX}px`;
        stalker.style.top = `${event.pageY}px`;
    });
</script>

とりあえずはpageX、pageYをstalkerのleftとtopに代入する。

ここまで来たらもう少し。このままではマウスの右下をついてくる形になり、矢印の指している個所とずれてしまっている。

矢印の位置を調整する


<script type="text/javascript">
    const stalker = document.querySelector('#stalker');
    const offsetX = -stalker.clientWidth / 2;
    const offsetY = -stalker.clientHeight;
    document.addEventListener('mousemove', event => {
        stalker.style.left = `${event.pageX + offsetX}px`;
        stalker.style.top = `${event.pageY + offsetY}px`;
    });
</script>

矢印の幅と高さをもとに、pageX、pageYの値から移動させる距離をoffsetとして取得する。それをpageX、pageYに足して位置を調整する。

これで思った通りのマウスストーカーが完成した。

応用例


これを応用して、矢印が勝手についてくるのではなく、ドラッグアンドドロップで移動できるようなものを考える。

<style>
    #arrow {
        --size: 20px;
        width: var(--size);
        height: var(--size);
        background-color: rgba(0, 0, 0, 0.5);
        position: absolute;
        clip-path: polygon(20% 0, 80% 0, 80% 50%, 100% 50%, 50% 100%, 0 50%, 20% 50%); 
    }
</style>

<div id="arrow">
</div>

<script type="text/javascript">
const arrow = document.querySelector('#arrow');
const offsetX = -arrow.clientWidth / 2;
const offsetY = -arrow.clientHeight / 2;

let isMouseDown = false;
arrow.addEventListener('mousedown', event => {
    isMouseDown = true;
});

document.addEventListener('mousemove', event => {
    if (isMouseDown) {
        arrow.style.left = `${event.pageX + offsetX}px`;
        arrow.style.top = `${event.pageY + offsetY}px`;
    }
});

document.addEventListener('mouseup', event => {
    isMouseDown = false;
});
</script>

マウスストーカーではなくなったのでstalkerではなくarrowにした。
arrowの上でマウスが押されたらisMouseDownをtrueにし、isMouseDownがtrueの間は矢印が移動する。マウスが離されたらisMouseDownをfalseにし、矢印が移動しないようにする。ただこれだけで……

矢印をドラッグアンドドロップで移動できるようになった。

最後に


今回は誰に刺さるのかマウスストーカーの話から、要素をドラッグアンドドロップで移動できる仕組みまで考えた。もっと頑張ればリストの要素を入れ替える仕組みやらなんやらだって作れるし、今回は自由に動かせるようにしたが、決まった範囲で動かせる仕組みだって作れる。興味がある人は色々弄ってみて欲しい。