JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

CSSとJavaScriptだけで実装!マウスオーバーで拡大できる画像ズーム機能の作り方

ECサイトの商品詳細ページなどでよく見かける、マウスを重ねた部分が拡大される「画像ズーム機能」。実はCSSとJavaScriptを組み合わせるだけで、外部ライブラリに頼らず手軽に実装できます。

この記事では、左側の画像上でカーソルを動かすと、右側のエリアにその部分が拡大表示される仕組みを、そのまま使えるサンプルコードとともに解説します。

画像ズーム機能のサンプルコード

以下がHTML・CSS・JavaScriptをすべて含んだ完全なコード例です。ファイルに保存してブラウザで開くだけで、すぐに動作を確認できます。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
    * {box-sizing: border-box;}
    .img {
        display: inline-block;
    }
    .img-zoom-container {
        position: relative;
    }
    .img-zoom-zoomLens {
        position: absolute;
        border: 1px solid #d4d4d4;
        width: 50px;
        height: 50px;
    }
    .myresult {
        display: inline-block;
    }
    .img-zoom-result {
        border: 1px solid #d4d4d4;
    }
</style>
</head>
<body>
<h1>画像ズームのサンプル</h1>
<div class="img-zoom-container">
<img class="myimage" src="https://i.picsum.photos/id/1015/536/354.jpg?hmac=x7KEhPoOftwPXIgnQoTQzNtVUqaPYwndK8n1x_9rWuM" style="width: 400px; height: 400px;">
<div class="myresult img-zoom-result" style="width: 400px; height: 400px;"></div>
</div>
<p>左側の画像にカーソルを合わせると、右側に拡大表示されます</p>
<script>
    let imageEle = document.querySelector('.myimage');
    let resultEle = document.querySelector('.myresult');
    enlargeImage(imageEle, resultEle);

    function enlargeImage(imgEle, resultEle) {
        var zoomLens, xPos, yPos;

        // ズームレンズ(拡大範囲を示す枠)を生成し、画像の直前に挿入
        zoomLens = document.createElement("DIV");
        zoomLens.setAttribute("class", "img-zoom-zoomLens");
        imgEle.parentElement.insertBefore(zoomLens, imgEle);

        // 表示エリアとレンズのサイズ比から拡大率を算出
        xPos = resultEle.offsetWidth / zoomLens.offsetWidth;
        yPos = resultEle.offsetHeight / zoomLens.offsetHeight;

        // 表示エリアの背景に同じ画像を拡大して設定
        resultEle.style.backgroundImage = `url(${imgEle.src})`;
        resultEle.style.backgroundSize = (imgEle.width * xPos) + "px " + (imgEle.height * yPos) + "px";

        // マウス操作・タッチ操作のどちらにも対応
        zoomLens.addEventListener("mousemove", lensMoveCalculate);
        imgEle.addEventListener("mousemove", lensMoveCalculate);
        zoomLens.addEventListener("touchmove", lensMoveCalculate);
        imgEle.addEventListener("touchmove", lensMoveCalculate);

        // レンズ移動時に拡大表示の位置を計算
        function lensMoveCalculate(e) {
            var pos, x, y;
            pos = getCursorPos(e);
            x = pos.x - (zoomLens.offsetWidth / 2);
            y = pos.y - (zoomLens.offsetHeight / 2);

            // レンズが画像の外にはみ出さないよう位置を制限
            if (x > imgEle.width - zoomLens.offsetWidth) {x = imgEle.width - zoomLens.offsetWidth;}
            if (x < 0) {x = 0;}
            if (y > imgEle.height - zoomLens.offsetHeight) {y = imgEle.height - zoomLens.offsetHeight;}
            if (y < 0) {y = 0;}

            zoomLens.style.left = x + "px";
            zoomLens.style.top = y + "px";
            resultEle.style.backgroundPosition = "-" + (x * xPos) + "px -" + (y * yPos) + "px";
        }

        // 画像内におけるカーソル(指)の位置を取得
        function getCursorPos(e) {
            var a, x = 0, y = 0;
            e = e || window.event;
            a = imgEle.getBoundingClientRect();
            x = e.pageX - a.left;
            y = e.pageY - a.top;
            x = x - window.pageXOffset;
            y = y - window.pageYOffset;
            return {x : x, y : y};
        }
    }
</script>
</body>
</html>

コードの仕組みを解説

1. ズームレンズの生成

ページの読み込み時にenlargeImage()関数が実行され、document.createElement("DIV")によってズームレンズ(50px四方の枠)が動的に生成され、元画像の直前に挿入されます。このレンズが、ユーザーのカーソルに追従しながら拡大対象の範囲を示します。

2. 拡大率の計算

表示エリアの幅・高さをレンズのサイズで割ることで拡大率を算出し、その値をもとにbackground-sizeを設定しています。これにより、レンズで囲まれた範囲がちょうど表示エリアいっぱいに拡大されて表示される仕組みです。

3. カーソル位置の追跡と表示の連動

mousemoveイベントとtouchmoveイベントの両方を監視しているため、PCはもちろん、スマートフォンやタブレットなどのタッチデバイスでも同じように操作できます。getBoundingClientRect()で画像内の正確なカーソル位置を取得し、レンズが画像の外にはみ出さないよう位置を補正したうえで、background-positionを調整することで、レンズの動きに拡大表示がリアルタイムに連動します。

出力結果

上記のコードをブラウザで開くと、次のように表示されます。左側の画像にカーソルを合わせて動かすと、右側にその部分が拡大表示されます。

CSSとJavaScriptだけで実装!マウスオーバーで拡大できる画像ズーム機能の作り方

  1. CSSとJavaScriptでアコーディオン(開閉パネル)を作成する方法をわかりやすく解説

    CSSとJavaScriptを組み合わせることで、クリックすると内容が開閉する「アコーディオン(折りたたみパネル)」を簡単に実装できます。本記事では、実際に動作するサンプルコードをもとに、その作成手順と仕組みを詳しく解説します。 アコーディオンの実装例 以下は、HTML・CSS・JavaScriptを使ってアコーディオンを実装した完全なサンプルコードです。 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, ini

  2. CSSとJavaScriptで作る!レスポンシブスライドショーの実装方法を徹底解説

    CSSとJavaScriptを組み合わせることで、画像を切り替えて表示できるレスポンシブなスライドショーを簡単に実装できます。本記事では、「前へ・次へ」のナビゲーションボタンとドットインジケーター付きのスライドショーを、実際のコード例とともにわかりやすく解説します。 実装例:完全なコード 以下は、CSSとJavaScriptを使用してレスポンシブスライドショーを作成するサンプルコードです。そのままHTMLファイルに保存すれば、すぐに動作を確認できます。 <!DOCTYPE html> <html> <head> <meta name="v