JavaScript で虫眼鏡の特殊効果を実現

JavaScript で虫眼鏡の特殊効果を実現

達成される効果:マウスを小さな画像の上に置くと、小さなブロックが小さな画像の上に表示され、この小さなブロック内の領域が拡大されて右側の大きな画像に表示されます(下図を参照)。

このエフェクトは主に、マウス座標 e.clientX、e.clientY、オフセット offsetLeft、offsetTop、offsetWidth、sffsetHeight などのプロパティを使用します。

HTML および CSS コード:

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
    <スタイル>
        *{
            マージン: 0;
            パディング: 0;
        }
        体{
            背景:#2c3e50;

        }
        。包む{
            ディスプレイ: フレックス;            
            位置: 相対的;
            左: 200px;
            上: 30px;
        }
        。小さい{
            幅: 500ピクセル;
            高さ: 300px;
            境界線の半径: 20px;
            オーバーフロー: 非表示;
            位置: 相対的;
            左: 0px;
        }
        .small画像{
            幅: 100%;
            高さ: 100%;
        }
        .small span{
            表示: なし;
            位置: 絶対;  
            左: 0;
            上: 0;      
            幅: 100ピクセル;
            高さ: 100px;
            背景: rgba(0,0,0,0.5);
            カーソル: ポインタ;
            zインデックス: 1;
        }
        。大きい{
            表示: なし;
            幅: 400ピクセル;
            高さ: 400px;
            オーバーフロー: 非表示;
            位置: 相対的;
            左: 50px;
            上: 0;
        }
        .bigimg{
            位置: 絶対;
            左: 0;
            上: 0; 
            幅: 1000ピクセル;
            高さ: 600px;
        }
    </スタイル>
</head>
<本文>
    <div class="wrap">
        <div class="small">
            <img src="img/33.jpg" alt="">
            <span></span>
        </div>
        <div class="big">
            <img src="img/33.jpg" alt="">
        </div>
    </div>

</本文>
</html>

JS部分:

マウスを虫眼鏡(小さな画像上の小さなブロック)に移動すると、右側に大きな画像が表示されます。

// 最大のコンテナ let wrap=document.querySelector('.wrap');
// 小さい画像部分 let smallWrap=document.querySelector('.wrap .small');
smallImg を document.querySelector('.wrap .small img') とします。
smallBox を document.querySelector('.wrap .small span') とします。
// 大きな画像部分 let bigBox=document.querySelector('.wrap .big');
bigImg を document.querySelector('.wrap .big img') とします。
smallWrap.onmouseover=関数(){
       smallBox.style.display="ブロック";
       bigBox.style.display="ブロック";
}

マウスがサムネイル上で移動すると、虫眼鏡も動きを追従します。マウスの座標を取得するには、イベントオブジェクトのevent.clientXとevent.clientYを使用します。

event.clientX と event.clientY を通じて、マウスの位置、親コンテナのオフセット、虫眼鏡のオフセットを取得できます (実際のプロジェクトでは、虫眼鏡にオフセットが設定されている場合があります。このオフセットの影響を除去するには、このオフセットを減算する必要があります)。虫眼鏡エフェクトでは、マウスは常に小さなブロックの中央にあるため、移動位置は次のように取得できます。

smallWrap.onmousemove=関数(e){
            moveX = e.clientX-wrap.offsetLeft-smallWrap.offsetLeft-smallBox.offsetWidth/2 とします。
            moveY=e.clientY-wrap.offsetTop-smallWrap.offsetTop-smallBox.offsetHeight/2 とします。

            maxX=smallWrap.offsetWidth-smallBox.offsetWidth とします。
            maxY = smallWrap.offsetHeight - smallBox.offsetHeight とします。


            smallBox.style.left=moveX+'px'
            smallBox.style.top=moveY+'px'

       }

この時点で、虫眼鏡はマウスの動きに追従します。範囲制限も追加する必要があります。そうしないと、虫眼鏡は小さな画像よりも遠くに移動します。

範囲の制限

smallWrap.onmousemove=関数(e){
            moveX = e.clientX-wrap.offsetLeft-smallWrap.offsetLeft-smallBox.offsetWidth/2 とします。
            moveY=e.clientY-wrap.offsetTop-smallWrap.offsetTop-smallBox.offsetHeight/2 とします。

            maxX = smallWrap.offsetWidth - smallBox.offsetWidth とします。
            maxY=smallWrap.offsetHeight-smallBox.offsetHeight とします。

           
            //範囲制限方法 1/* if(moveX<0){
                移動X=0;
            }そうでない場合(moveX>=maxX){
                移動X=最大X
            }
            移動Y<0の場合{
                移動Y=0;
            }そうでない場合(moveY>=maxY){
                移動Y=最大Y
            } */
             //範囲制限方法2 moveX=Math.min(maxX,Math.max(0,moveX))
            移動Y = Math.min(maxY, Math.max(0, 移動Y))

            smallBox.style.left=moveX+'px'
            smallBox.style.top=moveY+'px'

       }

