首页 > 编程语言 >Web开发 —— 放大镜效果(HTML、CSS、JavaScript)

Web开发 —— 放大镜效果(HTML、CSS、JavaScript)

时间:2024-07-12 22:26:21浏览次数:11  
标签:Web 鼠标 img 遮罩 大图 JavaScript mask HTML 移动

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

1、HTML 页面结构

2、CSS 元素样式

3、JavaScript动态控制

(1)获取元素

(2)控制大图和遮罩层的显隐性

(3)遮罩层跟随鼠标移动

(4)控制遮罩层移动范围

(5)显示放大图


一、需求描述

前端实现放大镜效果;

  • 鼠标移入图片区域,显示遮罩层;
  • 鼠标移出图片区域,隐藏遮罩层;
  • 鼠标移动,遮罩层跟随鼠标移动;
  • 遮罩层不能超出图片所在区域;
  • 遮罩层覆盖的图片区域按照指定比例放大显示;
  • 遮罩层移动,放大图跟随移动;

二、实现效果

初始效果

放大效果

三、完整代码

【test.html】

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>放大镜效果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .one-img-box,
        .big-img-box {
            position: relative;
            width: 300px;
            height: 300px;
            box-shadow: 0 0 6px 1px #cacaca;
            border-radius: 10px;
            overflow: hidden;
        }

        .one-img-box {
            display: inline-block;
            top: 60px;
            left: 60px;
            cursor: move;
        }

        .one-img-box>img {
            width: 100%;
            height: 100%;
        }

        .big-img-box {
            /* display: inline-block; */
            display: none;
            top: 60px;
            left: 100px;
        }

        .big-img-box>img {
            width: 300%;
            height: 300%;
        }

        .big-img {
            position: absolute;
            left: 0;
            top: 0;
        }

        .mask {
            /* display: inline-block; */
            display: none;
            position: absolute;
            left: 0;
            top: 0;
            width: 100px;
            height: 100px;
            background-color: yellowgreen;
            opacity: .4;
        }
    </style>
</head>

<body>
    <div class="one-img-box">
        <img src="D:\test\girl.png" alt="">
        <div class="mask"></div>
    </div>
    <div class="big-img-box"><img class="big-img" src="D:\test\girl.png" alt=""></div>
</body>
<script>
    // 1、获取元素
    // 获取原图的盒子
    var oneImgBox = document.querySelector('.one-img-box');
    // 获取遮罩层
    var mask = document.querySelector('.mask');
    // 获取大图盒子
    var bigImgBox = document.querySelector('.big-img-box');
    // 获取大图
    var bigImg = document.querySelector('.big-img');


    // 2、控制显示与隐藏
    // 2.1 鼠标经过 oneImgBox,显示 mask遮挡层 和 bigImgBox大盒子;
    oneImgBox.addEventListener('mouseover', function () {
        mask.style.display = 'inline-block';
        bigImgBox.style.display = 'inline-block';
    })
    // 2.2 鼠标移出 oneImgBox,隐藏 mask遮挡层 和 bigImgBox大盒子;
    oneImgBox.addEventListener('mouseout', function () {
        mask.style.display = 'none';
        bigImgBox.style.display = 'none';
    })

    // 3、遮罩层跟随鼠标移动
    oneImgBox.addEventListener('mousemove', function (e) {
        // 3.1 计算鼠标在盒子内的坐标
        var mouseX = e.pageX - oneImgBox.offsetLeft;
        var mouseY = e.pageY - oneImgBox.offsetTop;

        // 3.2 计算遮罩层的移动位置
        // 移动位置 = 鼠标的移动距离 - 遮罩层自己宽度\高度的一半(鼠标会在遮罩层中心位置,否则在左上角)
        var maskX = mouseX - mask.offsetWidth / 2;
        var maskY = mouseY - mask.offsetWidth / 2;

        // 计算结果赋给遮罩层;
        // mask.style.left = maskX + 'px';
        // mask.style.top = maskY + 'px';

        // 4、控制遮罩层的移动范围
        // 4.1 计算遮罩层最大移动宽度\高度 = 原图盒子的宽度\高度 - 遮罩层的宽度\高度
        var maskMaxX = oneImgBox.offsetWidth - mask.offsetWidth;
        var maskMaxY = oneImgBox.offsetHeight - mask.offsetHeight

        // 如果移动距离 大于 最大移动距离,则取最大的移动距离
        // 如果移动距离 小于 0,则取0;
        maskX = maskX > maskMaxX ? maskMaxX : maskX < 0 ? 0 : maskX;
        maskY = maskY > maskMaxY ? maskMaxY : maskY < 0 ? 0 : maskY;

        // 计算结果赋给遮罩层
        mask.style.left = maskX + 'px';
        mask.style.top = maskY + 'px';

        // 5、按比例显示大图
        // 5.1 放大比例 = 原图的宽度 / 大图的宽度 = 1 / 3
        var rate = oneImgBox.offsetLeft / bigImg.offsetWidth;

        // 5.2 大图的移动距离 = 遮罩层的移动距离 * 放大比例 (注意大图的移动方向与遮罩层相反)
        bigImg.style.left = - maskX * 3 + 'px';
        bigImg.style.top = - maskY * 3 + 'px';
    })
