Feylo

デモを見るコードを見る

マウスの位置に応じて傾くカードコンポーネント

カード
マウスの位置に応じて傾くカードコンポーネント

マウスの位置に応じてカードコンポーネントを傾かせる方法を紹介します。マウス位置はJavaScriptで取得して、その場所に応じて計算して傾けるようにします。

    実装のポイント
  • マウス位置をJavaScriptで取得する。
  • その位置に応じて計算してカードを傾ける。

実装の考え方

マウスの位置に応じてカードを傾けるには、マウスの位置をJavaScriptで取得し、その位置に応じて計算して傾けるようにします。傾きに関しては、CSSのtransform: rotateX() rotateY()を使用します。

実装方法

それでは実際に実装していきましょう。
まずはHTMLになります。

HTML

HTML
<div class="card-hover-range">
  <div class="card">
    <div class="card__img">
      <img src="https://picsum.photos/320/180?random=1" alt="" width="320" height="180">
    </div>
    <div class="card__text">
      <h2 class="card__title">Card Tilt</h2>
      <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Rerum consequatur aliquid quo vel dolor, possimus asperiores optio quas expedita rem inventore cum voluptatibus sed, labore enim, a quidem iste aspernatur.</p>
    </div>
  </div>
</div>

傾くカードはcardクラスになります。card-hover-rangeはカードが傾くマウスの範囲を広げるために、親要素として使用します。

CSS

CSSは次の通りになります。

CSS
.card-hover-range {
  padding: 5rem;
}

.card {
  width: 400px;
  background-color: #fff;
  border-radius: 1rem;
  border: 1px solid #000;
  transition: transform 0.3s linear;
}

card-hover-rangeはカードが傾くマウスの範囲を広げるために、paddingで広げます。cardtransformで傾くので、transitionを設定しておきます。デフォルトではイージングがeaseなので、linearに変更し、直ぐに傾くようにします。

JavaScript

最後にJavaScriptになります。

JavaScript
const cardMouseRange = document.querySelector(".card-hover-range");
const card = document.querySelector(".card");

const MaxRotate = 30;

cardMouseRange.addEventListener('mousemove', (e) => {
  const rect = card.getBoundingClientRect();

  const x = (e.clientX - rect.left) / rect.width;
  const y = (e.clientY - rect.top) / rect.height;

  const rotateX = (0.5 - y) * MaxRotate;
  const rotateY = (0.5 - x) * MaxRotate;

  card.style.transform = `rotateX(${rotateX}deg) rotateY(${-rotateY}deg)`;
});

cardMouseRange.addEventListener('mouseleave', () => {
  card.style.transform = 'rotateX(0deg) rotateY(0deg)';
});

それでは解説します。

要素の取得

JavaScript
const cardMouseRange = document.querySelector(".card-hover-range");
const card = document.querySelector(".card");

cardMouseRangeは、マウス移動を検知する範囲になります。後にこの要素に対してmousemoveイベントを設定します。
cardは、実際に傾けたいカード要素になります。

最大回転角度

JavaScript
const MaxRotate = 30;

MaxRotateは、後の計算で使用するカードが傾く最大の角度を設定してます。この値を変更することで、カードが傾く範囲を変更できます。このデモでは30度に設定しています。

イベントの設定

JavaScript
cardMouseRange.addEventListener('mousemove', (e) => {
  const rect = card.getBoundingClientRect();

  const x = (e.clientX - rect.left) / rect.width;
  const y = (e.clientY - rect.top) / rect.height;

  const rotateX = (0.5 - y) * MaxRotate;
  const rotateY = (0.5 - x) * MaxRotate;

  card.style.transform = `rotateX(${rotateX}deg) rotateY(${-rotateY}deg)`;
});

cardMouseRange.addEventListener('mouseleave', () => {
  card.style.transform = 'rotateX(0deg) rotateY(0deg)';
});

cardMouseRangemousemoveイベントを設定して、マウスが動くたびにカードを傾けます。mouseleaveイベントでカードを元に戻します。

JavaScript
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;

xyは、マウスの位置をカードの中心からの相対位置に変換しています。

  • e.clientX / e.clientY : マウスの現在のX/Y座標
  • rect.left / rect.top : カードの左上の座標
  • rect.width / rect.height : カードの幅/高さ

このように計算することで、カード内のマウスの位置を0~1の範囲に変換します!

JavaScript
const rotateX = (0.5 - y) * MaxRotate;
const rotateY = (0.5 - x) * MaxRotate;

中心(0.5, 0.5)からどれだけ離れているかで傾き度合いを決めます。

  • (0.5 - y) ; 上に行くと正になり、下に行くと負の値になる。
  • (0.5 - x) ; 左に行くと正になり、右に行くと負の値になる。

計算したものにMaxRotateをかけて、角度に変換します。

JavaScript
card.style.transform = `rotateX(${rotateX}deg) rotateY(${-rotateY}deg)`;

最後に計算した角度を、カードに適用します。rotateYにマイナスをつけているのは、マウス移動と回転方向が一致するようにするためです。

ホバーが外れたら、mouseleaveイベントでrotateを0にして、カードの角度を元に戻しましょう!

Share