仿京东产品图放大镜效果优化版与jQZoom v2.0插件实现放大镜效果

放大镜

放大镜顾名思义就是放大某一样东西,显示更多的细节给用户查看。左边是小图,右边是大图;当鼠标放在小图上时,右边的大图会显示对应的细节。代码来自于黑马程序员视频教程,但是黑马的程序父盒子没有position属性, preview_img盒子相对于body定位,但在实际开发中不能做到preview_img盒子其父元素并没有定位元素,本文代码封装了offset()函数,即使review_img盒子父级盒子有定位时,也可获得当前盒子相对于body的偏移量。

效果如图1所示:

图1

代码解析:

x,y 为鼠标在 preview_img 盒子里的坐标

var x = e.pageX - this.offsetWidth;
var y = e.pageY - this.offsetHeight;

image


遮罩层的鼠标坐标居中,盒子往上走一半,往左走一半

var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;

image

由于减去了遮罩层宽度的一半(maskX = x - mask.offsetWidth / 2; ),所以实际位置【以纯黄色图层为主】是
image

但是,限定遮罩层在preview_img盒子中的位置,所以我们看到的是:【以纯黄色图层为主】
image


小图和大图实际上是成比例关系的。我们无需关心这个比例(X)具体是多少,只需要知道大图该移动多少距离。由图中公式可知,遮罩层的移动距离、遮罩层的最大移动距离和大图最大移动距离我们都是可知的。所以,大图移动的距离 = 遮罩层移动距离 * 大图最大移动距离 / 遮挡层的最大移动距离。

image

完整代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>仿京东放大镜效果</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      #box {
        position: relative;
        left: 200px;
        top: 100px;
      }
      .preview_img {
        position: relative;
        width: 300px;
        height: 300px;
        display: block;
      }
      .preview_img img {
        width: 300px;
        height: 300px;
      }
      .mask {
        position: absolute;
        top: 0;
        width: 200px;
        height: 200px;
        background-color: #fede4f;
        opacity: 0.4;
        border: 1px solid #ccc;
        cursor: move;
        display: none;
      }
      .big {
        position: absolute;
        top: 0;
        left: 310px;
        width: 540px;
        height: 540px;
        overflow: hidden;
        display: none;
      }
      .big img {
        position: absolute;
        top: 0;
        left: 0;
      }
    </style>
  </head>
  <body>
    <!-- 外层盒子 -->
    <div id="box">
      <!-- 小图 -->
      <div class="preview_img">
        <img src="./static/img.jpg" alt="手机" />
        <!-- 遮罩层 -->
        <div class="mask"></div>
      </div>
      <!-- 大图 -->
      <div class="big">
        <!-- 这里放大图 -->
        <img src="./static/big.jpg" alt="手机" class="bigImg" />
      </div>
    </div>
  </body>

  <script>
    var preview_img = document.querySelector(".preview_img");
    var mask = document.querySelector(".mask");
    var big = document.querySelector(".big");

    // 鼠标经过与离开的效果
    preview_img.addEventListener("mouseover", function () {
      mask.style.display = "block";
      big.style.display = "block";
    });
    preview_img.addEventListener("mouseout", function () {
      mask.style.display = "none";
      big.style.display = "none";
    });

    preview_img.addEventListener("mousemove", function (e) {
      // x,y 为鼠标在 preview_img 盒子里的坐标
      var x = e.pageX - offset(preview_img, 'left');
      var y = e.pageY - offset(preview_img, 'top');

      // var x = e.pageX - this.offsetWidth;
      // var y = e.pageY - this.offsetHeight;
      // maskX,maskY为遮罩层移动距离的坐标。遮罩层的鼠标坐标居中,盒子往上走一半,往左走一半
      var maskX = x - mask.offsetWidth / 2;
      var maskY = y - mask.offsetHeight / 2;
      var maskMax = preview_img.offsetWidth - mask.offsetWidth;

      // 限定遮罩层在preview_img盒子中的位置
      if (maskX <= 0) maskX = 0;
      else if (maskX >= maskMax) maskX = maskMax;
      if (maskY <= 0) maskY = 0;
      else if (maskY >= maskMax) maskY = maskMax;

      mask.style.left = maskX + "px";
      mask.style.top = maskY + "px";
      // 遮挡层与大图之间存在比例:大图移动的距离 / 大图最大移动距离 = 遮罩层移动距离 / 遮挡层的最大移动距离
      // 大图移动的距离 = 遮罩层移动距离 * 大图最大移动距离 / 遮挡层的最大移动距离
      var bigImg = document.querySelector(".bigImg");
      var bigMax = bigImg.offsetWidth - big.offsetWidth;
      var bigX = (maskX * bigMax) / maskMax;
      var bigY = (maskY * bigMax) / maskMax;

      bigImg.style.left = -bigX + "px";
      bigImg.style.top = -bigY + "px";
    });

    // 获得偏移量。当小图父级有定位时,获得当前盒子相对于body的偏移量
    function offset(obj, direction) {
      //将top,left首字母大写,并拼接成offsetTop,offsetLeft
      var offsetDir =
        "offset" + direction[0].toUpperCase() + direction.substring(1);

      var realNum = obj[offsetDir];
      var positionParent = obj.offsetParent; //获取上一级定位元素对象

      while (positionParent != null) {
        realNum += positionParent[offsetDir];
        positionParent = positionParent.offsetParent;
      }
      return realNum;
    }
  </script>
</html>

代码下载:
https://wybing.lanzouw.com/ilANP0jlwrpa2

jQZoom v2.0插件

jQZoom v2.0基于jQuery的图片放大插件,可以通过简单的配置实现放大镜效果。

$(document).ready(function(){
	$(".jqzoom").jqueryzoom({
		xzoom: 450, //显示大图的区域的宽度大小
		yzoom: 450, //显示大图的区域的高度大小
		offset: 10, //偏移的位置
		position: "right" //显示的放大镜框位于原来小图显示的哪个方向
	});
});

实现效果图:
图2

代码下载:
https://wybing.lanzouw.com/iZ0PC0jlwrqb

abPicZoom插件

image

演示及下载地址:http://ab.geshai.com/other-plus/abPicZoom/abPicZoom.html


代码来自于:黑马程序员视频教程
offset()方法封装:汪小穆的博客

posted @ 2022-12-29 05:20  乌药ice  阅读(117)  评论(0编辑  收藏  举报