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

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

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>

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

每天进步一点点~!

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/796212.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

麦克风设计指南

前言&#xff1a; 本指南基于乐鑫的 ESP32-S3 系列语音开发板。 整机 mic 要求 麦克风电器性能推荐 麦克类型&#xff1a;全向型 MEMS 麦克风 SMD-4P,2.8x1.9mm MEMS 麦克风 顶视图 MEMS 麦克风 底视图 灵敏度 1 Pa 声压下模拟麦灵敏度不低于 -38 dBV&#xff0c;数字麦灵…

CSS技巧专栏:一日一例 5-纯CSS实现背景色从四周向中心填充的按钮特效

特此说明 本专题专注于讲解如何使用CSS制作按钮特效。前置的准备工作和按钮的基本样式,都在本专栏第一篇文章中又详细说明。自本专栏第四篇文章起,本专栏都将直接跳过前面的内容,不再重复复制,需要了解按钮基础样式的同学,请移步:《CSS技巧 - 一日一例 (1):会讨好的热…

全渠道AI智能商品管理软件平台 助力零售品牌占领技术高地

关于7thonline第七在线 1999年创立于纽约&#xff0c;7thonline第七在线全渠道AI智能商品管理平台&#xff0c;以先进的数学算法模型、人工智能和机器学习技术为核心驱动力&#xff0c;融合了众多零售商品管理的卓越实践经验&#xff0c;精心打造出一套深度适配零售业务场景的自…

微信小程序---npm 支持

一、构建 npm 目前小程序已经支持使用 npm 安装第三方包&#xff0c;但是这些 npm 包在小程序中不能够直接使用&#xff0c;必须得使用小程序开发者工具进行构建后才可以使用。 为什么得使用小程序开发者工具需要构建呢❓ 因为 node_modules 目录下的包&#xff0c;不会参与…

PG大会周五于杭州举办;Pika发布4.0;阿里云MySQL上线Zero-ETL集成能力

重要更新 1. PostgreSQL中国技术大会举行12日&#xff08;周五&#xff09;于杭州举办&#xff0c;是PostgreSQL社区年度的大会&#xff0c;举办地点&#xff1a;杭州君尚云郦酒店&#xff08;杭州市上城区临丁路1188号&#xff09;&#xff0c;感兴趣的可以考虑现场参加 ( [1]…

git常用命令及git分支

git常用命令及git分支 git常用命令设置用户签名初始化本地库查看本地库状态将文件添加到暂存区提交到本地库查看历史记录版本穿梭 git分支什么是分支分支的好处分支的操作查看分支创建分支切换分支删除分支合并分支合并冲突 git常用命令 设置用户签名 //设置用户签名 git con…

Ubuntu 修改~/.bashrc终端选择是否使用annconda环境

首先需要明白的是anaconda虽然自带了python&#xff0c;但安装anaconda后并不会覆盖掉你原来的python&#xff08;pip也是一样的&#xff09;&#xff0c;但安装anaconda后它会把自己的bin目录&#xff08;里面有python、pip、conda等命令&#xff09;加到PATH上&#xff0c;而…

Math/System/Runtime/Object

1、Math &#xff08;1&#xff09;常用方法 类型方法名说明public static intabs (int a)返回整数的绝对值public static doublepow (double a,double b)计算a的b次幂的值public static int max (int a,int b) 获取两个int值中的较大值public static intmin (int a,int…

vue学习day07-scoped样式冲突、data是一个函数、props详解、组件通信、非父子通信-event bus 事件总线

19、scoped样式冲突 &#xff08;1&#xff09;默认情况&#xff1a;写在组件中的样式会全局生效&#xff0c;因此会很容易造成多个组件之间的样式冲突问题。 1&#xff09;全局样式&#xff1a;默认组件中的样式会作用到全局 比如&#xff1a; 当只有box1设置边框时&#…

Unity如何查找两个transform最近的公共parent