虫眼鏡がマウスの動きに追従した後、次のステップは、虫眼鏡が動くと大きな画像も動く(大きな画像の移動方向は反対)ことを認識することです。虫眼鏡が動く距離は大きな画像が動く距離に比例し、小さな画像の幅は大きな画像の幅(非表示部分を含む)に比例し、小さな画像が動く最大距離も大きな画像が動く最大距離に比例するため、この2つの式を使用して大きな画像をどれだけ動かすかを計算できます。

虫眼鏡が移動する距離 / 小さい画像の幅 = 大きい画像が移動する距離 / 大きい画像の幅。この式は実装できますが、この効果をもたらす最大移動距離に制限はありません。

したがって、式は次のように記述する必要があります:虫眼鏡が移動する距離 / サムネイルの幅 - 虫眼鏡の幅 (これは虫眼鏡の最大移動範囲です)

虫眼鏡が移動する距離 / (小さい画像の幅 - 虫眼鏡の幅) = 大きい画像が移動する距離 / (大きい画像の幅 - 大きい画像の表示領域)

大きな画像が移動する方向は、虫眼鏡が移動する方向と逆であることに注意してください。

smallWrap.onmousemove=関数(e){
            moveX = e.clientX-wrap.offsetLeft-smallWrap.offsetLeft-smallBox.offsetWidth/2 とします。
            moveY=e.clientY-wrap.offsetTop-smallWrap.offsetTop-smallBox.offsetHeight/2 とします。

            maxX = smallWrap.offsetWidth - smallBox.offsetWidth とします。
            maxY = smallWrap.offsetHeight - smallBox.offsetHeight とします。

           
            //範囲制限方法 1/* if(moveX<0){
                移動X=0;
            }そうでない場合(moveX>=maxX){
                移動X=最大X
            }
            移動Y<0の場合{
                移動Y=0;
            }そうでない場合(moveY>=maxY){
                移動Y=最大Y
            } */
             //範囲制限方法2 moveX=Math.min(maxX,Math.max(0,moveX))
            移動Y = Math.min(maxY, Math.max(0, 移動Y))

            smallBox.style.left=moveX+'px'
            smallBox.style.top=moveY+'px'

            let left=moveX/(smallImg.offsetWidth-smallBox.offsetWidth);//smallImg.offsetWidth-smallBox.offsetWidth 最大移動位置 let top=moveY/(smallImg.offsetHeight-smallBox.offsetHeight);

            bigImg.style.left=-left*(bigImg.offsetWidth-bigBox.offsetWidth)+'px'
            bigImg.style.top=-top*(bigImg.offsetHeight-bigBox.offsetHeight)+'px'
       }

最後に、マウスアウトイベント、マウスアウト、虫眼鏡、大きな画像の非表示を追加します。

smallWrap.onmouseout=関数(){
            smallBox.style.display="なし";
            bigBox.style.display="なし";
       }

完全なコード:

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
    <スタイル>
        *{
            マージン: 0;
            パディング: 0;
        }
        体{
            背景:#2c3e50;

        }
        。包む{
            ディスプレイ: フレックス;            
            位置: 相対的;
            左: 200px;
            上: 30px;
        }
        。小さい{
            幅: 500ピクセル;
            高さ: 300px;
            境界線の半径: 20px;
            オーバーフロー: 非表示;
            位置: 相対的;
            左: 100px;
        }
        .small画像{
            幅: 100%;
            高さ: 100%;
        }
        .small span{
            表示: なし;
            位置: 絶対;  
            左: 0;
            上: 0;      
            幅: 100ピクセル;
            高さ: 100px;
            背景: rgba(0,0,0,0.5);
            カーソル: ポインタ;
            zインデックス: 1;
        }
        。大きい{
            表示: なし;
            幅: 400ピクセル;
            高さ: 400px;
            オーバーフロー: 非表示;
            位置: 相対的;
            左: 120px;
            上: 0;
        }
        .bigimg{
            位置: 絶対;
            左: 0;
            上: 0; 
            幅: 1000ピクセル;
            高さ: 600px;
        }
    </スタイル>
