マウス位置に応じ左右に無限ループスライダーを作る方法

Cocoonカスタマイズ集
この記事は約10分で読めます。
記事内に広告が含まれています。

はじめに

以下の記事では、CSSのみで無限ループスライダーを作る方法を紹介しました。

今回はこれに加えて、JavaScriptを用いて、画像にマウスオーバーした際にマウスの位置に応じてスライダーが左右にスクロールする、インタラクティブなスライダーを実装します。

この記事では、この方法について説明します。

完成イメージ

実装手順

以下の手順で実装します。

  • ラベル
    Gutenbergエディターでの設定

    Gutenbergエディター

    以下の手順で作成します。

    1. 「画像」ブロックを配置し、高度な設定→追加CSSクラスにslideと入力します。
    2. 複数の「画像」ブロックを「横並び」とし、高度な設定→追加 CSSクラスにslider-wrapperと入力します。
    3. さらに全体を「横並び」とし、高度な設定→追加CSSクラスにslider-containerと入力します。
  • ラベル
    JavaScriptを追加

    以下のコードをjavascript.jsに追加します。

    jQuery(function ($) {
      // スライダー全体のコンテナ要素を取得
      const $sliderContainer = $('.slider-container');
    
      // スライド全体を内包するラッパー要素を取得
      const $sliderWrapper = $sliderContainer.find('.slider-wrapper');
    
      // 個別のスライド要素群を取得
      const $slides = $sliderWrapper.children('.slide');
    
      // スライド1枚あたりの幅(マージン含む)を取得
      const slideWidth = $slides.outerWidth(true);
    
      // スライドの総枚数を取得
      const slideCount = $slides.length;
    
      // 無限ループを実現するためスライド要素のセットを複製して追加
      $sliderWrapper.append($slides.clone());
    
      // 2セット分のスライドを収めるラッパーの総幅を設定
      $sliderWrapper.css('width', slideWidth * slideCount * 2);
    
      // 現在の水平方向の移動位置(translateX)を保持する変数
      let currentX = 0;
    
      // 自動スクロールの移動スピード(1ステップあたりの移動ピクセル数)
      let scrollSpeed = 0;
    
      // 定期実行処理を制御するためのタイマーID
      let scrollTimer;
    
      // マウス追従時の感度係数(値が大きいほど移動速度が緩やかになる)
      const mouseSensitivity = 160;
    
      // ループ境界を定義する限界位置(最小値・最大値)
      const maxTranslateX = 0;
      const minTranslateX = -slideWidth * slideCount;
    
      /**
       * 指定されたX座標の位置へスライダーを移動させる関数
       *
       * @param {number} x 移動先のX座標(ピクセル)
       * @return {void}
       */
      function moveSlider(x) {
        // CSSのtranslateXを用いてラッパー要素を変位させる
        $sliderWrapper.css('transform', `translateX(${x}px)`);
      }
    
      /**
       * 一定間隔でスライダーの位置を更新し無限ループさせる自動スクロール関数
       *
       * @return {void}
       */
      function autoScroll() {
        // 現在の位置に速度を加算
        currentX += scrollSpeed;
    
        // 左方向への移動が限界値を超えた場合、位置を1セット分戻してループ
        if (currentX <= minTranslateX) {
          currentX += slideWidth * slideCount;
        }
    
        // 右方向への移動が限界値を超えた場合、位置を1セット分進めてループ
        if (currentX > maxTranslateX) {
          currentX -= slideWidth * slideCount;
        }
    
        // 計算後の位置をスライダーに反映
        moveSlider(currentX);
    
        // 10ミリ秒後に再度自身を呼び出してアニメーションを継続
        scrollTimer = setTimeout(autoScroll, 10);
      }
    
      // スライダー上でのマウス移動イベントを監視
      $sliderContainer.on('mousemove', function (e) {
        // スライダーコンテナの画面上の左端座標を取得
        const sliderLeft = $sliderContainer.offset().left;
    
        // スライダー内におけるマウスの相対的なX座標を算出
        let relativeX = e.pageX - sliderLeft;
    
        // 相対座標がコンテナの範囲外に出ないよう制限
        if (relativeX < 0) {
          relativeX = 0;
        }
        if (relativeX > $sliderContainer.width()) {
          relativeX = $sliderContainer.width();
        }
    
        // コンテナ中央からの距離を計算(正の値は左側、負の値は右側を指す)
        const distanceFromCenter = ($sliderContainer.width() / 2) - relativeX;
    
        // 中央からの距離と感度を基にスクロール速度を決定
        scrollSpeed = distanceFromCenter / mouseSensitivity;
      });
    
      // マウスカーソルがスライダーから離れた際にスクロールを停止
      $sliderContainer.on('mouseleave', function () {
        scrollSpeed = 0;
      });
    
      // ページの読み込み完了と同時に自動スクロールを開始
      autoScroll();
    });
  • ラベル
    CSSを追加

    以下のコードをstyle.cssに追加します。

    .slider-container {
      overflow: hidden;
      position: relative;
    
      .slider-wrapper {
        gap: 0;
      }
    
      .slide {
        aspect-ratio: 1 / 1;
        margin-bottom: 0;
        width: 250px;
    
        img {
          height: 100%;
          object-fit: cover;
        }
      }
    }

さいごに

今回紹介した方法を使えば、CSSのみでは実現が難しかった「マウス位置に応じて左右に動く無限ループスライダー」を、JavaScriptでシンプルかつ柔軟に実装できます。
ユーザーの操作に応じてスライダーの動きを変えることで、より直感的で魅力的なUIを提供することができます。
複雑なライブラリを使わず、コードも最小限で済むため、軽量なサイトや独自UIを作りたい場合にも最適です。

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