Web production note

 【更新日 :

【CSS, JavaScript】指定範囲の中でマウスに連動したパララックス効果を画像に追加する

Category:
css / js

CSSとJavaScriptを組み合わせて、指定範囲の中でマウスに連動したパララックス効果を画像に追加したサンプルです。

動作サンプル

codepen

See the Pen cursor parallax (mouse moves) by web_corder (@web_walking_nak) on CodePen.

以下は最低限動作させるための設定方法です。

HTML

<div class="js-cursor-parallax">
  <div class="js-cursor-parallax__body">
    <div class="js-cursor-parallax__item">
      <img src="" alt="" width="" height="">
    </div>
  </div>
</div>

設定

  • パララックス効果を与えるエリアに class="js-cursor-parallax" を追加。
  • パララックス効果を与える要素の親に class="js-cursor-parallax__body" を追加。
  • パララックス効果を与える要素に class="js-cursor-parallax__item" を追加。
  • パララックス効果を与える要素の中に imgタグを追加。

CSS

ホバー時の画像の拡大や移動の transition はCSS側で設定します。
transformtransition はサイトに合わせて適宜調整してください。

.js-cursor-parallax__body {
  overflow: hidden;
}
/* 画像の移動スピード */
.js-cursor-parallax__item {
  transition: transform .1s;
}
/* 画像の拡大スピード */
.js-cursor-parallax__item img {
  transition: transform .3s;
}
.js-cursor-parallax:hover .js-cursor-parallax__item img {
  transform: scale(1.05);
}

JavaScript

JavaScriptで拡大した要素をマウスに連動した位置へ移動させます。
PARALLAX_FACTOR の値はCSSに設定したアニメーションの設定に合わせて適宜調整してください。

//指定した範囲の中でマウス移動に視差効果を付ける
function cursorParallax() {
  const targets = document.querySelectorAll('.js-cursor-parallax');
  //要素が存在しない場合は処理しない
  if(targets.length === 0) {
    return;
  }

  //パララックス効果の強度を制御(画像の拡大率やスピードに合わせて調整する)
  //値が大きいほどパララックス効果は弱くなる
  const PARALLAX_FACTOR = 40;

  /**
   * 正規化(任意の範囲を、0から1の値に変換する)する関数
   * @param {number} value 対象の値
   * @param {number} min 下限値
   * @param {number} max 上限値
   */
  function norm (value, min, max) {
    return (value - min) / (max - min);
  }

  /**
   * 線形補間(範囲と割合を渡すと、その割合の位置にある値を返す)
   * @param {number} min 下限値
   * @param {number} max 上限値
   * @param {number} ratio 割合
   */
  function lerp (min, max, ratio) {
    return min + (max - min) * ratio;
  }

  targets.forEach(function(target) {
    //要素が存在しない場合は処理しない
    const item = target.querySelector('.js-cursor-parallax__item');
    if(!item) {
      return;
    }

    const itemStyle = item.style;
    //マウスがパララックスエリアに入った時のイベント
    let targetX,targetY,
    xCenterItem,yCenterItem,
    targetWidth,targetHeight,
    itemWidth,itemHeight;

    //ホバー時の処理
    target.addEventListener('mouseenter', function() {
      //動かすエリアの位置・サイズを取得
      const targetRect = target.getBoundingClientRect();
      targetX = targetRect.left;
      targetY = targetRect.top;

      targetWidth = targetRect.width;
      targetHeight = targetRect.height;

      //動かす要素のサイズを取得
      const itemRect = item.getBoundingClientRect();
      itemWidth = itemRect.width;
      itemHeight = itemRect.height;

      //動かす要素の中心位置を取得
      xCenterItem = itemWidth/2;
      yCenterItem = itemHeight/2;
    });

    //ホバー+移動中の処理
    target.addEventListener('mousemove', function(e) {
      //表示エリア内でのマウス座標を取得し動かす要素をどの程度移動させれば良いか計算
      const mouseX = e.clientX - targetX;
      const xNorm = norm(mouseX, 0, targetWidth);
      const x = (xCenterItem - lerp(0, itemWidth, xNorm)) / PARALLAX_FACTOR;

      const mouseY = e.clientY - targetY;
      const yNorm = norm(mouseY, 0, targetHeight);
      const y = (yCenterItem - lerp(0, itemHeight, yNorm)) / PARALLAX_FACTOR;

      //パララックスさせる要素にstyleの指定
      itemStyle.transform = `translate3d(${-x}px, ${-y}px,0)`;
    });

    //ホバー終了時にリセット
    target.addEventListener('mouseleave', function() {
      itemStyle.transform = '';
    });
  });
}

関数の呼び出し

任意の場所で以下を実行し関数を呼び出してください。

cursorParallax();

参考リンク

目次 を閉じる