JavaScript 项目——放大镜 | 青训营

147 阅读5分钟

JavaScript 项目——放大镜

本文将通过一个完整的项目实例演示,如何使用JavaScript实现放大镜效果。

大致目标效果如下:

m.bmp

项目思路

1、设置整体布局(html + css)

设置三个盒子A、B、mouse。盒子A是目标图像(即需要放大的图像),盒子B是放大后的图像,而盒子mouse作为“放大镜”,设置在A中。

  • 为了实现盒子A和B相邻,本项目使用定位布局,即设置position:absolute 后设置lefttop的值。

2、实现放大镜效果(js)

鼠标放在盒子A上时,盒子mouse会随着鼠标的移动而移动,同时盒子B中会出现盒子mouse所覆盖的图像的放大版。

  • 实现盒子mouse的鼠标跟随响应的效果。主要需要调用盒子A的onmousemove函数,获取到鼠标的位置(clientX,clientY),然后通过(clientX-boxA.offsetLeft,clientY-boxA.offsetTop)可获得鼠标在图像上的相对坐标(x,y),该坐标减去盒子mouse的宽度width、高度height的一半即可获得盒子mouse在A中的位置(这里的位置即盒子设置定位后的偏移量)。
    • 这里需要注意当盒子mouse要设置边距dis_x / dis_y,当盒子mouse与box的边距,即dis_x/dis_y = box的offsetWidth/offsetHeight - 鼠标在box的相对位置 时,要使其坐标固定。保证盒子mouse出现在盒子A中,并规范投影的有效范围
  • 实现盒子B投影放大盒子mouse的图像。这里是使用盒子A的图片作为盒子B的背景图,再通过 background-repeatbackground-size对原图像进行处理,实现放大的效果,再通过mouse的相对坐标去等比放大并改变盒子B背景图的坐标background-position,实现放大与移动的效果。
    • 其中background-position 的值等同于 盒子mouse移动的距离*(盒子B的大小除以mouse的大小)。 如本项目实例中,盒子B的与mouse的比值为3,而盒子mouse移动的距离 为 (80 - x) 或者 (60 - y) ,即B.style.backgroundPositionX = (80 - x) * 3 + 'px'B.style.backgroundPositionY = (60 - y) * 3 + 'px';

具体代码

<div id="box">
    <div id="mouse"></div>
    <img src="https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF" alt="">
</div>
<div id="mouse-box"></div>
* {
    margin: 0;
    padding: 0;
}

#box {
    position: absolute;
    left: 180px;
    top: 100px;
}

#box img {
    width: 400px;
    height: 300px;
    vertical-align: bottom;
}

#mouse-box {
    width: 480px;
    height: 360px;
    border: 1px solid black;
    position: absolute;
    left: 600px;
    top: 100px;
    background-image: url(https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF);
    background-repeat: no-repeat;
    background-size: 250% 250%
}

#mouse {
    /* mouse与img相对应,img的W和H是其的250%(三倍)*/
    width: 160px;
    height: 120px;
    position: absolute;

}
let box = document.getElementById("box");
let mouse = document.getElementById("mouse");
let mbox = document.getElementById("mouse-box");

box.onmousemove = function (client) {
    //鼠标在盒子box的相对位置
    let x = client.clientX - box.offsetLeft;
    let y = client.clientY - box.offsetTop;
    
    //盒子mouse在box中的坐标,即 鼠标在盒子box的相对位置 - 盒子mouse一半的width/height
    mouse.style.left = x - 80 + 'px';
    mouse.style.top = y - 60 + 'px';
    
    //盒子mouse与box的边距,即 box的offsetWidth/offsetHeight - 鼠标在box的相对位置
    //即,box.offsetWidth - (client.clientX - box.offsetLeft)
    let dis_x = box.offsetLeft + box.offsetWidth - client.clientX;
    let dis_y = box.offsetTop + box.offsetHeight - client.clientY;

    mbox.style.backgroundPositionX = (80 - x) * 3 + 'px';
    mbox.style.backgroundPositionY = (60 - y) * 3 + 'px';

    //表示盒子mouse超出box的可视区域,固定位置
    if (x - 80 < 0) {
        mouse.style.left = 0;
        mbox.style.backgroundPositionX = 0;
    }
    if (dis_x <= 80) {
        mouse.style.left = box.offsetWidth - 160 + 'px';
        mbox.style.backgroundPositionX = (160 - box.offsetWidth) * 3 + 'px';
    }
    if (y - 60 < 0) {
        mouse.style.top = 0;
        mbox.style.backgroundPositionY = 0;
    }
    if (dis_y < 60) {
        mouse.style.top = box.offsetHeight - 120 + 'px';
        mbox.style.backgroundPositionY = (120 - box.offsetHeight) * 3 + 'px';
    }

    //跟随鼠标移动显示
    mouse.style.backgroundColor = "rgba(255, 255, 255, 0.5)";

}

//鼠标移出后盒子mouse背景颜色消失
box.onmouseout = function () {
    mouse.style.backgroundColor="transparent"
}

补充知识

1、background-position

  • 在CSS中,使用background-position属性来定义背景图片的位置
  • background-position属性取值可同时设置水平方向和垂直方向的数值。例如,“background-position:12px 24px;”表示背景图片距离该元素(盒子box)左上角的水平方向距离为12px,垂直方向距离为24px。

2、x / y 坐标

  • clientX / clientY: 设置或获取鼠标指针位置相对于窗口客户区域的 x / y 坐标,其中客户区域不包括窗口自身的控件和滚动条,即浏览器可视区域 的x / y 元素。
  • offsetX / offsetY: 设置或获取鼠标指针位置相对于触发事件的(this)对象的 x / y 坐标,即绑定事件的元素的x / y 元素。
  • x / y: 设置或获取鼠标指针位置相对于父文档的 x / y 像素坐标。
  • 更多可以参考 《JavaScript 中一些概念理解 :clientX、clientY、offsetX、offsetY、screenX、screenY》

3、offsetLeft 与 style.left

  • offsetLeft 返回的是数字,而 style.left 返回的是字符串,除了数字外还带有单位:px
  • offsetLeft 只读,而 style.Left 可读写。(只读是获取值,可写是赋值)

总结

放大镜的应用实际十分常见 ,常用于购物商品详情界面中的商品图片放大,如下图

A.bmp

从需求出发,目标就会明确。明确需要达成什么功能,才能探索出更好更多的解决方法。本项目虽然只是实现放大镜这一简单的效果,但实际存在许多需要注意的小细节,如设置多少盒子、盒子mouse和盒子B如何对应并放大等。

无论是哪方面的学习,实践都是至关重要的。完成项目作为实践的一部分,一方面,能让我们认识运用新的知识,巩固并实践旧知识;另一方面,能对自己的学习程度产生更加明确认知,同时提升自身成就感。

这便是一个简单的项目,希望本文章对各位有所帮助。