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

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

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

推薦する

文字列から指定された文字を削除または抽出する JavaScript メソッド (非常によく使用されます)

目次1. 部分文字列() 2. サブストラクチャ() 3.インデックス() 4.最後のインデックス(...

Linuxの貼り付けコマンドの使い方

01. コマンドの概要貼り付けコマンドは各ファイルを列ごとに結合します。これは、2 つの異なるファイ...

Tik Tok サブスクリプション ボタンのアニメーション効果を実現する CSS

少し前にTik Tokを見ていて、フォローするときのボタンアニメーションがとても美しいと思ったのと、...

Linuxコマンド履歴の調整方法の詳細な説明

Linux システムの bash history コマンドは、以前に実行したコマンドを記憶し、再入力...

CSS で水平方向と垂直方向に中央揃えする 10 の方法を教えます (要約)

面接には必需品、仕事でも必ず使います。うーん、誰でも分かるでしょう。これ以上何も言わずに、要約とレン...

IIS web.config でクロスドメイン アクセスを設定する方法

要件: ページに画像を表示する必要がありますが、さまざまな理由により、画像はサーバー 2 にあります...

Linux での MySQL 8.0 インストール チュートリアル

この記事では、LinuxでMySQL 8.0をインストールする方法を紹介します。具体的な内容は次のと...

Vueのシンプルな状態管理ストアモードを理解する方法

目次概要1. store.jsを定義する2. store.js を使用するコンポーネント3. 成果を...

MYSQL の binlog 最適化に関する考察の要約

質問質問 1: トランザクションをコミットするときに REDO ログをフラッシュすることによって発生...

Apache ポートに基づいて仮想ホストを作成する例

apache: ポートに基づいて仮想ホストを作成する仮想ホスト(a、b、c)の作成を例に挙げます1)...

HTMLにビデオを挿入してすべてのブラウザと互換性を持たせる方法

HTML にビデオを挿入するために最もよく使用される方法は 2 つあります。1 つは古い <o...

JavaScript でシンプルな Web 時計を実装する

JavaScript を使用して Web ページ クロックを実装します。効果は次の図に示されています...

ウェブデザインにおけるテキスト入力ボックスのパラメータの説明

<br />一般的なゲストブック、フォーラムなどでは、テキスト入力ボックスが使われていま...

Dockerリポジトリの一般的なコマンドの詳細な説明

ログイン dockerログインdocker login コマンドを実行し、ユーザー名、パスワード、メ...

TypeScript の条件型に関する詳細な読書と実践記録

目次ジェネリック型での条件型の使用ツールタイプ脱出ポッド矢印関数で条件型を使用する型推論による条件型...