基于vue商品图片轮播和放大镜的方案
实现原理
放大镜的原理用一句话概括,就是根据小图上的鼠标位置去定位大图。
原理图(以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商品图片轮播和放大镜的方案相关推荐
- 淘宝店铺装修之一怎样在自定义内容区做个商品图片轮播展示
<wbr><span style="font-size:24px"><strong>店铺装修之一怎样在自定义内容区做个商品图片轮播展示</ ...
- 基于面向对象的图片轮播(js原生代码)
无论你想走多远,你都需要不断地走下去.前端最精华的便是原生的js,这也是我们前端工程师的技术分层的重要指标,也提现这你的代码能力,开发的水平.废话不多说,进入今天的主要分享----基于面向对象思想的图 ...
- vue 实现无限轮播_使用Vue制作图片轮播组件思路详解
之前一直都没有认真的写过一个组件.以前在写业务代码的过程中,都是用的别人封装好的组件,这次尝试着写了一个图片轮播组件,虽然比不上知名的轮播组件,但它的功能基本完整,而且在写这个组件的过程中,学的东西也 ...
- 安卓开发——基于ViewPager的图片轮播
概述: 要用ViewPager实现图片轮播,主要是两步: 1:用PagerAdapter使图片可以滑动切换 2:用Handler来实现图片自动轮播 页面布局部分的代码: <?xml versio ...
- vue实现图片轮播二
直接上代码吧 包含了鼠标放入移出,点击上一张下一张,自动播放. 还没做拖拽前进后退. 图片的切换部分是想模拟一个1/x的这么一个切换速度的曲线. <template><div cla ...
- 实现一个基于jQuery的图片轮播效果(带自动播放)
data.json {"data": [{"title": "西游题材小游戏合辑","subtitle": " ...
- PgwSlideshow-基于Jquery的图片轮播插件
友情链接:http://www.htmleaf.com/Demo/201504031619.html http://www.htmleaf.com/Demo/201504191708.html 0 ...
- jquery手写轮播图_15个超强的jQuery/HTML5图片轮播插件
最近我们为大家分享过不少基于jQuery的图片轮播插件,当然也有很多使用了HTML5和CSS3的相关技术,让整个图片播放器显得更加美观,动画效果显得更加炫酷.这次我们特意为大家筛选了一些最新的jQue ...
- html5+自动播放轮播插件,15个超强的jQuery/HTML5图片轮播插件
最近我们为大家分享过不少基于jQuery的图片轮播插件,当然也有很多使用了HTML5和CSS3的相关技术,让整个图片播放器显得更加美观,动画效果显得更加炫酷.这次我们特意为大家筛选了一些最新的jQue ...
最新文章
- MySQL 性能跟踪语句
- Java 流程控制与数组
- leetcode —— 752. 打开转盘锁
- Java基础04 编译与反编译
- 利用jemalloc分析内存泄漏以及LD_PRELOAD
- 力扣26,删除重复项(JavaScript)
- linux 扩lv文件系统,Linux LVM系列(五)lv xfs文件系统在线扩容
- is和as在类型转换时的性能差异
- Tizen已经够烂了 但份额还是超过了黑莓
- C# .NET 爬虫抓取京东商城所有商品分类
- HTML和jquery实现播放功能
- Android 仿淘宝首页界面
- E-day0003:generate
- 阿里云注册域名,购买云服务器,备案,域名解析图文教程
- JavaScript的一些简单代码
- Fast Non-Bayesian Poisson Factorization for Implicit-Feedback Recommendations
- android 自动安装 解析包错误,安卓android手机安装包频繁提示解析错误解决方法...
- 数据结构——顺序表的实现
- 出现了,PPT 制作新方式
- https web service(转)
热门文章
- 拼多多报活动没有流量怎么办 拼多多活动流量少是什么原因
- 非冯诺依曼体系计算机,一种新非冯·诺依曼计算机体系结构.pdf
- 虚拟运行ur5时,出现的问题
- python 函数定义 编译_Cython编译的模块不允许访问函数定义的“module”而不是callab...
- 用于播放视频的Html5元素是,HTML5多媒体播放video元素与audio元素详解
- xPC信号采集和分析(2)
- 有道云笔记Android app离线缓存,有道云笔记文件保存在哪里在哪个路径下
- ICC2(一)import design —— NDM
- python调用微信客户端_用Python编写的简化版微信客户端
- autojs安卓10,11泡椒云提示无法读取imei码解决方案