实现原理

放大镜的原理用一句话概括,就是根据小图上的鼠标位置去定位大图。

原理图(以2倍放大为例)

相信原理图已经画的很明白了, 图中,左侧框是小图框,其蓝色区域为图片遮罩层(需放大区域),右侧框是整个大图目前所在区域,其蓝色区域是放大区域,设置超出隐藏,就实现了放大遮罩区域的效果。
显然,两块蓝色区域存在着某种对应关系,即遮罩的左上角位置(相对于小图,以下称 X 坐标)和放大区域(相对于大图)的左上角位置是成比例的,即放大倍数。计算出 X 坐标后,适当调整背景图的位置,使大图向反方向移动 scale 倍的 X 坐标即可。
X 坐标为(maskX,maskY),以计算 maskX 为例:
鼠标移动中会产生 e.clientX ,标识鼠标与浏览器左侧的距离,小图与浏览器左侧的距离是 left ,由于遮罩始终是一个以鼠标为中心的正方形,所以:
maskX = e.clientX - left - mask/2
同理,
maskY = e.clientY - top - mask/2
大图的对应样式设置为:

{left: - maskX * scale + 'px';top: - maskY * scale + 'px';
}

效果演示

我引用的ui库是elementui,因为我当时需要的是商品可以轮播在加上商品放大效果,如果是简单的商品图片放大大家百度应该方法都差不多,大致都能实现,可是我因为商品需要在x轴上轮播,就必须在css上面加 overflow-x: hidden;我看了几个轮播插件,好像都需要加,因为如果加了 overflow的话,放大的图就不能出现了,后来想了好多办法,找到一种解决办法,代码如下:

<el-carousel height="360px" indicator-position="none" :autoplay="false" @change="changeshop"><el-carousel-item v-for="item in 2" :key="item"><div class="magnifier"><div class="small-box" @mouseover="handOver"  @mousemove="handMove" @mouseout="handOut"><img class="smallPic" src="@/static/img/good-img.jpg" /><div class="magnifier-zoom" v-show="showMask":style="{background: configs.maskColor,height: configs.maskWidth + 'px',width: configs.maskHeight + 'px', opacity: configs.maskOpacity, transform: transformMask}"></div></div></div></el-carousel-item></el-carousel><div class="magnifier-layer" v-show="showMagnifier":style="{ width: configs.width + 'px', height: configs.height + 'px', left: configs.width + 20 + 'px' }"><div class="big-box":style="{ width: bigWidth + 'px',height: bigHeight + 'px',left: moveLeft,top: moveTop}"><div class="big-box-img":style="{ width: bigWidth - 2  + 'px', height: bigHeight - 2 + 'px' }"><imgsrc="@/static/img/good-img.jpg":style="{ minWith: bigWidth - 2 + 'px', minHeight: bigHeight -2 + 'px' ,}"/></div></div></div>

如果大家不需要轮播的话可以直接写下面的代码:

 <div class="magnifier"><!-- 小图 --><div class="small-box" @mouseover="handOver"  @mousemove="handMove" @mouseout="handOut"><img class="smallPic" src="@/static/img/good-img.jpg" /><div class="magnifier-zoom" v-show="showMask":style="{background: configs.maskColor,height: configs.maskWidth + 'px',width: configs.maskHeight + 'px', opacity: configs.maskOpacity, transform: transformMask}"></div></div><!-- 大图, 注意误差 --><div class="magnifier-layer" v-show="showMagnifier":style="{ width: configs.width + 'px', height: configs.height + 'px', left: configs.width + 20 + 'px' }"><div class="big-box":style="{ width: bigWidth + 'px',height: bigHeight + 'px',left: moveLeft,top: moveTop}"><div class="big-box-img":style="{ width: bigWidth - 2  + 'px', height: bigHeight - 2 + 'px' }"><imgsrc="@/static/img/good-img.jpg":style="{ maxWidth: bigWidth - 2 + 'px', maxHeight: bigHeight -2 + 'px' }"/></div></div></div></div>

css:

.small-box{position: relative;}
.magnifier-zoom{position: absolute;top: 0;left: 0;
}
.magnifier-layer{position: absolute;top: 0;right: 0;z-index: 1000;overflow: hidden;background-color: #fff;
}
.big-box{position: absolute;
}.magnifier{position: relative;width: 580px;height: 360px;border-radius: 8px;}.smallPic{width: 580px;height: 360px;border-radius: 8px;}
 computed: {bigWidth(){return this.configs.scale * this.configs.width;},bigHeight(){return this.configs.scale * this.configs.height;}},mounted () {this.$init()},data(){return {configs:{width:570,//放大区域height:360,//放大区域maskWidth:210,//遮罩maskHeight:210,//遮罩maskColor:'rgba(25,122,255,0.5)',//遮罩样式maskOpacity:0.6,scale:2,//放大比例},imgObj: {},moveLeft: 0,moveTop: 0,transformMask:`translate(0px, 0px)`,showMagnifier:false,showMask:false,}},  methods: {$init(){setTimeout(() => {this.imgObj = this.$el.getElementsByClassName('small-box')[0].getBoundingClientRect();}, 500);},changeshop(e){this.showMagnifier = false;this.showMask = false;this.transformMask = `translate(0px, 0px)`this.moveLeft = 0this.moveTop = 0},handMove(e) {// 动态获取小图的位置(或者监听 scroll )let imgRectNow = this.imgObj;let objX = e.clientX - imgRectNow.left;let objY = e.clientY - imgRectNow.top;// 计算初始的遮罩左上角的坐标let maskX = objX - this.configs.maskWidth / 2;let maskY = objY - this.configs.maskHeight / 2;// 判断是否超出界限,并纠正maskY = maskY < 0 ? 0 : maskY; maskX = maskX < 0 ? 0 : maskX; if(maskY + this.configs.maskHeight >= imgRectNow.height) {maskY = imgRectNow.height - this.configs.maskHeight;}if(maskX + this.configs.maskWidth >= imgRectNow.width) {maskX = imgRectNow.width - this.configs.maskWidth;}// 遮罩移动this.transformMask = `translate(${maskX}px, ${maskY}px)`;// 背景图移动this.moveLeft = - maskX * this.configs.scale + "px";this.moveTop = - maskY * this.configs.scale + "px";},handOut() {this.showMagnifier = false;this.showMask = false;},handOver() {this.showMagnifier = true;this.showMask = true;}},

如果不需要轮播图的话就可以不写changeshop这个方法就行,其余的都一样的

采坑结束,如果大家有更好的方法,欢迎在评论里告诉我哦~~~

基于vue商品图片轮播和放大镜的方案相关推荐

  1. 淘宝店铺装修之一怎样在自定义内容区做个商品图片轮播展示

    <wbr><span style="font-size:24px"><strong>店铺装修之一怎样在自定义内容区做个商品图片轮播展示</ ...

  2. 基于面向对象的图片轮播(js原生代码)

    无论你想走多远,你都需要不断地走下去.前端最精华的便是原生的js,这也是我们前端工程师的技术分层的重要指标,也提现这你的代码能力,开发的水平.废话不多说,进入今天的主要分享----基于面向对象思想的图 ...

  3. vue 实现无限轮播_使用Vue制作图片轮播组件思路详解

    之前一直都没有认真的写过一个组件.以前在写业务代码的过程中,都是用的别人封装好的组件,这次尝试着写了一个图片轮播组件,虽然比不上知名的轮播组件,但它的功能基本完整,而且在写这个组件的过程中,学的东西也 ...

  4. 安卓开发——基于ViewPager的图片轮播

    概述: 要用ViewPager实现图片轮播,主要是两步: 1:用PagerAdapter使图片可以滑动切换 2:用Handler来实现图片自动轮播 页面布局部分的代码: <?xml versio ...

  5. vue实现图片轮播二

    直接上代码吧 包含了鼠标放入移出,点击上一张下一张,自动播放. 还没做拖拽前进后退. 图片的切换部分是想模拟一个1/x的这么一个切换速度的曲线. <template><div cla ...

  6. 实现一个基于jQuery的图片轮播效果(带自动播放)

    data.json {"data": [{"title": "西游题材小游戏合辑","subtitle": " ...

  7. PgwSlideshow-基于Jquery的图片轮播插件

    友情链接:http://www.htmleaf.com/Demo/201504031619.html  http://www.htmleaf.com/Demo/201504191708.html 0 ...

  8. jquery手写轮播图_15个超强的jQuery/HTML5图片轮播插件

    最近我们为大家分享过不少基于jQuery的图片轮播插件,当然也有很多使用了HTML5和CSS3的相关技术,让整个图片播放器显得更加美观,动画效果显得更加炫酷.这次我们特意为大家筛选了一些最新的jQue ...

  9. html5+自动播放轮播插件,15个超强的jQuery/HTML5图片轮播插件

    最近我们为大家分享过不少基于jQuery的图片轮播插件,当然也有很多使用了HTML5和CSS3的相关技术,让整个图片播放器显得更加美观,动画效果显得更加炫酷.这次我们特意为大家筛选了一些最新的jQue ...

最新文章

  1. MySQL 性能跟踪语句
  2. Java 流程控制与数组
  3. leetcode —— 752. 打开转盘锁
  4. Java基础04 编译与反编译
  5. 利用jemalloc分析内存泄漏以及LD_PRELOAD
  6. 力扣26,删除重复项(JavaScript)
  7. linux 扩lv文件系统,Linux LVM系列(五)lv xfs文件系统在线扩容
  8. is和as在类型转换时的性能差异
  9. Tizen已经够烂了 但份额还是超过了黑莓
  10. C# .NET 爬虫抓取京东商城所有商品分类
  11. HTML和jquery实现播放功能
  12. Android 仿淘宝首页界面
  13. E-day0003:generate
  14. 阿里云注册域名,购买云服务器,备案,域名解析图文教程
  15. JavaScript的一些简单代码
  16. Fast Non-Bayesian Poisson Factorization for Implicit-Feedback Recommendations
  17. android 自动安装 解析包错误,安卓android手机安装包频繁提示解析错误解决方法...
  18. 数据结构——顺序表的实现
  19. 出现了,PPT 制作新方式
  20. https web service(转)

热门文章

  1. 拼多多报活动没有流量怎么办 拼多多活动流量少是什么原因
  2. 非冯诺依曼体系计算机,一种新非冯·诺依曼计算机体系结构.pdf
  3. 虚拟运行ur5时,出现的问题
  4. python 函数定义 编译_Cython编译的模块不允许访问函数定义的“module”而不是callab...
  5. 用于播放视频的Html5元素是,HTML5多媒体播放video元素与audio元素详解
  6. xPC信号采集和分析(2)
  7. 有道云笔记Android app离线缓存,有道云笔记文件保存在哪里在哪个路径下
  8. ICC2(一)import design —— NDM
  9. python调用微信客户端_用Python编写的简化版微信客户端
  10. autojs安卓10,11泡椒云提示无法读取imei码解决方案