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

news2024/11/15 15:47:01

目录

一、需求描述

二、实现效果

三、完整代码

四、实现过程

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>

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

每天进步一点点~!

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【电脑应用技巧】如何寻找电脑应用的安装包华为电脑、平板和手机资源交换共享

电脑的初学者可能会直接用【百度】搜索电脑应用程序的安装包&#xff0c;但是这样找到的电脑应用程序安装包经常会被加入木马或者强制捆绑一些不需要的应用装入电脑。 今天告诉大家一个得到干净电脑应用程序安装包的方法&#xff0c;就是用【联想的应用商店】。联想电脑我是一点…

使用Lego进行证书的申请和更新

姊妹篇: 使用Let’s Encrypt 申请通配符证书 关于acme 协议 ACME是自动证书管理环境&#xff08;Automatic Certificate Management Environment&#xff09;的缩写&#xff0c;是一个由IETF&#xff08;Internet Engineering Task Force&#xff09;制定的协议标准&#xff0c…

gd32F470串口重定义

c代码&#xff1a; /** Author: Bleaach008* Date: 2024-07-10 17:31:01* LastEditTime: 2024-07-11 09:42:06* FilePath: \MDK-ARMd:\Code\GD32\GD01_UART\MyApplication\Public.c* Description:** Copyright (c) 2024 by 008, All Rights Reserved.*/ /* Includes ----------…

QFileDialog的简单了解

ps&#xff1a;写了点垃圾&#xff08;哈哈哈&#xff09; 现在感觉Qt库应该是调用了Windows提供的这块的接口了。 它继承自QDialog 这是Windows自己的文件夹 这是两者的对比图&#xff1a; 通过看QFileDialog的源码&#xff0c;来分析它是怎么实现这样的效果的。 源码组成…

面试篇-Java-5+设计模式

文章目录 前言一、你知道工厂方法模式吗1.1 你有使用过简单工厂模式吗1.2 你有使用过简单工厂方法模式吗1.3 你有使用过抽象工厂方法模式吗1.4 你有使用过策略模式吗 二、你们项目中是怎么使用设计模式的呢2.1 策略模式 工厂模式 实现不同的方式的登录2.1.1 定义一个登录的接口…

SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测

SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测 目录 SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现NGO-CNN-LSTM-Mutilhead-Attention北方苍鹰算…

怎么用PPT录制微课?详细步骤解析!

随着信息技术的不断发展&#xff0c;微课作为一种新型的教学形式&#xff0c;因其短小精悍、针对性强等特点&#xff0c;在教育领域得到了广泛的应用。而PPT作为一款常用的演示工具&#xff0c;不仅可以用来制作课件&#xff0c;还可以利用其内置的录屏功能或结合专业的录屏软件…

【机器学习】Exam4

实现线性不可分logistic逻辑回归 我们目前所学的都是线性回归&#xff0c;例如 y w 1 x 1 w 2 x 2 b y w_1x_1w_2x_2b yw1​x1​w2​x2​b 用肉眼来看数据集的话不难发现&#xff0c;线性回归没有用了&#xff0c;那么根据课程所学&#xff0c;我们是不是可以增加 x 3 x…

有必要把共享服务器升级到VPS吗?

根据自己的需求来选择是否升级&#xff0c;虚拟专用服务器 (VPS) 是一种托管解决方案&#xff0c;它以低得多的成本提供专用服务器的大部分功能。使用 VPS&#xff0c;您的虚拟服务器将与在其上运行的其他虚拟服务器共享硬件服务器的资源。但是&#xff0c;与传统的共享托管&am…

# Redis 入门到精通(一)数据类型(4)

Redis 入门到精通&#xff08;一&#xff09;数据类型&#xff08;4&#xff09; 一、redis 数据类型–sorted_set实现时效性任务管理 1、sorted_set 类型数据操作的注意事项 score 保存的数据存储空间是64位&#xff0c;如果是整数范围是-9007199254740992~9007199254740992…

内网对抗-基石框架篇域树林域森林架构信任关系多域成员层级信息收集环境搭建

