记录--手把手教学,实现一个优雅的图片预览

news2024/12/22 19:45:39

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

在我们开发项目中,经常会遇到预览图片的需求。也就是点击图片,会全屏显示该图片。需求很简单,但是如何让实现更优雅就需要花点心思了。

最终效果图

4.gif

基础版本

实现方式

  • 点击图片,创建蒙层,克隆图片
  • 将图片添加定位属性,并添加到蒙层中
  • 将蒙层添加到body中

观察下图发现,虽然实现了需求,但是动画很生硬,我们作为前端开发工程师,得对得起工程师的身份,需要有工匠精神,接下来将介绍如何实现优雅的图片预览效果。

效果图

1.gif

代码

<!DOCTYPE html>
<html lang="en">
<head>
  <title>基础版本</title>
  <style>
    .pic1 {
      width: 400px;
    }
    .mask {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.7);
    }
    .previewImg {
      position: absolute;
      width: 80%;
      left: 50%;
      top: 200px;
      transform: translateX(-50%);
    }
  </style>
</head>
<body>
  <img class="pic1" src="./xtjj.jpg" alt="">
  <script>
    const pic1 = document.querySelector(".pic1");
    pic1.addEventListener("click", function () {
      // 创建蒙层
      const mask = document.createElement("div")
      mask.classList.add("mask");
      const pic1Clone = pic1.cloneNode();
      pic1Clone.classList.add("previewImg");
      // 将图片和蒙层添加到页面中
      mask.appendChild(pic1Clone)
      document.body.appendChild(mask)

      mask.addEventListener("click", function () {
        document.body.removeChild(this)
      })
    })
  </script>
</body>
</html>

打开动画

实现方式

  • 点击图片
    • 克隆原图,计算原图当前距离窗口的top与left的距离(用于确定克隆图片的初始位置)
    • 计算克隆图片的初始位置以及其相关属性
    • 创建蒙层,并添加相关的定位,背景色属性
    • 使用setTimeout是为了触发transition,产生移动效果。
    • 并且在setTimeout最开始将原图进行隐藏,产生是原图移动到屏幕中心的效果。使用visibility属性,避免引起页面布局变化。
  • 为蒙层添加点击事件
    • 点击蒙层后,删除蒙层元素,实现关闭预览功能

效果图

2.gif

代码

<!DOCTYPE html>
<html lang="en">
<head>
  <title>添加预览动画</title>
  <style>
    .pic {
      width: 400px;
    }
    .mask {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.7);
      transition: all .3s;
    }
    .previewImg {
      position: absolute;
      transform: translateX(-50%);
      transition: all .3s;
    }
  </style>
</head>
<body>
  <img class="pic" src="./xtjj.jpg" alt="">
  <script>
    const pic = document.querySelector(".pic");
    pic.addEventListener("click", function () {
      // 1,克隆元素
      const pic2 = pic.cloneNode();
      // 2,计算原图距离窗口left,top的距离
      picToTop = pic.getBoundingClientRect().x;
      picToLeft = pic.getBoundingClientRect().y;
      // 3,设置克隆图片初始位置
      pic2.style.position = "absolute";
      pic2.style.left = `${picToLeft}px`;
      pic2.style.top = `${picToTop}px`;
      // 4,创建蒙层
      const mask = document.createElement("div")
      mask.classList.add("mask");
      // 5,将元素添加到body中
      mask.appendChild(pic2)
      document.body.appendChild(mask)
      // 6,使用setTimeout是为了触发`transition`,产生动画
      setTimeout(() => {
        // 7,隐藏原图片
        pic.style.visibility = "hidden";
        // 8,设置预览图片展示宽度以及位置
        pic2.style.width = "80%";
        pic2.style.left = "50%";
        pic2.style.top = `200px`;
        pic2.classList.add("previewImg");
      }, 0);
      // 9,点击蒙层关闭预览
      mask.addEventListener("click", function () {
        this.remove()
      })
    })
  </script>
</body>
</html>

