【応用編】マグネティックエフェクトでカードを反転+背景が変わる3Dアニメーション

CSS、JavaScript

前回の「カードホバー拡大&回転アニメーション」に続き、今回はカードが裏返る3D表現にマグネティックな動きを組み合わせた応用テクニックを紹介します。

さらに、応用として「裏面の色に合わせて背景が変わる」動的な演出も紹介します。
基本から応用までステップ式で学べる内容になっています。

マグネティックエフェクトとは?

マグネティックエフェクトとは、
マウスカーソルの位置に応じて要素(カードなど)がわずかに傾くアニメーション効果のことです。

まるで磁石に引かれるような自然な動きが生まれるため、
カードやボタンなどのインタラクティブな演出に人気があります。

基本のフリップカードを作る

まずは、カードが表面から裏面へと反転する基本構造を作ります。
この時点では、マグネティックな動きは入っていません。

HTML構造

<div class="card-container">
  <div class="card">
    <div class="card-inner">
      <div class="card-front">表</div>
      <div class="card-back">裏</div>
    </div>
  </div>
  <!-- 同様に複数カードを作成 -->
</div>
  • .card-containerカードを横並びにするコンテナ
  • .card個別カード
  • .card-inner回転・拡大を制御
  • .card-front / .card-back表面・裏面

CSSスタイル

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #f0f0f0;
  margin: 0;
  font-family: sans-serif;
}

.card-container {
  display: flex;
  gap: 20px;
}

.card {
  width: 120px;
  height: 180px;
  perspective: 1000px;
  transition: transform 0.5s ease, opacity 0.5s ease;
}

.card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.5s ease;
  cursor: pointer;
  transform-origin: center;
}

.card-front,
.card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  font-weight: bold;
  border-radius: 8px;
}

.card-front {
  background: white;
  color: black;
}

.card-back {
  background: black;
  color: white;
  transform: rotateY(180deg);
}

この段階では、カードにカーソルを合わせると裏面に回転するだけの、シンプルな3Dアニメーションです。

JavaScriptでマウスに応じて傾きを制御

次に、カードにマグネティックな傾き効果を加えます。
マウスの位置に応じてカードが動くようになります。

const cards = document.querySelectorAll('.card');

cards.forEach(card => {
  card.addEventListener('mousemove', (e) => {
    const rect = card.getBoundingClientRect();
    const x = e.clientX - rect.left - rect.width / 2;
    const y = e.clientY - rect.top - rect.height / 2;
    const rotateX = (-y / rect.height) * 25; // 上下傾き
    const rotateY = (x / rect.width) * 25;   // 左右傾き
    card.querySelector('.card-inner').style.transform = `rotateY(180deg) rotateX(${rotateX}deg) rotateZ(${rotateY}deg) scale(1.5)`;
    card.classList.add('hovered');
    card.parentNode.classList.add('hovered'); // 他カード縮小用
  });

  card.addEventListener('mouseleave', () => {
    const inner = card.querySelector('.card-inner');
    inner.style.transform = 'rotateY(0deg) rotateX(0deg) rotateZ(0deg) scale(1)';
    card.classList.remove('hovered');
    card.parentNode.classList.remove('hovered');
  });
});
  • rotateXrotateY をマウス座標に応じて算出し、傾きを強調(25°まで拡大)
  • scale(1.5) によって、ホバー時に少し拡大する自然な動き
  • mouseleave イベントで、元の角度に戻すことで滑らかなリセット

サンプル

See the Pen card-3 by kasasagi_kmnmc (@kasasagi_kmnmc) on CodePen.

背景色を変化させる応用版

ここでは、カードの裏面色に合わせて body の背景色が動的に変化するバージョンを紹介します。

HTML

<div class="card-container">
  <div class="card" data-bg="#1e1e1e">
    <div class="card-inner">
      <div class="card-front">Card 1</div>
      <div class="card-back" style="background: #1e1e1e;">Back 1</div>
    </div>
  </div>

  <div class="card" data-bg="#003366">
    <div class="card-inner">
      <div class="card-front">Card 2</div>
      <div class="card-back" style="background: #003366;">Back 2</div>
    </div>
  </div>

  <div class="card" data-bg="#4a148c">
    <div class="card-inner">
      <div class="card-front">Card 3</div>
      <div class="card-back" style="background: #4a148c;">Back 3</div>
    </div>
  </div>
</div>

JavaScript

const cards = document.querySelectorAll('.card');
const body = document.body;

// カードごとの裏面色を配列で用意
const backColors = ['#ff6666', '#66ccff', '#66ff99', '#ffcc66', '#cc66ff'];

cards.forEach((card, index) => {
  card.addEventListener('mousemove', (e) => {
    const rect = card.getBoundingClientRect();
    const x = e.clientX - rect.left - rect.width / 2;
    const y = e.clientY - rect.top - rect.height / 2;
    const rotateX = (-y / rect.height) * 25;
    const rotateY = (x / rect.width) * 25;

    // 回転・傾き・拡大
    card.querySelector('.card-inner').style.transform = `rotateY(180deg) rotateX(${rotateX}deg) rotateZ(${rotateY}deg) scale(1.5)`;
    card.classList.add('hovered');
    card.parentNode.classList.add('hovered');

    // カードごとの裏面色に合わせて背景を変更
    body.style.background = backColors[index];
  });

  card.addEventListener('mouseleave', () => {
    const inner = card.querySelector('.card-inner');
    inner.style.transform = 'rotateY(0deg) rotateX(0deg) rotateZ(0deg) scale(1)';
    card.classList.remove('hovered');
    card.parentNode.classList.remove('hovered');

    // 元の背景に戻す
    body.style.background = '#f0f0f0';
  });
});
  • 各カードに data-bg 属性を追加し、背景色を個別に設定可能
  • mousemove イベント内で body.style.background を動的に変更
  • mouseleave 時に背景色を元に戻して自然な演出に

サンプル

See the Pen card-4 by kasasagi_kmnmc (@kasasagi_kmnmc) on CodePen.

まとめ

今回紹介した内容では、

  • 基本的な3Dフリップカード
  • マウス位置に応じたマグネティックエフェクト
  • 裏面の色に連動する背景変化演出

と段階的に発展させることで、
一見複雑そうなアニメーションも理解しやすく構築できました。

特に、data-bg のようにHTML属性を活用することで、
JavaScript側をシンプルに保ちながら表現を自由に変えることが可能です。

タイトルとURLをコピーしました