</script>

</html>

四、实现过程

1、HTML 页面结构

一个原图片的盒子【div元素】,里面放原图【img元素】和遮罩层【div元素】

一个放大后的图片盒子【div元素】,里面放大图【img元素】;

<body>
    <div class="one-img-box">
        <img src="D:\test\girl.png" alt="">
        <div class="mask"></div>
    </div>
    <div class="big-img-box"><img class="big-img" src="D:\test\girl.png" alt=""></div>
</body>

2、CSS 元素样式

(1)两个盒子及图片样式

这里设置原图的宽高均为300px;大图的宽高是原图的三倍;

【 cursor: move; 】使得鼠标在移入图片变成“移动”样式;

【overflow: hidden;】使得图片超出盒子部分被隐藏(大图);

注意,大图盒子最初的的display的值应设为none,显隐性由鼠标移入或移出图片决定;

.one-img-box,
.big-img-box {
    position: relative;
    width: 300px;
    height: 300px;
    box-shadow: 0 0 6px 1px #cacaca;
    border-radius: 10px;
    overflow: hidden;
}

.one-img-box {
    display: inline-block;
    top: 60px;
    left: 60px;
    cursor: move;
}

.one-img-box>img {
    width: 100%;
    height: 100%;
}

.big-img-box {
    display: inline-block;
    top: 60px;
    left: 100px;
}

.big-img-box>img {
    width: 300%;
    height: 300%;
}

.big-img {
    position: absolute;
    left: 0;
    top: 0;
}

(2)遮罩层样式

遮罩层使用绝对定位,根据鼠标的移动位置,再更改其left和top值,使遮罩层跟随鼠标移动;

注意:遮罩层最初不显示,display的值也应设为none;

.mask {
    display: inline-block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100px;
    height: 100px;
    background-color: yellowgreen;
    opacity: .4;
}

注意:

原图的宽高均为300px;遮罩层的宽高均为100px;遮罩层与原图的宽高比例都是1 :3;

放大图的盒子和大图的比例需要一致(1 :3),所以大图的宽高应该均为900px;

这里的比例如果不一致,则会出现,遮罩层覆盖的内容,在大图中没有完全显示,或显示不全;当然可以自定义这个比例;

3、JavaScript动态控制

(1)获取页面元素

将页面中需要操作的元素都进行获取;

这里使用的是querySelector()方法来获取元素,是JavaScript中获取dom元素的方式之一;

<script>
    // 1、获取元素
    // 获取原图的盒子
    var oneImgBox = document.querySelector('.one-img-box');
    // 获取遮罩层
    var mask = document.querySelector('.mask');
    // 获取大图盒子
    var bigImgBox = document.querySelector('.big-img-box');
    // 获取大图
    var bigImg = document.querySelector('.big-img');
    ......
</script>

(2)控制大图和遮罩层的显隐性

先设置大图盒子和遮罩层的display 为 none;

......
.big-img-box {
    /* display: inline-block; */
    display: none;
    ......
}
.mask {
    /* display: inline-block; */
    display: none;
    ......
}
......

分析需求可知:

  • 遮罩层和大图盒子的显示与隐藏是同时的,大图盒子显示则遮罩层显示,大图盒子隐藏则遮罩层隐藏;
  • 当鼠标经过原图时,两者显示,需要给这个原图盒子注册鼠标经过事件,完成相应功能;
  • 当鼠标移出原图时,两者隐藏,也需要给这个原图盒子注册鼠标移出事件,完成相应功能;