关闭动画

上一个步骤中,实现了点击图片,图片流畅显示的动画。但是关闭的时候很突然,这次将实现关闭的流畅动画。

实现方式

  • 点击图片的时候获取原图的宽度,以及距离窗口lefttop的距离
  • 点击蒙层的时候将克隆图片的位置移动到原图的位置(根据前面获取的原图位置)
  • 当克隆图片回到原图的位置时,需要将原图进行显示。使用visibility属性。
  • 使用setTimeout的原因是触发transition,产生动画效果。
  • 使用300毫秒是因为transition设置的是300毫秒的过渡时间,为了能在克隆图片会到原图位置的时候,再显示原图,并删除蒙层。

效果图

3.gif

代码

查看下个步骤

滚动时取消预览

实现方式

  • 在点击图片的时候,存储当前页面滚动的距离:lastPositon

  • 监听滚动事件,当滚动的距离减去lastPositon的值,大于100px的时候,触发蒙层的点击事件

  • 蒙层收到点击动作后,会执行取消预览的一系列动作。

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <title>滚动时取消预览</title>
  <style>
    body {
      height: 1000px;
    }
    .pic {
      width: 400px;
    }
    .mask {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.7);
      transition: all .3s;
    }
  </style>
</head>
<body>
  <img class="pic" src="./xtjj.jpg" alt="">
  <script>
    // 16,滚动超过100px。就取消预览
    window.onscroll = (e) => {
      if (Math.abs(window.pageYOffset - lastPositon) > 100) {
        document.querySelector(".mask")?.click();
      }
    }
    // 14,预览图片前页面滚动距离初始值
    let lastPositon = 0;
    const pic = document.querySelector(".pic");
    pic.addEventListener("click", function () {
      // 15,计算预览图片前页面滚动距离
      lastPositon = window.pageYOffset;
      // 1,克隆元素
      const pic2 = pic.cloneNode();
      // 2,计算原图距离窗口left,top的距离
      picToTop = pic.getBoundingClientRect().x;
      picToLeft = pic.getBoundingClientRect().y;
      // 11,计算原图宽度
      picWidth = pic.width;
      // 3,设置克隆图片初始位置
      pic2.style.position = "absolute";
      pic2.style.left = `${picToLeft}px`;
      pic2.style.top = `${picToTop}px`;
      // 4,创建蒙层
      const mask = document.createElement("div")
      mask.classList.add("mask");
      // 5,将元素添加到body中
      mask.appendChild(pic2)
      document.body.appendChild(mask)
      // 6,使用setTimeout是为了触发`transition`,产生动画
      setTimeout(() => {
        // 7,隐藏原图片
        pic.style.visibility = "hidden";
        // 8,设置预览图片展示宽度以及位置
        pic2.style.position = "absolute";
        pic2.style.transition = "all .3s";
        pic2.style.transform = "translateX(-50%)";
        pic2.style.width = "80%";
        pic2.style.left = "50%";
        pic2.style.top = `200px`;
      }, 0);
      // 9,点击蒙层关闭预览
      mask.addEventListener("click", function () {
        // 10,预览图回到原图位置
        pic2.style.width = `${picWidth}px`;
        pic2.style.left = `${picToLeft}px`;
        pic2.style.top = `${picToTop}px`;
        pic2.style.transform = "";
        // 12,显示原图
        setTimeout(() => {
          pic.style.visibility = "visible";
          // 13,删除蒙层以及预览图
          this.remove()
        }, 300);
      })
    })
  </script>
</body>
</html>

本文转载于:

https://juejin.cn/post/7155789252075356190

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

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

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

相关文章

从 Issue 看 El-Table 源码,给 Element+ 提 Pr 的背后竟如此坎坷

Element Plus大家应该都不陌生&#xff0c;用过 el-table 的伙伴更是多数&#xff0c;毕竟搞ToB业务 table 必不可少&#xff0c;但是真正翻看过源码的应该还是少数&#xff0c;有没有对其内部实现怀揣着一点点好奇呢&#xff1f;笔者就是因为怀揣着好奇&#xff0c;所以才走上…