查找两个子对象最近的父对象 一、问题背景二、解决方案思路核心算法代码 三、总结 一、问题背景 最近看到个关于Unity的问题&#xff1a;在Hierarchy面板中的游戏对象&#xff0c;给定两个子物体transform对象&#xff0c;如何查找这两个transform最近的公共父级parent。感觉挺…

应用帕累托原则学习新的编程语言

在本文中&#xff0c;我将讨论如何应用帕累托原则快速学习一门新的编程语言&#xff0c;并在加深对编程语言的理解的同时开始解决实际问题。 什么是帕累托原则&#xff1f; 帕累托原则&#xff0c;又称 80/20 法则&#xff0c;指出对于许多结果而言&#xff0c;大约 80% 的后…

【简历】某电子科技大学:前端实习简历指导,面试通过率低

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份一本某电子科技大学的同学简历&#xff0c;投递的职位就是我们前端&#xff0c;但是因为学校是一本&#xff0c;我们说主要主体在…

【Lora模型推荐】Stable Diffusion创作具有玉石翡翠质感的图标设计

站长素材AI教程是站长之家旗下AI绘图教程平台 海量AI免费教程&#xff0c;每日更新干货内容 想要深入学习更多AI绘图教程&#xff0c;请访问站长素材AI教程网&#xff1a; AI教程_深度学习入门指南 - 站长素材 (chinaz.com) logo版权归各公司所有&#xff01;本笔记仅供AIGC…

Cesium 点选3DTiles泛光特效

Cesium 点选3DTiles泛光特效 原理&#xff1a;和上一篇点选Entity相同 直接上效果&#xff1a;

StarRocks部署高可用 FE 集群

一、准备工作 1.1 部署规划 这里我打算部署存算一体模式&#xff0c;三节点。即三个FE节点&#xff0c;三个BE节点。假设三台IP分别为&#xff1a;10.10.10.50、10.10.10.51、10.10.10.52 我将采用三台centos7.9进行部署&#xff0c;单台配置为128C 256G 3T。 1.2 服务器检查…

GESP CCF C++ 二级认证真题 2024年6月

第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级&#xff0c;那他可以选择的认证语言有几种&#xff1f;&#xff08; &#xff09; A. 1 B. 2 C. 3 D. 4 第 2 题 下面流程图在yr输入2024时&#xff0c;可以判定yr代表闰年&#xff0c;并输出 2月…

【LeetCode】2187. 完成旅途的最少时间

1. 题意 2. 分析 二分法有一个关键特征&#xff1a;如果答案answer满足题意&#xff0c;那么对于任何整数i&#xff0c;如果有i>answer&#xff0c;那么i也会是一个存在的解&#xff0c;只不过不是最优解。 本题想要找出一个达到 totalTrips 趟需要的最少时间成本t&#x…

分布式系统中雪花ID的使用及前后台精度解决

本文介绍了雪花ID的应用场景&#xff0c;以及针对雪花id生成精度过大导致数据缺失的解决方案。 一、概念 雪花 ID是一种分布式 ID 生成策略&#xff0c;保证全局唯一&#xff0c;位数组成中含有时间戳&#xff0c;相比UUID,故也能保证自增。 二、应用场景 分库、分表、分片、…

Python 爬虫:使用打码平台来识别各种验证码:

本课程使用的是 超级鹰 打码平台&#xff0c; 没有账户的请自行注册&#xff01; 超级鹰验证码识别-专业的验证码云端识别服务,让验证码识别更快速、更准确、更强大 使用打码平台来攻破验证码难题&#xff0c; 是很简单容易的&#xff0c; 但是要钱&#xff01; 案例代码及测…

Ubuntu安装MATLAB

一、准备工作 下载MATLAB安装文件&#xff1a; 访问MathWorks官方网站&#xff08;MathWorks官网&#xff09;&#xff0c;下载适用于Linux的MATLAB安装文件。这通常是一个.iso镜像文件或.zip压缩文件。请注意选择与Ubuntu版本相匹配的MATLAB版本。创建安装目录&#xff1a; 打…