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実装

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

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

推薦する

MySQL/MariaDB ルートパスワードリセットチュートリアル

序文パスワードを忘れることは、よく遭遇する問題です。MySQL または MariaDB データベース...

カスタムスクロールバー効果を実現するJavaScript

実際のプロジェクトでは、上下のスクロール バーと左右のスクロール バーは DIV 内にないため、右の...

MySQLで時間別データと最後の時間別データの差をクエリするアイデアの詳細な説明

1. はじめに要件は、特定の時間範囲内で、1 時間ごとのデータと前の 1 時間ごとのデータの差と比率...

5分でWebRTCビデオチャットを構築する

前回の記事では、Ubuntu 上の webrtc ベースの多人数ビデオチャット サービスの詳細なコー...

Minio 軽量オブジェクト ストレージ サービスのインストールとブラウザの使用チュートリアル

目次導入インストール1. マウントするフォルダを作成する2. イメージをプルする3. コンテナを作成...

Linux exa コマンド (ls よりも優れたファイル表示エクスペリエンス)

インストールREADMEに従ってインストールしてくださいドキュメントには、exa は Rust で実...

1 行または複数行のテキストがオーバーフローしたときに省略記号を表示する CSS を実装する方法

1. 単一行オーバーフロー1. 1 行がオーバーフローした場合、超過部分は表示されます...または、...

Web アプリ開発時間を短縮する 10 の時間を節約するヒント (グラフィカル チュートリアル)

今日の開発環境では、速いほど良いです。 「迅速なアプリケーション開発」、「アジャイル ソフトウェア開...

JSONP クロスドメインシミュレーション Baidu 検索

目次1. JSONPとは何か2. JSONPクロスドメインリクエスト3. Baidu検索をシミュレー...

Windows 10 に MySQL 8.0.19 を zip 形式でインストールする詳細なチュートリアル

目次1.ダウンロード後、インストールしたいディレクトリに解凍します。 2. インストールディレクトリ...

WindowsでiTunesのバックアップパスを変更する方法

0. 準備: • iTunesを閉じる• タスクマネージャーでiTunesから始まるサービスを終了し...

Linuxファイアウォールiptablesの詳細な紹介、設定方法と事例

1.1 iptablesファイアウォールの概要Netfilter/Iptables (以下、Ipta...

ユニアプリとミニプログラム(画像とテキスト)を下請けする方法を教えます

目次1. ミニプログラム下請け2. Uniapp 下請けアプレット下請けの手順: 1. manife...

Docker Gitlab+Jenkins+Harborは永続的なプラットフォーム運用を構築します

CI/CD の概要CIワークフロー設計Gitコードバージョン管理システムはコマンドラインでのみ管理で...

MySQL累積計算実装方法の詳しい説明

目次序文需要分析MySQL ユーザー変数累積計算にMysqlユーザー変数を使用する要約するこの記事で...