<script>
    ......
    // 2、控制显示与隐藏
    // 2.1 鼠标经过 oneImgBox,显示 mask遮挡层 和 bigImgBox大盒子;
    oneImgBox.addEventListener('mouseover', function () {
        mask.style.display = 'inline-block';
        bigImgBox.style.display = 'inline-block';
    })
    // 2.2 鼠标移出 oneImgBox,隐藏 mask遮挡层 和 bigImgBox大盒子;
    oneImgBox.addEventListener('mouseout', function () {
        mask.style.display = 'none';
        bigImgBox.style.display = 'none';
    })
    ......
</script>

(3)遮罩层跟随鼠标移动

分析需求可知:

  • 遮罩层在盒子内的移动距离,实际就是鼠标的移动距离(遮罩层跟着鼠标移动),但注意这个是遮罩层左上角的位置;
  • 遮罩层中心的移动距离,要在鼠标移动距离的基础上,减去遮罩层自身的宽度或高度;
  • 鼠标的移动距离mouseX\mouseY为,鼠标在页面中的X坐标\Y坐标 - 图片盒子的左\上边距;
  • 注意,这里鼠标一开始进入图片盒子就开始计算;
<script>
    ......
    // 3、遮罩层跟随鼠标移动
    oneImgBox.addEventListener('mousemove', function (e) {
        // 3.1 计算鼠标在盒子内的坐标
        var mouseX = e.pageX - oneImgBox.offsetLeft;
        var mouseY = e.pageY - oneImgBox.offsetTop;

        // 3.2 计算遮罩层的移动位置
        // 移动位置 = 鼠标的移动距离 - 遮罩层自己宽度\高度的一半(鼠标会在遮罩层中心位置,否则在左上角)
        var maskX = mouseX - mask.offsetWidth / 2;
        var maskY = mouseY - mask.offsetWidth / 2;

        // 计算结果赋给遮罩层;
        mask.style.left = maskX + 'px';
        mask.style.top = maskY + 'px';
        ......
    })
</script>

注意:

这里存在一个问题,就是当鼠标靠近图片边缘的时候,遮罩层会继续移动,被裁剪;

应该加以判断,控制遮罩层的移动范围,使得遮罩层不会被移出去;

(4)控制遮罩层移动范围

分析需求可知:

  • 遮罩层的移动距离不能小于 0,也不能超过它的最大移动距离;
  • 遮罩层最大移动宽度\高度 = 原图盒子的宽度\高度 - 遮罩层的宽度\高度;
  • 如果移动距离 大于 最大移动距离,则取最大的移动距离;
  • 如果移动距离 小于 0,则取0;
<script>
    ......
    // 3、遮罩层跟随鼠标移动
    oneImgBox.addEventListener('mousemove', function (e) {
        ......
        // 4、控制遮罩层的移动范围
        // 4.1 计算遮罩层最大移动宽度\高度 = 原图盒子的宽度\高度 - 遮罩层的宽度\高度
        var maskMaxX = oneImgBox.offsetWidth - mask.offsetWidth;
        var maskMaxY = oneImgBox.offsetHeight - mask.offsetHeight

        // 如果移动距离 大于 最大移动距离,则取最大的移动距离
        // 如果移动距离 小于 0,则取0;
        maskX = maskX > maskMaxX ? maskMaxX : maskX < 0 ? 0 : maskX;
        maskY = maskY > maskMaxY ? maskMaxY : maskY < 0 ? 0 : maskY;

        // 计算结果赋给遮罩层
        mask.style.left = maskX + 'px';
        mask.style.top = maskY + 'px';
        ......
    })
</script>

(5)按比例移动放大图

分析需求可知:

  • 放大比例 = 原图的宽度 / 大图的宽度;
  • 大图的移动距离 = 遮罩层的移动距离 * 放大比例;
  • 注意:大图的移动方向与遮罩层相反;
<script>
    ......
    // 3、遮罩层跟随鼠标移动
    oneImgBox.addEventListener('mousemove', function (e) {
        ......
        // 5、按比例显示大图
        // 5.1 放大比例 = 原图的宽度 / 大图的宽度 = 1 / 3
        var rate = oneImgBox.offsetLeft / bigImg.offsetWidth;

        // 5.2 大图的移动距离 = 遮罩层的移动距离 * 放大比例 (注意大图的移动方向与遮罩层相反)
        bigImg.style.left = - maskX * 3 + 'px';
        bigImg.style.top = - maskY * 3 + 'px';
    })
