js放大效果(一)

实现效果:
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, …}
如图所示:js放大效果(一)

我发现,刚好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';
    }
})();

如果想要完全像商城那样,鼠标移入右侧显示,鼠标移出右侧隐藏就改动下布局就好了。