知识点&#xff1a; 1、基石框架篇-域树&域林架构-权限控制-用户和网络 2、基石框架篇-域树&域林架构-环境搭建-准备和加入 3、基石框架篇-域树&域林架构-信息收集-手工和工具1、工作组(局域网) 将不同的计算机按照功能分别列入不同的工作组。想要访问某个部门的…

PostgreSQL 怎样处理数据仓库中维度表和事实表的关联性能?

文章目录 PostgreSQL 中维度表和事实表关联性能的处理 PostgreSQL 中维度表和事实表关联性能的处理 在数据仓库的领域中&#xff0c;PostgreSQL 作为一款强大的关系型数据库管理系统&#xff0c;对于处理维度表和事实表的关联性能是一个关键的问题。维度表和事实表的关联是数据…

基于B站视频评论的文本分析,采用包括文本聚类分析、LDA主题分析、网络语义分析

研究主题 本研究旨在通过对B站视频评论数据进行文本分析&#xff0c;揭示用户评论的主题、情感倾向和语义结构&#xff0c;助力商业决策。主要技术手段包括Python爬虫、LDA主题分析、聚类分析和语义网络分析。首先&#xff0c;利用Python爬虫采集大量评论数据并进行预处理。运…

Hadoop3:动态扩容之新增一台机器的初始化工作

一、需求描述 给Hadoop集群动态扩容一个节点 那么&#xff0c;这个节点是全新的&#xff0c;我们需要做哪些准备工作&#xff0c;才能将它融入集群了&#xff1f; 二、初始化配置 1、修改IP和hostname vim /etc/sysconfig/network-scripts/ifcfg-ens33 vim /etc/hostname2、…

激活交通运输创新活力 推进户外安全指数——北三车载终端TD3D:准确追踪 应急救援

根据交通运输部办公厅发布《关于充分发挥全国道路货运车辆公共监管与服务平台作用支撑行业高质量发展的意见》&#xff08;下称《意见》&#xff09;。《意见》提出&#xff0c;要持续拓展货运平台服务功能&#xff0c;加快推动北斗终端应用。 《意见》提出&#xff0c;加快单…

【eNSP模拟实验】单臂路由实现VLAN间通信

实验需求 如下图所示&#xff0c;辅导员办公室需要访问处在不同vlan的学生管理服务器的文件&#xff0c;那么如何实现两台终端相互通信呢&#xff1f;我们可以使用单臂路由的方式来实现。 单臂路由&#xff08;router-on-a-stick&#xff09;是指在路由器的一个接口上通过配置…

Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志

章节内容 上节我们完成了如下的内容&#xff1a; Sqoop MySQL迁移到HiveSqoop Hive迁移数据到MySQL编写脚本进行数据导入导出测试 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机…

某某会员小程序后端性能优化

背景 某某会员小程序后台提供开放平台能力&#xff0c;为三方油站提供会员积分、优惠劵等api。当用户在油站加油&#xff0c;油站收银会调用我们系统为用户发放积分、优惠劵等。用户反馈慢&#xff0c;三方调用发放积分接口性能极低&#xff0c;耗时30s&#xff1b; 接口情况…

短视频SEO矩阵系统:源码开发与部署全攻略

在数字化时代&#xff0c;短视频已成为人们获取信息、娱乐休闲的重要方式。随着短视频平台的兴起&#xff0c;如何让自己的内容在众多视频中脱颖而出&#xff0c;成为每个创作者和内容运营者关注的焦点。本文将为您深入解析短视频SEO矩阵系统的源码开发与部署&#xff0c;助您在…

【原创教程】埃斯顿机器人:弯管机推力解决方式(上)

现的功能及应用的场合 本项目为弯管机设备改造工程,在不破坏设备原有的功能的情况下通过只更换设备原来的永宏PLC,使弯管机能够与埃斯顿机器人进行信号交互,通过机器人对弯管机进行上料、下料动作,即节约了人工成本,又提高了生产效率。 本文所述内容为“弯管机推力”的解决…