要素に入るとポインターに追従する白い丸の中に文字が入る実装をしてみる(備忘録)
今回は、要素に入るとポインターに追従する白い丸の中に文字が入る実装をしていきます。一旦ポインターのシリーズはこれで最後としたいと思います。前回の記事を参考にして対応をしています。
HTMLの記述について
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>要素に入るとポインターに追従する白い丸の中に文字が入る実装をしてみる(備忘録)</title>
<link rel="stylesheet" href="../reset.css">
<link rel="stylesheet" href="./style.css">
</head>
<body>
<main>
<div class="pointer-area"></div>
</main>
<script src="./style.js"></script>
</body>
</html>
これは前回と同じのため、解説は省略します。
CSSの記述について
@charset "utf-8";
/* ==========================
初期設定
========================== */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
position: relative;
word-wrap: break-word;
}
img {
width: 100%;
vertical-align: bottom;
}
/* レイアウト設定 */
main {
margin: 80px 0;
}
.pointer-area {
background-color: #c3512f;
height: 400px;
cursor: auto;
}
.custom-cursor {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: #fff;
position: fixed;
pointer-events: none;
display: none;
z-index: 1000;
transition: opacity 0.5s ease-out, transform 0.5s ease-out;
display: grid;
place-items: center;
transform: scale(0);
opacity: 0;
}
.custom-cursor span {
display: inline-block;
text-align: center;
line-height: 1;
font-size: 12px;
font-family: sans-serif;
}
custom-cursorの白い丸の中に文字が上下中央に配置されるよう設定しています。
JavaScriptの記述について
"use strict";
document.addEventListener("DOMContentLoaded", () => {
// .pointer-area 要素を取得
const pointerArea = document.querySelector(".pointer-area");
// カスタムカーソル要素を作成
const cursor = document.createElement("div");
cursor.classList.add("custom-cursor");
// カスタムカーソルの中に「VIEW」という文字を追加
const cursorText = document.createElement("span");
cursorText.innerText = "VIEW";
cursor.appendChild(cursorText);
// カスタムカーソル要素をボディに追加
document.body.appendChild(cursor);
// マウスとカーソルの位置を保持する変数を初期化
let mouseX = 0,
mouseY = 0;
let cursorX = 0,
cursorY = 0;
let fadeTimeout; // フェードアウトのタイマーを保持する変数
// マウスが pointerArea に入った時の処理
pointerArea.addEventListener("mouseenter", () => {
// フェードアウトタイマーが存在する場合はクリア
if (fadeTimeout) {
clearTimeout(fadeTimeout);
}
cursor.style.display = "grid"; // カスタムカーソルを表示
setTimeout(() => {
cursor.style.transform = "scale(1)"; // カスタムカーソルを通常サイズに拡大
cursor.style.opacity = 1; // カスタムカーソルの透明度を1に設定
}, 10); // 少しの遅延を追加してスムーズな表示を実現
});
// マウスが pointerArea 内で動いた時の処理
pointerArea.addEventListener("mousemove", (e) => {
// マウスの位置を取得
mouseX = e.clientX;
mouseY = e.clientY;
// カーソルの初期位置が未設定の場合は設定
if (!cursorX && !cursorY) {
cursorX = mouseX;
cursorY = mouseY;
}
});
// マウスが pointerArea から出た時の処理
pointerArea.addEventListener("mouseleave", () => {
cursor.style.transform = "scale(0)"; // カスタムカーソルを縮小
cursor.style.opacity = 0; // カスタムカーソルの透明度を0に設定(フェードアウト開始)
fadeTimeout = setTimeout(() => {
cursor.style.display = "none"; // フェードアウト後にカスタムカーソルを非表示に
}, 500); // フェードアウトの時間に合わせてタイマーを設定
});
// カスタムカーソルをマウスに追従させるアニメーション関数
function animate() {
// カーソルの位置を徐々にマウスの位置に近づける
cursorX += (mouseX - cursorX) * 0.1;
cursorY += (mouseY - cursorY) * 0.1;
// カスタムカーソルの位置を更新
cursor.style.left = cursorX - 40 + "px"; // 80pxの半分で位置を補正
cursor.style.top = cursorY - 40 + "px"; // 80pxの半分で位置を補正
// アニメーションフレームをリクエスト
requestAnimationFrame(animate);
}
// アニメーションを開始
animate();
});
詳細はコメントアウトで記載しているとおりです。
以上で実装完了です。
また何か思いついたときに記事を書いていきたいと思います。