什么是Intel Elkhart Lake?专用于物联网的处理器系列

随着世界向工业4.0过渡&#xff0c;边缘计算应用程序对实时推理、连接和数据遥测的更高性能和更低功耗处理的需求激增&#xff0c;并加强了加固。物联网和边缘计算的爆炸性增长造成了上一代处理器无法维持的性能瓶颈和限制。英特尔最新推出的Atom x6000 E系列、奔腾和赛扬N&…

IDEA无法使用Git Pull的问题

一、问题描述 我们开发项目时&#xff0c;经常会和第三方接口打交道&#xff0c;有些第三方项目为了安全起见&#xff0c;会把项目部署在"内网"环境&#xff0c;不对外暴露&#xff0c;通常会提供VPN代理才能访问到资源。 而在项目中我就因为这个而遇到了一个问题&am…

RK3568平台开发系列讲解(Linux系统篇)什么是Linux文件

🚀返回专栏总目录 文章目录 一、文件描述符二、常用文件 I/O 操作和函数2.1、open2.2、close2.3、read2.4、write沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 把大部分系统资源当作文件呈现给用户,用户只需按照文件 I/O 的方式,就能完成数据的输入输出。…

Diffusion 扩散模型(DDPM)详解及torch复现

文章目录torch复现第1步&#xff1a;正向过程噪声调度器Step 2: 反向传播 U-NetStep 3: 损失函数采样Training我公众号文章目录综述&#xff1a;https://wangguisen.blog.csdn.net/article/details/127065903 保姆级讲解 Diffusion 扩散模型&#xff08;DDPM&#xff09; ht…

python面向对象:入门

python面向对象&#xff1a;入门 文章目录python面向对象&#xff1a;入门一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.创建类和对象2.构造方法3.类中的实例方法一、实验目的 掌握类的基本使用 二、实验原理 面向过程&#xff1a;根据业务逻辑从上到下写…

Win10 BCD文件损坏怎么修复?

在Windows 10操作系统中&#xff0c;BCD代表引导配置数据&#xff08;Boot Configuration Data&#xff09;&#xff0c;Windows运行时BCD将告诉Windows引导加载程序在哪里查找引导信息&#xff0c; 因此&#xff0c;它对成功地加载和运行操作系统是非常重要的。哪些情况下会导…

二叉树的前序遍历

题目144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09;本章我们来探讨运用二叉树中所学的知识解决本题。对二叉树仍有疑问的小伙伴可以点击下方链接哦。参考文献&#xff1a;(1条消息) 二叉树&#xff08;三&#xff09;_染柒_GRQ的博客-CSDN博客原理首先我们来回…

CyberBattleSim-(内网自动化渗透)研究分析

**01 **背景知识介绍 CyberBattleSim介绍 CyberBattleSim是一款微软365 Defender团队开源的人工智能攻防对抗模拟工具&#xff0c;来源于微软的一个实验性研究项目。该项目专注于对网络攻击入侵后横向移动阶段进行威胁建模&#xff0c;用于研究在模拟抽象企业网络环境中运行的…

基于蜣螂算法优化的核极限学习机(KELM)分类算法-附代码

基于蜣螂算法优化的核极限学习机(KELM)分类算法 文章目录基于蜣螂算法优化的核极限学习机(KELM)分类算法1.KELM理论基础2.分类问题3.基于蜣螂算法优化的KELM4.测试结果5.Matlab代码摘要&#xff1a;本文利用蜣螂算法对核极限学习机(KELM)进行优化&#xff0c;并用于分类1.KELM理…

R语言贝叶斯方法在生态环境领域中的应用

贝叶斯统计已经被广泛应用到物理学、生态学、心理学、计算机、哲学等各个学术领域&#xff0c;其火爆程度已经跨越了学术圈&#xff0c;如促使其自成统计江湖一派的贝叶斯定理在热播美剧《The Big Bang Theory》中都要秀一把。贝叶斯统计学即贝叶斯学派是一门基本思想与传统基于…

