js+css+html实现放大镜效果
Posted 橘猫吃不胖~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js+css+html实现放大镜效果相关的知识,希望对你有一定的参考价值。
js+css+html实现放大镜效果
1 案例描述
在很多网页中,我们都能看到一个类似于放大镜的效果,一般显示为有一个小的图,旁边有一个大图,当鼠标在小图上来回移动时,大图也会在相应的位置上来回移动,这样的效果一般在购物网站、制图网站上很常见,方便用户查看各种细节。
案例设计分析图:
效果图如下:
该效果主要是由2个div构成,一个放置小的图片,另一个放置大的,当鼠标在小效果图上来回移动时,会按照比例显示相应部分的大效果图。
2 编写HTML代码
在html部分中,要写入两个div,一个放置小图和遮罩层,另一个放置大图,代码如下:
<!-- 图片预览区域 -->
<div class="preview">
<!-- 小图 -->
<img src="./phone.png">
<!-- 遮罩层 -->
<div class="mask"></div>
</div>
<!-- 图片放大区域 -->
<div class="big_show">
<!-- 大图 -->
<img src="./bigphone.png">
</div>
3 编写CSS代码
首先为图片预览区域设置样式,为其设置宽和高,设置一个边框,方便对边界看得更加清楚,最后设置一个相对定位,为了让里面的遮罩层在设置绝对定位后位置相对于该区域定位,代码如下:
/* 为图片预览区域设置样式 */
.preview
width: 200px;
height: 200px;
border: 1px solid red;
position: relative;
从效果图可以看出,小图片太大,无法放入预览区中,因此为小图片设置一个高和宽,代码如下:
/* 为小图片设置样式 */
.preview img
width: 200px;
height: 200px;
让两个图片显示在一行上面,因此为<body></body>
设置弹性盒子样式,代码如下:
/* 让两个元素显示在一行 */
body
display: flex;
为图片显示区域设置样式,给其设置宽和高(要比大图片小)、边框、绝对定位(方便定位里面的img元素),为其设置盒子之外的部分不可见,最后将其隐藏,代码如下:
/* 图片显示区域 */
.big_show
width: 400px;
height: 400px;
border: 1px solid blue;
/* 盒子外面的部分不可见 */
overflow: hidden;
/* 绝对定位,距离页面左边300像素 */
position: absolute;
left: 300px;
/* 将其隐藏 */
display: none;
注:下面的图片是没有将其隐藏时的效果,也就是上面的代码中,不写入display: none;
时的效果。
为大图片设置样式,将大图片的宽和高设置好,方便javascript部分按照比例显示图片,然后为图片设置绝对定位,方便JavaScript部分对图片进行定位,代码如下:
/* 为大图片设置样式 */
.big_show img
position: absolute;
width: 800px;
height: 800px;
注:下面的图片是没有将其隐藏时的效果,也就是图片显示区域(big_show)的代码中,不写入display: none;
时的效果。
为遮罩层设置样式,给它设置宽高、绝对定位、背景颜色,以及先将其隐藏起来,代码如下:
/* 为遮罩层设置样式 */
.mask
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
/* rgba最后一个参数为透明度 */
background-color: rgba(255, 0, 0, 0.2);
/* 先将其隐藏起来 */
display: none;
注:下面的效果图为遮罩层样式不加display: none;
时的效果
到这里CSS样式就编写完成了,当前页面上的效果如下:
4 编写JavaScript代码
首先获取页面中需要使用到的元素,分别是:图片预览区、遮罩层、图片显示区以及大图片,代码如下:
//1、获取页面中的元素
let preview = document.querySelector(".preview");//获取预览区
let mask = document.querySelector(".mask");//获取遮罩层
let big_show = document.querySelector(".big_show");//获取显示区
let big_img = big_show.querySelector("img");//获取大图片
然后为预览区写入鼠标移动事件,当鼠标移动到预览区中时,显示遮罩层和图片显示区,当鼠标在预览区四处移动时,图片显示区域也会相应地显示出预览区遮罩层下面的部分,具体的解释在代码的注释中。
preview.onmousemove = function (e) //当鼠标在预览区移动时
mask.style.display = "block";//显示遮罩层
big_show.style.display = "block";//显示图片显示区
//鼠标在盒子中的横坐标=鼠标在页面中的横坐标-预览区在页面中的横坐标
//然后鼠标在盒子中的横坐标需要赋值给遮罩层在预览区中的横坐标,这时鼠标的位置正好对应遮罩层最左边
//为了让鼠标显示在遮罩层的中心,遮罩层在预览区中的横坐标需要再减去1/2遮罩层的宽度
//遮罩层在预览区的横坐标=鼠标在页面中的坐标-预览区对页面坐标的偏移量-
let x = e.pageX - preview.offsetLeft - mask.offsetWidth / 2;
//纵坐标与横坐标原理相同
let y = e.pageY - preview.offsetTop - mask.offsetHeight / 2;
//获取遮罩层最大的移动距离,最大移动距离不超过图片预览区域
//(这是一个固定的数字)水平最大移动距离=预览区的宽度-遮罩层的宽度
let x_max = preview.offsetWidth - mask.offsetWidth;
//(这时一个固定的数字)垂直最大移动距离=预览区的高度-遮罩层的高度
let y_max = preview.offsetHeight - mask.offsetHeight;
//根据最大移动距离限制遮罩层水平方向的移动范围
if (x < 0) //如果遮罩层在左侧要移出预览区
x = 0;//让遮罩层的横坐标为0,无法出去
else if (x > x_max) //如果遮罩层最右侧要移出预览区
x = x_max;//遮罩层的横坐标恒为最大移动距离
//根据最大移动距离限制遮罩层垂直方向的移动范围
if (y < 0) //如果遮罩层在上方要移出预览区
y = 0;//让遮罩层的纵坐标恒为0,无法移出
else if (y > y_max) //如果遮罩层在下方要移出预览区
y = y_max;//让遮罩层的纵坐标恒为最大值
//将计算好的遮罩层的坐标x和y赋值给遮罩层,让其跟随鼠标进行移动
mask.style.left = x + "px";
mask.style.top = y + "px";
//遮罩层的坐标比整个预览区的宽度,得到两个比值,该比值是移动距离的比值
let x_pro = x / preview.offsetWidth;
let y_pro = y / preview.offsetHeight;
//大图片的移动距离=移动距离的比值×大图片的宽高
let x_big = x_pro * big_img.offsetWidth;
let y_big = y_pro * big_img.offsetHeight;
//由于图片显示区域是固定不变的,是大图片的位置在改变
//当遮罩层在预览区向右移动一段距离,那么大图片在显示区必须向左移动一定比例的距离
//这样才能显示在显示区域(big_show)中,因此为大图片的移动距离赋值时
//需要将大图片的移动距离变成负值
big_img.style.left = -x_big + "px";
big_img.style.top = -y_big + "px";
在这部分中,首先获得遮罩层mask在图片预览区preview中的横坐标x和纵坐标y,这部分比较抽象难以理解,因此以获取遮罩层mask在图片预览区preview的横坐标x为例,设计出以下示意图:
为预览区写鼠标移出事件,当鼠标移出预览区时,遮罩层隐藏,显示区域隐藏,代码如下:
//给预览区注册鼠标移开事件
preview.onmouseleave = function ()
mask.style.display = "none";//遮罩层隐藏
big_show.style.display = "none";//图片显示区域隐藏
5 总代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
/* 让两个元素显示在一行 */
body
display: flex;
/* 为图片预览区域设置样式 */
.preview
width: 200px;
height: 200px;
border: 1px solid red;
position: relative;
/* 为小图片设置样式 */
.preview img
width: 200px;
height: 200px;
/* 图片显示区域 */
.big_show
width: 400px;
height: 400px;
border: 1px solid blue;
/* 盒子外面的部分不可见 */
overflow: hidden;
/* 绝对定位,距离页面左边300像素 */
position: absolute;
left: 300px;
/* 将其隐藏 */
display: none;
/* 为大图片设置样式 */
.big_show img
position: absolute;
width: 800px;
height: 800px;
/* 为遮罩层设置样式 */
.mask
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
/* rgba最后一个参数为透明度 */
background-color: rgba(255, 0, 0, 0.2);
/* 先将其隐藏起来 */
display: none;
</style>
<body>
<!-- 图片预览区域 -->
<div class="preview">
<!-- 小图 -->
<img src="./phone.png">
<!-- 遮罩层 -->
<div class="mask"></div>
</div>
<!-- 图片放大区域 -->
<div class="big_show">
<!-- 大图 -->
<img src="./bigphone.png">
</div>
<script>
//1、获取页面中的元素
let preview = document.querySelector(".preview");//获取预览区
let mask = document.querySelector(".mask");//获取遮罩层
let big_show = document.querySelector(".big_show");//获取显示区
let big_img = big_show.querySelector("img");//获取大图片
preview.onmousemove = function (e) //当鼠标在预览区移动时
mask.style.display = "block";//显示遮罩层
big_show.style.display = "block";//显示图片显示区
//鼠标在盒子中的横坐标=鼠标在页面中的横坐标-预览区在页面中的横坐标
//然后鼠标在盒子中的横坐标需要赋值给遮罩层在预览区中的横坐标,这时鼠标的位置正好对应遮罩层最左边
//为了让鼠标显示在遮罩层的中心,遮罩层在预览区中的横坐标需要再减去1/2遮罩层的宽度
//遮罩层在预览区的横坐标=鼠标在页面中的坐标-预览区对页面坐标的偏移量-
let x = e.pageX - preview.offsetLeft - mask.offsetWidth / 2;
//纵坐标与横坐标原理相同
let y = e.pageY - preview.offsetTop - mask.offsetHeight / 2;
//获取遮罩层最大的移动距离,最大移动距离不超过图片预览区域
//(这是一个固定的数字)水平最大移动距离=预览区的宽度-遮罩层的宽度
let x_max = preview.offsetWidth - mask.offsetWidth;
//(这时一个固定的数字)垂直最大移动距离=预览区的高度-遮罩层的高度
let y_max = preview.offsetHeight - mask.offsetHeight;
//根据最大移动距离限制遮罩层水平方向的移动范围
if (x < 0) //如果遮罩层在左侧要移出预览区
x = 0;//让遮罩层的横坐标为0,无法出去
else if (x > x_max) //如果遮罩层最右侧要移出预览区
x = x_max;//遮罩层的横坐标恒为最大移动距离
//根据最大移动距离限制遮罩层垂直方向的移动范围
if (y < 0) //如果遮罩层在上方要移出预览区
y = 0;//让遮罩层的纵坐标恒为0,无法移出
else if (y > y_max) //如果遮罩层在下方要移出预览区
y = y_max;//让遮罩层的纵坐标恒为最大值
//将计算好的遮罩层的坐标x和y赋值给遮罩层,让其跟随鼠标进行移动
mask.style.left = x + "px";
mask.style.top = y + "px";
//遮罩层的坐标比整个预览区的宽度,得到两个比值,该比值是移动距离的比值
let x_pro = x / preview.offsetWidth;
let y_pro = y / preview.offsetHeight;
//大图片的移动距离=移动距离的比值×大图片的宽高
let x_big = x_pro * big_img.offsetWidth;
let y_big = y_pro * big_img.offsetHeight;
//由于图片显示区域是固定不变的,是大图片的位置在改变
//当遮罩层在预览区向右移动一段距离,那么大图片在显示区必须向左移动一定比例的距离
//这样才能显示在显示区域(big_show)中,因此为大图片的移动距离赋值时
//需要将大图片的移动距离变成负值
big_img.style.left = -x_big + "px";
big_img.style.top = -y_big + "px";
//给预览区注册鼠标移开事件
preview.onmouseleave = function ()
mask.style.display = "none";//遮罩层隐藏
big_show.style.display = "none";//图片显示区域隐藏
</script>
</body>
</html>
以上是关于js+css+html实现放大镜效果的主要内容,如果未能解决你的问题,请参考以下文章