放大镜效果
在电商平台中,我们常常见到比如放大镜这样的效果,例如:
这样的效果是怎么实现的呢,他主要由三部分组成:
- 原始图片
- 放大图片
- 遮罩层
首先研究遮罩层,当鼠标移入图片中,遮罩层的位置也随之改变思路如下:
-
我们可以先设定好一个遮罩层,给其指定宽高(为图片大小的一半),并设置定位 position,后期我们需要改变这个left以及top实现遮罩层的位置改变。
<!-- 遮罩层 --> <div class="mask"></div> <!--这里使用的为 less--> <style lang="less"> .mask { // 设置宽高为大盒子的一般 width: 50%; height: 50%; // 设置背景颜色 background-color: rgba(0, 255, 0, 0.3); // 设置定位 position: absolute; // 设置初始位置 left: 0; top: 0; // 默认不显示,当鼠标移入时显示 display: none; } // 当鼠标移入时显示 .event:hover ~ .mask, .event:hover ~ .big { display: block; } </style>
-
当鼠标移入图片时会触发鼠标移动(mousemove)事件,并会传入一个 event 事件对象,其中包含的 offsetX,offsetY(相对于这个图片边界的X,Y值)就是我们需要的内容,使用 event.offsetWidth(offsetHeight) 可以获取当前元素的宽高。
-
获取mask节点,当鼠标移动时,改变 mask 的 left 和 top,注意:这里的 left 以及 top,应当是
鼠标当前位置相对于图片边界坐标 - mask元素的宽高的一半,也就是:
document.querySelector(".mask").addEventListener('mousemove',(event)=>{ let left = event.offsetX - mask.offsetWidth / 2; let top = event.offsetY - mask.offsetHeight / 2; mask.style.left = left + 'px'; mask.style.top = top + 'px'; })
基础功能实现,但是现在遮罩层可以超出边界,如下图:
-
所以我们需要添加一些判断。如果两项相减小于0,就让这个宽高等于0;如果两项相减大于 mask 的宽高,就让这个值等于 mask 的宽高;
document.querySelector(".mask").addEventListener('mousemove',(event)=>{ let mask = document.querySelector(".mask"); let left = event.offsetX - mask.offsetWidth / 2; let top = event.offsetY - mask.offsetHeight / 2; // 约束范围 if (left <= 0) left = 0; if (left >= mask.offsetWidth) left = mask.offsetWidth; if (top <= 0) top = 0; if (top >= mask.offsetHeight) top = mask.offsetHeight; mask.style.left = left + 'px'; mask.style.top = top + 'px'; })
实现功能如下:
实现完遮罩层的功能之后,我们要试着实现放大镜的功能了。
-
定义一个放大镜的盒子,命名为 big,放大镜的原理就是,将区域图片的宽高都放大一倍,就像是放大了一样。
<div class="big"> <img src="imgUrl" /> </div> <style lang="less"> .big { // 定义盒子的宽高,这里的宽高要和原始图片宽高一致 width: 100%; height: 100%; // 开启定位,将放大镜与原始图片齐平 position: absolute; top: 0; left: 100%; border: 1px solid #aaa; // 隐藏超出部分 overflow: hidden; z-index: 1000; display: none; background: white; // 设置放大镜中的图片 img { // 设置图片宽度为.big的二倍 width: 200%; max-width: 200%; // 设置图片高度为.big的二倍 height: 200%; // 设置定位,通过更改定位left以及top进行放大的同步展示 position: absolute; left: 0; top: 0; } } </style>
-
当鼠标在原始图片上移动时,改变.big中图片的 left 以及 top。代码与上方一致,这里一定要用-2,用2则方向相反。
big.style.top = -2 * top + 'px'; big.style.left = -2 * left + 'px';
-
至此,功能完成。
全部代码:
<div class="spec-preview">
<img src="imgUrl" />
<div class="event"></div>
<div class="big">
<img ref="big" src="imgUrl" />
</div>
<!-- 遮罩层 -->
<div class="mask"></div>
</div>
</template>
<script>
document.querySelector(".mask").addEventListener('mousemove',(event)=>{
let mask = document.querySelector(".mask");
let big = document.querySelector(".big img");
let left = event.offsetX - mask.offsetWidth / 2;
let top = event.offsetY - mask.offsetHeight / 2;
// 约束范围
if (left <= 0) left = 0;
if (left >= mask.offsetWidth) left = mask.offsetWidth;
if (top <= 0) top = 0;
if (top >= mask.offsetHeight) top = mask.offsetHeight;
mask.style.left = left + 'px';
mask.style.top = top + 'px';
big.style.top = -2 * top + 'px';
big.style.left = -2 * left + 'px';
};
</script>
<style lang="less">
.event {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 998;
}
.mask {
width: 50%;
height: 50%;
background-color: rgba(0, 255, 0, 0.3);
position: absolute;
left: 0;
top: 0;
display: none;
}
.big {
width: 100%;
height: 100%;
position: absolute;
top: -1px;
left: 100%;
border: 1px solid #aaa;
overflow: hidden;
z-index: 1000;
display: none;
background: white;
img {
width: 200%;
max-width: 200%;
height: 200%;
position: absolute;
left: 0;
top: 0;
}
}
.event:hover ~ .mask,
.event:hover ~ .big {
display: block;
}
}
</style>