</head>
<本文>
    <div class="wrap">
        <div class="small">
            <img src="img/33.jpg" alt="">
            <span></span>
        </div>
        <div class="big">
            <img src="img/33.jpg" alt="">
        </div>
    </div>
    <スクリプト>
        // 最大のコンテナ let wrap=document.querySelector('.wrap');
       // 小さい画像部分 let smallWrap=document.querySelector('.wrap .small');
       smallImg を document.querySelector('.wrap .small img') とします。
       smallBox を document.querySelector('.wrap .small span') とします。
        // 大きな画像部分 let bigBox=document.querySelector('.wrap .big');
       bigImg を document.querySelector('.wrap .big img') とします。
       smallWrap.onmouseover=関数(){
            smallBox.style.display="ブロック";
            bigBox.style.display="ブロック";
       }
       smallWrap.onmousemove=関数(e){
            moveX = e.clientX-wrap.offsetLeft-smallWrap.offsetLeft-smallBox.offsetWidth/2 とします。
            moveY=e.clientY-wrap.offsetTop-smallWrap.offsetTop-smallBox.offsetHeight/2 とします。

            maxX=smallWrap.offsetWidth-smallBox.offsetWidth とします。
            maxY = smallWrap.offsetHeight - smallBox.offsetHeight とします。

           
            //範囲制限方法 1/* if(moveX<0){
                移動X=0;
            }そうでない場合(moveX>=maxX){
                移動X=最大X
            }
            移動Y<0の場合{
                移動Y=0;
            }そうでない場合(moveY>=maxY){
                移動Y=最大Y
            } */
             //範囲制限方法2 moveX=Math.min(maxX,Math.max(0,moveX))
            移動Y = Math.min(maxY, Math.max(0, 移動Y))

            smallBox.style.left=moveX+'px'
            smallBox.style.top=moveY+'px'

            let left=moveX/(smallImg.offsetWidth-smallBox.offsetWidth);//smallImg.offsetWidth-smallBox.offsetWidth 最大移動位置 let top=moveY/(smallImg.offsetHeight-smallBox.offsetHeight);

            bigImg.style.left=-left*(bigImg.offsetWidth-bigBox.offsetWidth)+'px'
            bigImg.style.top=-top*(bigImg.offsetHeight-bigBox.offsetHeight)+'px'
       }
       smallWrap.onmouseout=関数(){
            smallBox.style.display="なし";
            bigBox.style.display="なし";
       }
    </スクリプト>
</本文>
</html>

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Javascript サンプル プロジェクトでの虫眼鏡効果の実装プロセス
  • JavaScript が Jingdong の虫眼鏡の特殊効果を模倣
  • 虫眼鏡ケースのJavaScriptオブジェクト指向実装
  • JavaScript が Jingdong の虫眼鏡効果を模倣
  • JavaScript が Taobao の虫眼鏡効果を模倣
  • 虫眼鏡効果を実現するJavaScript
  • js で虫眼鏡効果を実現するためのアイデアとコード
  • 虫眼鏡の詳細のJavaScript実装

<<:  フレームセットを使用してワイドスクリーンを中央に配置するためのヒントを共有する

>>:  個人的な意見: デザインについて語る

推薦する

React コンポーネントのコンストラクタとスーパーの知識ポイントのまとめ

1. Reactでクラス宣言する際のヒント 上記のように、Child クラスは class キーワー...

Ubuntu Server 16.04 MySQL 8.0 のインストールと設定のグラフィックチュートリアル

Ubuntu Server 16.04 MySQL 8.0 のインストールと設定のグラフィックチュー...

VMware ESXi 6.0 および仮想マシンのインストール チュートリアルの展開 (画像とテキスト)

社内には以前からアイドル状態だった、構成の整ったサーバーがあったので、EXSI 6.0 を使って複数...

CSS でより美しいリンクプロンプト効果をカスタマイズする方法

提案: コードをできるだけ手書きすると、学習の効率と深さを効果的に向上できます。デフォルトでは、&l...

Django+vue 登録とログインのサンプルコード

登録するフロントエンドは、vue の axios を使用して値を渡し、取得したアカウントとパスワード...

HTML/XHTML における img 画像タグの基本的な使用法の詳細な説明

画像タグは、Web ページに画像を表示するために使用されます。 HTML/XHTML 画像 <...

pdf.js を使用して Vue で PDF ファイルをプレビューする方法

ページ上で PDF をプレビューすると、一部のファイルは印刷またはダウンロードできません。現時点では...

ウェブデザインを改善するための 8 つの CSS ツールを共有する

ウェブサイトのデザインを編集または変更する必要がある場合、CSS が重要な役割を果たします。 CSS...

JavaScript Canvas で三目並べゲームを実装

この記事では、JavaScript Canvasで三目並べゲームを実装するための具体的なコードを参考...

GIFアニメーション効果を模倣した自動ビデオ再生を実現するWeChatアプレットの例

需要背景:ミニプログラムページに GIF ダイナミック画像を挿入しますが、GIF 画像は通常サイズが...

Docker ベースの Redis クラスターの構築方法

Redisイメージをダウンロードする docker pull yyyyttttwww/redis を...

MySQL で遅い SQL 文を見つける方法

MySQL で遅い SQL ステートメントを見つけるにはどうすればよいでしょうか?これは、多くの人を...

HTMLは実際にはいくつかの重要なタグを学ぶアプリケーションです

「これは革命になるだろう」という記事が出たあと。業界の皆様に認知され、もちろん内外からの評価もいただ...

MySQL 8.0.11 圧縮版のインストールチュートリアル

この記事では、MySQL 8.0.11のインストールチュートリアルを参考までに紹介します。具体的な内...

Win10 に Linux ubuntu-18.04 デュアル システムをインストールする (インストール ガイド)

コンピューターに Linux Ubuntu システムをインストールしました。初めてインストールしまし...