要素に入ったときにポインターが丸に拡大しつつ文字が中に入るパターンを実装してみる(備忘録)

今回は前回の記事の応用編で、要素に入ったときにポインターが丸に拡大しつつ文字が中に入るパターンを実装してみます。

中の文字は仮で「VIEW」としていますが、別のテキストに変更できます。

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: none;
}

.custom-cursor {
  font-family: sans-serif;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background-color: #fff;
  position: fixed;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  font-size: 12px;
  display: grid;
  place-items: center;
  transform: scale(0);
  transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out,
    visibility 0.3s;
}

今回は、custom-cursorに対して、要素に入るときにアニメーションをつけたいので、displayのnoneは用いずに、opacityを0に、visibilityをhiddenにしてアニメーションが効くようにしています。

また、VIEWという文字を丸の中心に設定したいので、dispalyをgridに、place-itemsをcenterにしています。

transformでscaleを0にしているのは、要素に入ったときに丸が拡大していくようにアニメーションさせるためです。

JavaScriptの記述について

"use strict";

// ページのDOMが完全に読み込まれた後に実行される関数を定義
document.addEventListener("DOMContentLoaded", () => {
  // .pointer-areaクラスを持つ要素をHTMLから探して取得
  const pointerArea = document.querySelector(".pointer-area");
  // 新しいdiv要素を作成
  const cursor = document.createElement("div");
  // 作成したdivにカスタムカーソル用のクラスを追加
  cursor.classList.add("custom-cursor");
  // カーソルのテキスト内容として'VIEW'を設定
  cursor.textContent = "VIEW";
  // 完成したカーソルをbody要素の子としてDOMに追加
  document.body.appendChild(cursor);

  // pointerAreaにマウスが入ったときのイベントリスナーを追加
  pointerArea.addEventListener("mouseenter", () => {
    // カーソルを視覚的に表示するためvisibilityをvisibleに設定
    cursor.style.visibility = "visible";
    // カーソルを不透明にするためopacityを1に設定
    cursor.style.opacity = "1";
    // カーソルを拡大表示するためtransformプロパティでscale(1)を適用
    cursor.style.transform = "scale(1)";
  });

  // pointerArea上でマウスが動いた時のイベントリスナーを追加
  pointerArea.addEventListener("mousemove", (e) => {
    // カーソルの位置をマウスの位置に合わせますが、
    // カーソルがマウスポインタの中心に来るように調整するために左と上に丸のサイズ80pxの半分の40pxずつずらす
    cursor.style.left = `${e.clientX - 40}px`;
    cursor.style.top = `${e.clientY - 40}px`;
  });

  // pointerAreaからマウスが出たときのイベントリスナーを追加
  pointerArea.addEventListener("mouseleave", () => {
    // カーソルを縮小表示するためtransformプロパティでscale(0)を適用
    cursor.style.transform = "scale(0)";
    // カーソルを透明にするためopacityを0に設定
    cursor.style.opacity = "0";
    // カーソルを視覚的に非表示にするためvisibilityをhiddenに設定
    cursor.style.visibility = "hidden";
  });
});

詳細はコメントアウトで記載しているとおりです。

今回は文字をいれるため、textContentを用いています。

あとはopacity・transform・visibilityのCSSをJavaScript側で変更しています。マウスが動いているときは、丸の直径の半分のサイズ(今回は40px)を考慮して引いています。

これで実装は完了です。

次回も引き続き応用編で別のパターンを紹介していけたらと思います。