</script>

=========================================================================

每天进步一点点~!

记录一下这个实用的前端"小轮子"~! 

标签:Web,鼠标,img,遮罩,大图,JavaScript,mask,HTML,移动
From: https://blog.csdn.net/m0_65029152/article/details/140320108

相关文章

  • 【云服务器介绍】选择指南 腾讯云 阿里云全配置对比 搭建web 个人开发 app 游戏服务器
    ​省流目录:适用于博客建站(2-4G)、个人开发/小型游戏[传奇/我的世界/饥荒](4-8G)、数据分析/大型游戏[幻兽帕鲁/雾锁王国]服务器(16-64G)1.京东云-专属活动 官方采购季专属活动地址:京东云-618采购季服务器活动专区https://3.cn/20-J4jjX京东云又双叒降价了!活动页大改,增加两个大......
  • 科研训练课程1--LetPub与Web of Science(查询工具)
    科研训练课程1–LetPub与WebofScience(查询工具)文章目录前言课程任务(可跳过)了解1.LetPub2.WebofScience总结前言本系列笔记为记录大二暑期学校课程——科研训练与写作,记录一下每天了解了什么吧(苦逼又无聊的学习生涯又开始了。才刚结束啊)在’亲爱‘的大......
  • web渗透——信息收集
    切记:未经授权,禁止对任何网站进行渗透测试摘要whois查询端口扫描CMS识别DNS记录备案信息旁站查询子域名查询CND绕过WAF识别资产收集反查域名证书查询空间测绘威胁情报源码泄露whois查询常用网址:爱站:https://www.aizhan.com/站长之家:https://whois.chinaz.com......
  • HTML(3)
    10.列表定义:布局内容排列整齐的区域。分类:无序列表,有序列表,定义列表1.无序列表:ul是无序列表,li是列表条目,ul嵌套li<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,......
  • 【JavaWeb程序设计】EL和JSTL
    目录一、在数据库Book中建立表Tbook,包含图书ID,图书名称,图书价格。实现模糊查询图书,如果图书的价格在50元以上,则以黄色字体显示书名。相应的模糊查询放在Servlet中实现,在图书的显示代码中使用JSTL。1.运行截图2.建表(tbook)并插入数据3.search.jsp(1)查找表单(2)CSS4.mybat......
  • JavaScript调试技巧总结
    debug javascript最全面的JavaScript调试技巧总结本文将一一讲解各种前端JS调试技巧,也许你已经熟练掌握,那让我们一起来温习,也许有你没见过的方法,不妨一起来学习,也许你尚不知如何调试,赶紧趁此机会填补空白。Thisentrywaspostedin Review andtagged debug, javasc......
  • 动态添加HTML时onclick函数参数传递
    onclick函数动态传参1.参数为数值类型时:var tmp=123;var strHTML="<divonclick=func(" +tmp+")>点击弹出数据及其类型</div>";info.append(strHTML); function func(tmp){    alert(typeof tmp+"" +tmp);}string12......
  • 同时用到,网页,java程序,数据库的web小应用
    具体实现功能:通过网页传输添加用户的请求,需要通过JDBC来向MySql添加一个用户数据第一步,部署所有需要用到的工具IDEA(2021.1),Tomcat(9),谷歌浏览器,MySql,jdk(17)第二步,创建java项目,提前部署数据库在idea中新建一个空的java项目:我创建的数据库名为learnbase,执行use......
  • 通过 tomcat 让手机访问到电脑写的 html 网页
    之前实现的html小项目只能在自己的电脑上展示,如果要在其他电脑或者在手机上就看不到网页了想要在手机上访问自己写的网页,我们可以借助tomcat首先我们可以从官网下载tomcat官网链接:apache官网我们拉到最底部,找到apache公司下的tomcat下载zip版本即可(只有十几MB,解......
  • 深入理解 JavaScript 闭包:前端开发中的重要概念
    闭包是JavaScript中一个非常重要的概念,对于理解和编写高效、灵活的代码至关重要。尽管它看似复杂,但一旦掌握了闭包,你将能够更好地理解JavaScript的函数作用域和变量生命周期。本文将深入探讨JavaScript闭包,帮助你在前端开发中更好地运用这一强大工具。什么是闭包?闭包是指......