JavaScript 项目——放大镜
本文将通过一个完整的项目实例演示,如何使用JavaScript实现放大镜效果。
大致目标效果如下:
项目思路
1、设置整体布局(html + css)。
设置三个盒子A、B、mouse。盒子A是目标图像(即需要放大的图像),盒子B是放大后的图像,而盒子mouse作为“放大镜”,设置在A中。
- 为了实现盒子A和B相邻,本项目使用定位布局,即设置
position:absolute后设置left和top的值。
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中,并规范投影的有效范围。
- 这里需要注意当盒子mouse要设置边距dis_x / dis_y,当盒子mouse与box的边距,即
- 实现盒子B投影放大盒子mouse的图像。这里是使用盒子A的图片作为盒子B的背景图,再通过
background-repeat、background-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返回的是字符串,除了数字外还带有单位:pxoffsetLeft只读,而style.Left可读写。(只读是获取值,可写是赋值)
总结
放大镜的应用实际十分常见 ,常用于购物商品详情界面中的商品图片放大,如下图
从需求出发,目标就会明确。明确需要达成什么功能,才能探索出更好更多的解决方法。本项目虽然只是实现放大镜这一简单的效果,但实际存在许多需要注意的小细节,如设置多少盒子、盒子mouse和盒子B如何对应并放大等。
无论是哪方面的学习,实践都是至关重要的。完成项目作为实践的一部分,一方面,能让我们认识运用新的知识,巩固并实践旧知识;另一方面,能对自己的学习程度产生更加明确认知,同时提升自身成就感。
这便是一个简单的项目,希望本文章对各位有所帮助。