vue项目——商品详情页面图片放大镜效果实现(完成)

本文详细介绍了如何在Vue.js项目中实现图片放大镜效果,包括HTML结构、CSS样式和JavaScript关键代码。通过监听鼠标移入移出、移动事件,结合背景图片的大小和位置调整,实现实时预览鼠标指针下的放大区域,为用户提供更好的商品详情查看体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天在做商品详情页面时,遇到一个需求,就是图片放大镜效果。在图片上鼠标划过时,右侧出现一个大图,用于展示鼠标移过的区域,也就是图片放大镜效果。
在这里插入图片描述

效果图基本类似如下:
在这里插入图片描述
我之前有篇文章js实现图片放大镜效果:https://blog.csdn.net/yehaocheng520/article/details/115278622?spm=1001.2014.3001.5501

当时是用js实现的效果,因此现在要把代码嫁接到vue创建的项目中。

html部分代码:

<div class="big-img-box" ref="big-img-box" @mouseleave="moveend">
  <div class="imgWrap" @mouseenter="movestart" @mousemove.stop>
    <img :src="HOST + commonUploadFileUrl + bigImgsrc" alt="" />
  </div>
  <div
    v-if="bigImgUrl"
    @mousemove.stop
    @mousemove="move"
    class="move"
    ref="move"
    :style="{ left: -left / 3 + 'px ', top: -top / 3 + 'px' }"
  ></div>
  <div
    class="bigPic"
    ref="bigPic"
    v-if="bigImgUrl"
    :style="{ backgroundPosition: left + 'px ' + top + 'px' }"
  ></div>
</div>
<div class="small-img-box">
  <div class="img-content-box">
    <ul>
      <li
        v-for="(item, index) in detailInfo.images"
        :key="index"
        @mouseover="handleBigImg(item, index)"
        :class="{ smallImgBorder: currentSmallImgIndex == index }"
      >
        <img :src="HOST + commonUploadFileUrl + item.src" alt="" />
      </li>
    </ul>
  </div>
</div>

图片放大镜效果的重点——cssjs部分

css部分的关键

这个效果有个特别的css样式,分析一下有几个元素;
左侧图片原图:这个就是个普通的图片,可以通过background设置图片路径,也可以是一个img标签来展示。
图片上的鼠标移动区域:这个比较需要注意的是:这个是个绝对布局,为了js部分计算简单,我使用了200x200的大小,颜色为一个偏透明的色号
右侧大图:这个也是个绝对布局,采用background的方式来设置图片路径和背景参数,background-size设置成大于1的参数。

css部分代码如下:

.big-img-box {
  width: 480px;
  height: 360px;
  margin: 0 0 20px;
  border: 1px solid #eee;
  position: relative;
  .imgWrap {
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
  .move {
    position: absolute;
    left: 0;
    top: 0;
    width: 200px;
    height: 200px;
    background: rgba(0, 0, 255, 0.15);
    cursor: move;
  }
  .bigPic {
    width: 480px;
    height: 480px;
    position: absolute;
    left: 480px;
    top: 0;
    border: 2px solid #f90;
    background-position: 0 0;
    background-size: 300% 300%;
    background-repeat: no-repeat;
    z-index: 2;
  }
}

原图下方的小图部分:就是一排普通的图片,css样式部分并无不同

.small-img-box {
  width: 480px;
  height: 70px;
  position: relative;
  .img-content-box {
    width: 100%;
    margin: 0 auto;
    height: 100%;
    display: block;
    ul {
      width: 105%;
      height: 100%;
      li {
        display: inline-block;
        width: 88px;
        height: 100%;
        margin-right: 10px;
        overflow: hidden;
        img {
          display: block;
          width: 100%;
        }
      }
    }
  }
}
js部分的关键——鼠标的移入移出事件+dom元素的位置及大小

在用js实现此效果时,需要用到几个重要的参数

  1. 左侧原图距离左侧的大小——oAppLeft
  2. 左侧原图距离上方的大小——oAppTop
  3. 鼠标移入后的位置e.pageX e.pageY,之前的js版本的效果用的是e.clientX e.clientY,这个e.clientX有问题,这个参数会跟着屏幕的滚动而发生变化,我们需要的是一个不会变化的值,鼠标的位置对于整个页面来说是固定的,而不是随着页面的滚动发生变化。
  4. 移动区域的大小——可以通过style.width style.height来获取,但是我在css部分为了方便,直接固定为200X200,因此我这边是直接使用的200的数值
    在这里插入图片描述
左侧原图距离左边和上边的大小——oAppLeftoAppTop的计算
mounted() {
  this.$nextTick(() => {//页面加载完成后再去获取`dom`元素的位置
    this.oAppLeft = this.$refs["big-img-box"].offsetLeft;
    this.oAppTop = this.$refs["big-img-box"].offsetTop;
  });
},
针对普通的dom元素可以通过this.$refs[xxx].xxx的方式来获取
针对v-for等渲染的dom元素可以通过this.$refs[xxx][0].xxx的方式来获取

鼠标移入移出需要注意的部分:

  1. 左侧原图具体展示哪张图片可以根据一个字段bigImgUrl来处理。下方下图鼠标移入时,更改bigImgUrl的值,就可以了
  2. 鼠标移入到左侧原图时,开始出现选择框,右侧展示选择框中的图片放大效果,也就是说:左侧原图需要加一个鼠标移入的监听事件
<div class="big-img-box" ref="big-img-box" @mouseleave="moveend">
    <div class="imgWrap" @mouseenter="movestart" @mousemove.stop>
      <img :src="HOST + commonUploadFileUrl + bigImgsrc" alt="" />
    </div>
	<div v-if="bigImgUrl" @mousemove.stop @mousemove="move" class="move" ref="move"
	:style="{ left: -left / 3 + 'px ', top: -top / 3 + 'px' }"></div>
          <div class="bigPic" ref="bigPic" v-if="bigImgUrl" :style="{ backgroundPosition: left + 'px ' + top + 'px' }">		  		           </div>
</div>

上面html结构中的class='imgWrap'就是左侧原图部分

鼠标移入的函数——鼠标移入的位置就是选择框的初始位置
//鼠标移入后,就要展示选择框,因此鼠标移入的位置跟选择框的位置有关
movestart(e) {
  this.move(e);
  this.bigImgUrl = this.bigImgsrc;
  var imgUrl = this.HOST + this.commonUploadFileUrl + this.bigImgUrl;//这个就是当前图片的路径,不管多管
  this.$nextTick(() => {//页面加载完成后,更改大图的`backgroundImage`,这个也可以直接在html中动态绑定style,那样会简单很多
    this.$refs.bigPic.style.backgroundImage = `url(${imgUrl})`;
  });
},
选择框鼠标移动的位置——改变选择框的位置
//鼠标移动时,选择框的位置也会发现改变
move(e) {
  var left = e.pageX - this.oAppLeft - 100;
  var top = e.pageY - this.oAppTop - 100;
  if (left < 0) {
    left = 0;
  } else if (left > 280) {
    left = 280;
  }
  if (top < 0) {
    top = 0;
  } else if (top > 160) {
    top = 160;
  }
  this.left = -left * 3;
  this.top = -top * 3;
},
左侧原图鼠标移出——隐藏选择框和大图(将bigImgUrl置为空即可)
     moveend() {
      this.bigImgUrl = "";
      this.left = 0;
      this.top = 0;
    },

最终功能实现!!!!

补充:注意事项——上面的比例部分有问题,更改如下:

1.左侧原图最好是设置为div的背景图片
<div class="imgWrap" @mouseenter="movestart" @mousemove.stop :style="{backgroundImage: `url(${HOST + commonUploadFileUrl + bigImgsrc})`}">

因为图片放大镜的原理就是通过backgroundSize+backgroundPostion两个属性配合使用的。为了保证左侧原图和右侧大图保持一致。最好统一都设置为背景图片。如果左侧原图不设置为背景图片,则需要将class="imgWrap"中的img宽高设置为100%.

2.比例是怎么来的?

在这个项目中,有用到两个比例,一个是右侧大图backgroundSize,一个是右侧大图的位置left top的计算比例。

在这里插入图片描述
注意此处的background-size的比例跟左侧原图的宽高是有关系的。
在这里插入图片描述
左侧原图的宽高比例是:480:360,也就是:4:3;因此右侧大图的background-size应该设置为400% 300%;上面的比例是错误的。或者可以将左侧原图的大小改为:width:360px;height:360px;,则此时的右侧大图的background-size可以设置为300% 300%,也就是方法3倍的意思。

this.left this.top的比例是怎么来的????
在这里插入图片描述
注意这个地方:左侧原图上的选择框大小是:width:200px height:200px ,右侧大图的大小是:width:360px; height:360px;,也就是右侧大图是左侧选择框的1.8倍,因此此处的比例应该是1.8,上面的内容应该改为:this.left = -left * 1.8;this.top = -top*1.8;

选择框在左侧原图中的边界计算:

一定要注意:我们计算的是选择框的left top值,也就是左上角顶点的位置。

因此选择框的边界4个值就是:(0,0) (左侧原图的宽度-选择框的宽度,0) (左侧原图的宽度-选择框的宽度,左侧原图的高度-选择框的高度) (0,左侧原图的高度-选择框的高度)

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶浩成520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值