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

news/2024/9/11 3:55:39/ 标签: html, css, JavaScript, 放大镜效果
htmledit_views">

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

1、HTML 页面结构

2、CSS 元素样式

JavaScript%E5%8A%A8%E6%80%81%E6%8E%A7%E5%88%B6-toc" style="margin-left:40px;">3、JavaScript动态控制

(1)获取元素

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

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

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

(5)显示放大图


一、需求描述

前端实现放大镜效果

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

二、实现效果

初始效果

放大效果

三、完整代码

【test.html

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 / 3var 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元素】;

html"><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,显隐性由鼠标移入或移出图片决定;

css">.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;

css">.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;

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

JavaScript%E5%8A%A8%E6%80%81%E6%8E%A7%E5%88%B6">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;

css">......
.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 / 3var rate = oneImgBox.offsetLeft / bigImg.offsetWidth;// 5.2 大图的移动距离 = 遮罩层的移动距离 * 放大比例 (注意大图的移动方向与遮罩层相反)bigImg.style.left = - maskX * 3 + 'px';bigImg.style.top = - maskY * 3 + 'px';})
</script>

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

每天进步一点点~!

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


http://www.ppmy.cn/news/1474711.html

相关文章

C# Winform 系统方案目录的管理开发

在做一个中等复杂程度项目时&#xff0c;我们通常有系统全局配置&#xff0c;还要有对应的方案目录的管理和更新。 比如我们有如下需求&#xff1a;开发一个方案管理&#xff0c;可以新建、打开和保存方案&#xff0c;同时还需要保存方案中的各种文件。我设计的采用目录管理和…

【YashanDB知识库】表收集统计信息默认阈值引起SQL执行效率差

【问题分类】性能优化 【关键字】统计信息&#xff0c;阈值&#xff0c;执行计划 【问题描述】表新增87w数据自动收集统计信息任务没有启动导致SQL执行计划变差 【问题原因分析】 CUS_REGISTER_READ 数据总量是18374074&#xff0c;插入81万&#xff0c;统计信息失效的阈值是…

流程图怎么做?有三种制作方法

流程图怎么做&#xff1f;在日常生活和工作中&#xff0c;流程图作为一种直观展示步骤、流程或决策路径的工具&#xff0c;扮演着不可或缺的角色。它不仅能够帮助我们理清思路、规划任务&#xff0c;还能促进团队协作与沟通。那么&#xff0c;如何高效地绘制流程图呢&#xff1…

Objective-C 自定义渐变色Slider

文章目录 一、前情概要二、具体实现 一、前情概要 系统提供UISlider&#xff0c;但在开发过程中经常需要自定义&#xff0c;本次需求内容是实现一个拥有渐变色的滑动条&#xff0c;且渐变色随着手指touch的位置不同改变区域&#xff0c;类似如下 可以使用CAGradientLayer实现渐…

Web开发:一个可拖拽的模态框(HTML、CSS、JavaScript)

目录 一、需求描述 二、实现效果 三、完整代码 四、实现过程 1、HTML 页面结构 2、CSS 元素样式 3、JavaScript动态控制 &#xff08;1&#xff09;获取元素 &#xff08;2&#xff09;显示\隐藏遮罩层与模态框 &#xff08;3&#xff09;实现模态框拖动效果 一、需求…

VMware安装Ubuntu以及利用vscode远程Ubuntu

一、VMware安装Ubuntu &#xff08;1&#xff09;VMware安装Ubuntu主要参考此文VMware虚拟机安装Ubuntu22.04图文教程&#xff08;超详细&#xff01;&#xff01;&#xff01;&#xff09;。 &#xff08;2&#xff09;VMware密钥参考此文24年VMware 17密钥(附下载链接&#…

《C++并发编程实战》笔记(一、二)

一、简介 抽象损失&#xff1a;对于实现某个功能时&#xff0c;可以使用高级工具&#xff0c;也可以直接使用底层工具。这两种方式运行的开销差异称为抽象损失。 二、线程管控 2.1 线程的基本控制 1. 创建线程 线程相关的管理函数和类在头文件&#xff1a; #include <…

Memcached高并发挑战:性能优化与实战策略

标题&#xff1a;Memcached高并发挑战&#xff1a;性能优化与实战策略 在高并发的网络应用场景中&#xff0c;Memcached作为一项高效的分布式内存缓存系统&#xff0c;其性能表现尤为关键。然而&#xff0c;面对海量的请求和数据&#xff0c;Memcached的性能如何&#xff0c;以…

