js放大效果(一)
实现效果:
很简易的,只是完成了一个简单的放大功能。
布局方面左右两个容器分别放了两个图片,右边是正常尺寸,左边是缩小版的。
遮罩层和右边的图片用了绝对定位,用left,top值来控制显示的区域
html代码:
<div class="wrap">
<div class="left">
<img src="default.jpeg" id="leftImg">
<div class="mask"></div>
</div>
<div class="right">
<img src="default.jpeg" id="rightImg">
</div>
</div>
body {
margin: 0;
height: 100vh;
background-color: rgb(67, 62, 73);
}
.wrap {
display: flex;
justify-content: space-around;
margin: 50px auto;
}
.left {
width: 400px;
height: 400px;
border: 1px solid rgb(100, 253, 240);
position: relative;
overflow: hidden;
}
.left img {
height: 400px;
}
.right {
width: 400px;
height: 400px;
border: 1px solid rgb(100, 253, 240);
border-radius: 50%;
position: relative;
overflow: hidden;
}
.mask {
background: rgba(253, 191, 191, 0.459);
position: absolute;
left:0;
top: 0;
border-radius: 50%;
display: none;
}
.right img {
position: absolute;
left: 0;
top: 0;
}
实现效果思路:
1.由于大图跟小图的大小是一定的,所以能够求出来一个比值。右边容器相当于大图的可视窗口,大小也是固定的,左边与之相对应的就是遮罩层。有了比值和右边容器的大小就能确定遮罩层的大小了
2.如何让遮罩层跟随鼠标指针位置移动?这里用到了event对象。在某点打印出event对象会得到MouseEvent {isTrusted: true, screenX: 384, screenY: 518, clientX: 375, clientY: 416, …}
如图所示:
我发现,刚好event.offsetX的值刚好就是我想要的,所以就用offestX和offsetY来计算。但是效果会出现遮罩层和图片不断闪烁的问题,后来才发现
event.clientX、event.clientY
鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性
event.pageX、event.pageY
类似于event.clientX、event.clientY,但它们使用的是文档坐标而非窗口坐标。这2个属性不是标准属性,但得到了广泛支持。IE事件中没有这2个属性。
event.offsetX、event.offsetY
鼠标相对于事件源元素(srcElement)的X,Y坐标,只有IE事件有这2个属性,标准事件没有对应的属性。
event.screenX、event.screenY
鼠标相对于用户显示器屏幕左上角的X,Y坐标。标准事件和IE事件都定义了这2个属性
原来是IE的属性!那就手动算一下吧,也很简单,x轴方向用event.clientX减去元素左边到浏览器的距离也就是左边容器的offsetLeft,y轴方向用event.clientY减去元素上边到浏览器的距离也就是左边容器的offsetTop
3.为了让鼠标指针指在遮罩层的中心位置,所以还要拿到遮罩层的半径做个减法
js完整代码:
(function () {
let leftImg = document.querySelector('#leftImg');//左边图片
let rightImg = document.querySelector('#rightImg');//右边图片
let mask = document.querySelector('.mask');//左边遮罩层
let right = document.querySelector('.right');//右边容器
let left = document.querySelector('.left');//左边容器
let leftWidth = getComputedStyle(left).width;
let leftHeight = getComputedStyle(left).height;
let ratio = getComputedStyle(rightImg).width/getComputedStyle(leftImg).width;//左右比值
let rightWidth = getComputedStyle(right).width;//右边容器宽度。计算用
let rightHeight = getComputedStyle(right).height;//右边容器高度。计算用
let r = rightWidth/ratio/2;//遮罩层半径。调节位移值用
let x = 0;//x轴方向位移初始值
let y = 0;//y轴方向位移初始值
mask.style.width = rightWidth/ratio + 'px';//设置遮罩层的宽
mask.style.height = rightHeight/ratio + 'px';//设置遮罩层的高
left.onmouseover = function(){ //鼠标移入左侧显示遮罩层
mask.style.display = 'block';
}
left.onmousemove = function(e){ //鼠标移动改变遮罩层位移值,右边图片位移值
x = e.clientX-left.offsetLeft;
y = e.clientY-left.offsetTop;
//过界处理
if(x < r){
x = r;
} else if(x>leftWidth-r){
x = leftWidth-r
}
if(y < r){
y = r
} else if(y>leftHeight-r){
y = leftHeight-r
}
mask.style.left = x - r + 'px';
mask.style.top = y - r + 'px';
rightImg.style.left = -(x-r)*ratio+ 'px';
rightImg.style.top = -(y-r)*ratio+ 'px';
}
left.onmouseout = function(){ //鼠标移出左侧隐藏遮罩层
mask.style.display = 'none';
}
})();
如果想要完全像商城那样,鼠标移入右侧显示,鼠标移出右侧隐藏就改动下布局就好了。