STM32CubeMx使用FreeRTOS搭建printf输出串口打印-----基于正点原子开发板阿波罗

文章目录STM32CubeMx使用FreeRTOS搭建printf输出串口打印-----基于正点原子开发板阿波罗1.输入目标芯片2.选择RCC时钟3.配置调试模式4.USART的配置5.配置中断6.printf的重定向功能7.代码添加8.修改中断函数9.添加全局变量10.增加FreeRTOS支持11.在FreeRTOS中添加源码STM32CubeM…

【数学建模】数学建模中的常用工具推荐

前言 整理了几款我在建模比赛中需要准备的小工具&#xff0c;后续会随时不定期更新&#xff0c;以及完善内容&#xff0c;需要的小伙伴建议收藏一波~ [1] 公式编译器 Axmath&#xff08;建议购买正版&#xff09;mathtypeWord内置的公式编辑器 Axmath是国产的软件&#xff0…

pytorch安装(模式识别与图像处理课程实验)

pytorch安装&#xff08;模式识别与图像处理课程实验&#xff09;1、 打开cmd&#xff0c;创建torch虚拟环境。2、 激活创建的torch虚拟环境2.1、 进入pytorch官网&#xff0c;复制如下的命令&#xff0c;进行pytorch的安装2.2、测试安装是否成功3、 通过pip命令安装pytorch&am…

基于WPS实现Excel表的二级下拉选择框

基于WPS实现Excel表的二级下拉选择框第一步&#xff1a;先在sheet2上创建源数据第二步&#xff1a;创建一级下拉框第三步&#xff1a;创建二级下拉框报错记录&#xff1a; “列表源”XXXXXX第一步&#xff1a;先在sheet2上创建源数据 第二步&#xff1a;创建一级下拉框 一级下…

难受啊,备战字节跳动132天,因为一个疏忽让我前功尽弃...

&#x1f4cc; 博客主页&#xff1a; 程序员二黑 &#x1f4cc; 专注于软件测试领域相关技术实践和思考&#xff0c;持续分享自动化软件测试开发干货知识&#xff01; &#x1f4cc; 如果你也想学习软件测试&#xff0c;文末卡片有我的交流群&#xff0c;加入我们&#xff0c;一…

Kibana报错:Kibana server is not ready yet

背景 网页中访问kinaba http://localhost:5601 ,一直提示“Kibana server is not ready yet”。 执行如下命令查看kibana日志&#xff0c; docker logs kibana 发现有提示&#xff1a; 正文 怀疑是不是容器重启后&#xff0c;各容器内部ip变化了导致。 1、故执行如下命令查看…

Android框架源码分析——从设计模式角度看 RxJava 核心源码

从设计模式角度来看 RxJava 核心源码 从订阅者模式和装饰器模式的角度来看 RxJava 源码。 1. 普通订阅者模式与 RxJava 中的订阅者模式 订阅者模式又叫做观察者模式&#xff0c;主要用于实现响应式编程。其本质&#xff0c;就是接口回调。 普通订阅者模式&#xff1a;多个对…

来啦,华东师范大学2024年入学MBA提前面试流程及时间

项目简介华东师范大学系国家教育部和国务院学位办【2007&#xff08;36&#xff09;号】批准的工商管理硕士&#xff08;MBA&#xff09;培养单位。华东师范大学MBA项目&#xff0c;依托学校深厚的人文底蕴和育人文化&#xff0c;利用多学科支撑的优势、利用多元化的办学资源&a…

CUAD学习笔记

目录一、头文件**1、mex.h****2、matrix.h****3、string****4、iostream****5、omp.h**6、cuda_runtime.h7、stdlib.h8、sys/time.h9、stdio.h10、string.h11、time.h12、math.h13、device_launch_parameters.h二、一些声明语句1、using namespace std**2、typedef unsigned ch…