Spring Boot 框架知识汇总

1、什么是SpringBoot&#xff1f; 通过Spring Boot&#xff0c;可以轻松地创建独立的&#xff0c;基于生产级别的Spring的应用程序&#xff0c;您可以“运行"它们。大多数Spring Boot应用程序需要最少的Spring配置&#xff0c;集成了大量常用的第三方库配置&#xff0c;使…

【力扣C语言】每日一题—第50题,Pow(x,n)

题目 实现x的n次幂。 问题分析&#xff1a; 当n大于零&#xff0c;等于零&#xff0c;小于零时都需要分析 思路&#xff1a;反复迭代&#xff0c;利用通过二进制位进行缩短计算时间。 力扣通过代码&#xff1a; ​ double myPow(double x, int n) {long nnn;double ret1;…

R语言学习笔记3-基本类型篇

R语言学习笔记-基本类型篇 基本类型介绍数值型&#xff08;Numeric&#xff09;整数型&#xff08;Integer&#xff09;浮点数型&#xff08;Double&#xff09;数值运算数值型 NA&#xff08;缺失值&#xff09; 字符型&#xff08;Character&#xff09;字符型的特点和用途基…

C++进阶:继承和多态

文章目录 ❤️继承&#x1fa77;继承与友元&#x1f9e1;继承和静态成员&#x1f49b;菱形继承及菱形虚拟继承&#x1f49a;继承和组合 ❤️多态&#x1fa77;什么是多态&#xff1f;&#x1f9e1;多态的定义以及实现&#x1f49b;虚函数&#x1f49a;虚函数的重写&#x1f499…

鸿蒙开发工程师面试题-架构篇

1. 假如让你负责鸿蒙App架构设计&#xff0c;你会关注哪些方面&#xff1f; 分层架构设计&#xff1a; 将应用划分为产品定制层、基础特性层和公共能力层&#xff0c;以降低层间依赖性&#xff0c;提升代码可维护性。通过分层架构设计&#xff0c;进一步明确每层的职责和层间交…

实现基于Elasticsearch的搜索服务

实现基于Elasticsearch的搜索服务 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. Elasticsearch简介 Elasticsearch是一个开源的分布式搜索引擎&#xff0c;提供强大的全文搜索和分析功能。本文…

快速上手文心一言:让创作更轻松

引言 在当今信息爆炸的时代&#xff0c;如何高效地进行内容创作成为了许多人的关注焦点。百度推出的文心一言&#xff0c;作为一款强大的AI写作工具&#xff0c;为内容创作者提供了全新的解决方案。本文将带您快速上手文心一言&#xff0c;让创作变得更轻松、更高效。 什么是…

FastReport 指定sql,修改数据源 ( 非DataSet修改 )

FastReport 指定sql&#xff0c;修改数据源&#xff0c;非DataSet修改 介绍报告文件&#xff1a; codetest.frx 文件核心代码&#xff1a;&#xff08;扩展&#xff09;小结一下&#xff1a; 介绍 在FastReport中&#xff0c;经常会遇到需要给 sql 加条件的情况。 &#xff0…

LeetCode 445.两数相加||

1.题目要求: 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。示例1&#xff1a;输入&#xff1a;l1 [7,2,4,3], l2 …

什么是 SpringBoot

SpringBoot 是由 Pivotal 团队提供的一个开源框架&#xff0c;旨在简化基于 Spring 框架的应用程序开发。它通过提供一套可用的默认配置和一系列有用的功能&#xff0c;使开发者能够迅速创建独立、生产级的 Spring 应用程序&#xff0c;而无需进行大量的配置。 SpringBoot 的设…

华为HCIP Datacom H12-821 卷38

1.多选题 下面关于 BGP中的公认属性的描述&#xff0c;正确的是 A、公认必遵属性是所有BGP路由器都识别&#xff0c;且必须存在于Updata消息中心 B、BGP必须识别所有公认属性 C、公认属性分为公认必遵和可选过渡两种 D、公认任意属性是所有BGP造由器都可以识别&#xff0c…

license系统模型设计使用django models

User (用户)License (许可证)Product (产品)LicenseAssignment (许可证分配) 简单的模型定义&#xff1a; from django.db import models from django.contrib.auth.models import Userclass Product(models.Model):name models.CharField(max_length255)description model…