JavaScript

マウスドラッグで横スクロール!慣性付きスムーズスクロールの実装方法

Webページ上で横に長い画像を表示する際、マウスの左クリックを押したままドラッグするとスムーズにスクロールし、ドラッグを解除すると慣性スクロールがかかる実装方法を紹介します。

左右横スクロールとは

通常、横に長いコンテンツを表示する場合、スクロールバーやホイールスクロールを使います。
しかし、マウスの左クリックを活用したドラッグ操作でスクロールを実装すると、より直感的な操作が可能になります。

左クリックとは

マウスの左ボタンを押す操作のことです。通常、クリックやドラッグ操作に使用されます。

左クリックドラッグ慣性付きスクロールページを作ってみる

CSSの記述

<style>
body{
  padding: 0;
  margin: 0;
  text-align: center;
  font-size: 16px;
}
::-webkit-scrollbar{
  width: 15px;
  height: 10px;
}
::-webkit-scrollbar-track{
  background-color: #cccccc;
}
::-webkit-scrollbar-thumb{
  background-color: #333333;
}
h1{
  font-size:20px;
  line-height:1.6em;
  text-align:center;
  padding: 15px 0 0 0;
}
#scrollarea{
  width: 100%;
  position: relative;
  padding: 50px 0 100px 0;
}
#scrollarea .scrollwrap{
  width: 100%;
  height: 600px;
    position: relative;
    overflow-y: hidden;
    overflow-x: scroll;
}
#scrollarea .scrollwrap img{
  width: auto;
  height: 600px;
}
</style>

上記のCSSでは、スクロールバーのデザインと横スクロールエリアを設定しています。

HTMLの記述

<h1>マウス左クリック中は左右にドラッグスクロールすると慣性付きで左右にスクロールできます。</h1>
<section id="scrollarea">
  <div class="scrollwrap">
<img src="width3000.jpg" alt="幅3000pxの画像">
  </div>
</section>

画像を横スクロール可能なエリア内に配置します。

JavaScriptの記述

<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
    const detailswrap = document.querySelector('.scrollwrap');
    const img = detailswrap.querySelector('img');

    img.setAttribute('draggable', 'false');
    img.addEventListener('dragstart', (e) => e.preventDefault());

    let isDragging = false;
    let startX = 0;
    let scrollStartX = 0;

    let velocity = 0;      // マウス移動速度
    let animationFrameId;  // 慣性アニメーション用
    let lastPageX = 0;     // 直前のマウス位置

    // ドラッグ開始
    detailswrap.addEventListener('mousedown', (e) => {
        if (e.button !== 0) return;  // 左クリックのみ
        isDragging = true;
        startX = e.pageX;
        scrollStartX = detailswrap.scrollLeft;
        detailswrap.style.cursor = 'grabbing';
        img.style.pointerEvents = 'none';

        velocity = 0;
        lastPageX = e.pageX;

        // 慣性スクロール中なら停止
        cancelAnimationFrame(animationFrameId);
    });

    // ドラッグ中
    document.addEventListener('mousemove', (e) => {
        if (!isDragging) return;

        const deltaX = e.pageX - startX;
        detailswrap.scrollLeft = scrollStartX - deltaX;

        // 速度計算(現在位置と前回位置の差)
        velocity = e.pageX - lastPageX;
        lastPageX = e.pageX;
    });

    // ドラッグ終了(慣性スクロール開始)
    document.addEventListener('mouseup', () => {
        if (isDragging) {
            isDragging = false;
            detailswrap.style.cursor = 'auto';
            img.style.pointerEvents = 'auto';

            startInertiaScroll();
        }
    });

    // エリア外に出てもドラッグ解除
    detailswrap.addEventListener('mouseleave', () => {
        if (isDragging) {
            isDragging = false;
            detailswrap.style.cursor = 'auto';
            img.style.pointerEvents = 'auto';

            startInertiaScroll();
        }
    });

    // 慣性スクロール関数
    function startInertiaScroll() {
        const friction = 0.95;  // 摩擦係数(数値が小さいほど早く止まる)
        function inertia() {
            detailswrap.scrollLeft -= velocity;
            velocity *= friction;  // 徐々に減速
            if (Math.abs(velocity) > 0.1) {
                animationFrameId = requestAnimationFrame(inertia);
            }
        }
        inertia();
    }
});
</script>

このスクリプトでは、左クリックしたときにスクロールの開始位置を取得し、マウス移動時にスクロール位置を更新します。
マウスボタンを離した後は、慣性をシミュレーションしてスムーズに停止させます。

左クリックドラッグ慣性付きスクロールデモページ

実装したスクロールデモページは以下のリンクから確認してみてください。

左クリックドラッグ慣性付きスクロールデモページ

注意点

  • タッチデバイスでは動作しない可能性があります。
  • 画像のサイズが適切でないと動作に影響を及ぼす可能性があります。

まとめ

本記事では、マウスの左クリックドラッグによる慣性付きスクロールを実装する方法を紹介しました。
Webページ上で横に長いコンテンツを扱う場合、スムーズな操作感を提供できるので、ぜひ活用してみてください。

 
※参考にされる場合は自己責任でお願いします。
 デモページheadタグ内のGoogleアナリティクスタグは流用しないで下さい。