ホームページ > 記事 > ウェブフロントエンド > CSSを使って写真の虫眼鏡効果を実現する例を詳しく解説(写真)
この記事では、CSS を使用して 画像 虫眼鏡効果 を実現する方法について説明します? 以下は画像拡大鏡効果の CSS 例の詳細な説明
効果は写真に示すとおりです (例では、密かに Tmall の写真をリンクしました。何も起こらないことを願っています -.-):
実装プロセスは簡単ですが、CSS 解析から開始します。プロセスは次のとおりです (例: 画像は四角形になっています):
css:
/* 图片容器 */ .imgBox{ width: 200px; /* 各位大老爷们看着办 */ height: 200px; /* 各位大老爷们看着办 */ position: relative; /* 必需 */ } /* 图片标签 */ .mainImg{ width: 100%; /* 各位大老爷们看着办,尽量100%好看些[斜眼笑] */ height: 100%; /* 各位大老爷们看着办,尽量100%好看些[斜眼笑] */ } /* 遮罩层-既放大区域 */ .glass{ position: absolute; /* 必需 */ width: 50px; /* 遮罩层宽度 此处是放大4倍,所以为200/4=50 */ height: 50px; /* 遮罩层高度 此处是放大4倍,所以为200/4=50 */ top: -9999px; /* 绝对位置,先放远些 */ left: -9999px; /* 绝对位置,先放远些 */ cursor: move; /* 鼠标样式,好看些 */ background: rgba(0,0,180,0.5); /* 遮罩层样式,好看些 */ } /* 大图所在的容器 */ .imgMax{ position: absolute; /* 必需 */ overflow: hidden; /* 必需,盖掉超出的大图[斜眼笑] */ left: 210px; /* 必需,此处为距原图左边10像素 */ top: 0; /* 必需,此处为距上边0像素 */ width: 200px; /* 放大图片容器的宽度 此处此处是放大4倍,为200,保持和原图容器一般大,若此处为400,则是放大2*4倍,那么相应的放大图片应该是200*4*2=1600 */ height: 200px; /* 放大图片容器的高度 此处此处是放大4倍,为200,保持和原图容器一般大,若此处为400,则是放大2*4倍,那么相应的放大图片应该是200*4*2=1600 */ display: none; /* 先隐藏 */ } .maxImg{ position: absolute; /* 必需 */ width: 800px; /* 此处是放大4倍,所以为200*4=800 受放大图片所在的容器影响,规则如上 */ height: 800px; /* 此处是放大4倍,所以为200*4=800 受放大图片所在的容器影响,规则如上 */ }
上記の CSS で注意する必要がある点はいくつかあります。位置と拡大縮小率に注意してください
スタイルを記述した後、レイアウトを見てみましょう:
html:
<!-- 图片容器 --> <pclass="J_imgBox imgBox"> <!-- 需要放大的图片-原始图 --> <imgclass="J_mainImg mainImg" src="http://img.alicdn.com/bao/uploaded/i7/TB1Xpe_NXXXXXXRXFXXGTq09XXX_035318.jpg_430x430q90.jpg"/> <!-- 遮罩-既放大的区域 --> <pclass="J_glass glass"></p> <!-- 大图的容器 --> <pclass="J_imgMax imgMax"> <!-- 大图 --> <imgclass="J_maxImg maxImg"/> </p> </p>
以下は、いつものようにコメント付きのメインの JS コードです:
js :
(function(){ /* 放大镜函数 ** @imgContainer 需要实现放大镜效果的图片容器 此处是 class 为 J_imgBox 的 p */ function imgZoom(imgContainer){ // 取大图url,不知道淘宝图片规则如何,反正看了详情页的大图和小图url对比,随便写了个替换 var imgUrl = imgContainer.querySelector('.J_mainImg').src.replace(/.(jpg|jpeg|png|gif)(_)(d+)(x)(d+)(q90)?/g,''); // 取大图标签的节点 var maxImg = imgContainer.querySelector('.J_maxImg'); // 给该节点的src属性赋值为大图的url maxImg.src = imgUrl; // 取大图所在的容器 var maxImgContainer = imgContainer.querySelector('.J_imgMax'); // 取遮罩块 var glassBlock = imgContainer.querySelector('.J_glass'); // 取消放大镜效果 var hideMaxImg = function(){ glassBlock.style.top = '-9999px'; glassBlock.style.left = '-9999px'; maxImgContainer.style.display = 'none'; } // 鼠标移出图片区域,取消放大镜效果 imgContainer.onmouseout = function(event){ event.stopPropagation(); hideMaxImg(); }; // 鼠标在图片区域内移动事件 imgContainer.onmousemove = function(event) { event.stopPropagation(); // 取图片容器的大小及其相对于视口的位置,需要实时取,所以放在move事件里 var clientRect = event.currentTarget.getBoundingClientRect(); // 获取距鼠标距的上和左的坐标 var leftX = event.clientX - clientRect.left; var leftY = event.clientY - clientRect.top; // 动态设置遮罩块的left和top位置 这里需要减去遮罩层的一半,因为鼠标位于遮罩块中心点 var pointerLeft = leftX - 25; var pointerTop = leftY - 25; // 如果鼠标坐标移动超出原始图片区域边缘 则取消放大镜效果 因为这里存在快速移动鼠标到大图区域时,鼠标仍处在外层的图片区域内,并不会触发mouseout事件(虽然中间隔了小小的间距,但是快速移动仍能产生这个bug,如代码下面的图所示) if((pointerLeft+25) > clientRect.width || pointerLeft clientRect.height || pointerTop ){ hideMaxImg(); return !1; }; // 遮罩块在最左边的时候,鼠标仍在图片区域内,可在遮罩块左边缘至中心线区域内移动,且这时遮罩块为距左0像素 if(pointerLeft ){ pointerLeft = 0; }; // 同上 右边限制 if(pointerLeft > clientRect.width - 50){ pointerLeft = clientRect.width - 50; }; // 同上 顶部限制 if(pointerTop ){ pointerTop = 0; }; // 同上 底部限制 if(pointerTop > clientRect.height - 50){ pointerTop = clientRect.height - 50; }; // 设置遮罩块的位置 glassBlock.style.left = pointerLeft; glassBlock.style.top = pointerTop; // 取遮罩快距离左边的位置和图片区域的宽高比,用于计算大图偏移距离,展示遮罩块所对应的图片区域 var percentLeft = pointerLeft/clientRect.width; var percentHeight = pointerTop/clientRect.height; // 设置大图偏移距离 因为其父元素存在 overflow:hidden 所以只会展示对应区块 maxImg.style.left = -(percentLeft*maxImg.clientWidth)+'px'; maxImg.style.top = -(percentHeight*maxImg.clientHeight)+'px'; }; } var elem = document.querySelectorAll('.J_imgBox'); elem.forEach(function(item,idx){ imgZoom(item) }) })()
バグ修正画像:
これを読んで、あまりにも簡単ではないと思いますか? 次に見てみましょう 上記のコードから、日常の開発におけるいくつかの実践的な知識ポイントを抽出できます。 :
Element.getBoundingClientRect()
Element.getBoundingClientRect() メソッドは、要素のサイズとビューポートに対する相対的な位置を返します
例:
<bodystyle="width:1400;height:1000"> <pid="testp" style="width:10px;height:20px;background:#f00"></p> <script> (function(){ var elem = document.getElementById('testp'); document.body.addEventListener('click',function(){ console.log(elem.getBoundingClientRect()) },false) })() </script> </body>
効果は図に示すとおりです:
効果図から、ビューを移動してボディをクリックすると、印刷されたオブジェクトが要素のサイズとビューポートに対する相対的な位置を正しく返すことができることがわかります。Position
これ
Event
1.event.target およびevent.currentTarget
target: トリガーする要素を指すメソッドを使用して、要素が下/上にスクロールされたときに対応するイベントをトリガーすることもできます。 currentTarget: バインドされたイベント ハンドルの要素を指します
バインドされた
イベント ハンドラープログラムとトリガーとなるイベント ハンドラーが両方とも同じオブジェクトである場合のみ、2 つは同じですサンプル コード:
html:
<pid="ap"> 123 <pid="bp">456</p> </p>
js:
document.getElementById('ap').addEventListener('click',function(e){ if(e.target === e.currentTarget) { console.log('target === currentTarget') }else{ console.log('target !== currentTarget') } console.log('target',e.target) console.log('currentTarget',e.currentTarget) },false)
レンダリング:
レンダリングから、456 をクリックすると、ターゲットは 456 が配置されている bp を指し、currentTarget は を指すことがわかります。 ap。イベントは ap にバインドされていますが、トリガーは bp 上にあり、bp は ap 内にあります。123 をクリックすると、ターゲットは currentTarget と一致し、バインディングとトリガーの両方が
2 になります。 .event.preventDefault() &event.stopPropagation()
preventDefault: イベントがキャンセル可能な場合、イベントのさらなる伝播を停止せずにイベントをキャンセルします
stopPropagation: キャプチャおよびバブリングでの現在のイベントのさらなる伝播を防止しますphases
3.event.stopPropagation() &event.stopImmediatePropagation()
stopPropagation: キャプチャフェーズとバブリングフェーズでの現在のイベントのさらなる伝播を防ぎます
stopImmediatePropagation: 要素上の同じイベントを呼び出す他のイベントがリッスンしないようにしますバブリングを防ぎます
2 つの違いの例:
Html: re
<pid="ap"> 123 <pid="bp">456</p> </p>js:
document.getElementById('ap').addEventListener('click',function(){ console.log('click ap') },false) document.getElementById('bp').addEventListener('click',function(e){ e.stopImmediatePropagation(); console.log('click bp') },false) document.getElementById('bp').addEventListener('click',function(){ console.log('click me too') },false)E 上記のコードの結果は次のようになります:
clickbp
e e.stopimdiaTePropagation (); ポイントは、日常の開発でも非常に実用的です。何もすることがない場合は、詳細から始めてさらに検討してください。 -~
以上がCSSを使って写真の虫眼鏡効果を実現する例を詳しく解説(写真)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。