首页 > 其他分享 >记录--手把手教学,实现一个优雅的图片预览

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

时间:2023-01-31 17:37:07浏览次数:48  
标签:style 蒙层 预览 -- 手把手 pic mask pic2

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

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

最终效果图

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

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

 

标签:style,蒙层,预览,--,手把手,pic,mask,pic2
From: https://www.cnblogs.com/smileZAZ/p/17079921.html

相关文章

  • 零代码实现EDI标准报文转换
    在与客户进行沟通的时候,经常有客户对EDI实施很感兴趣,一方面是客户具有相应的IT基础和技术力量,并且后续可能会有更多合作伙伴的EDI接入,因此客户有自主实施的想法;另一方面也......
  • Maven依赖调解
    实际开发中可能存在这种情况,A->B->C->X(1.0),A->D->X(2.0),此时X出现了2个版本1.0和2.0,此时A项目会选择X的哪个版本?解决这种问题,maven有2个原则:路径最近原则上面A->B->C->......
  • WebAPI_DAY2
    事件编程时系统发生的动作或发生的事情(如单击一个按钮)事件监听程序检测是否有事件产生,一旦事件触发,就立即调用一个函数作出响应,称为注册事件语法元素.addEventListene......
  • Makefile文件
    #编译后的可执行文件名称BIN=stack#收集目录下的所有.c文件SRC=$(wildcard*.c)#调用makefile中的函数patsubst,用.o文件代替.c文件OBJ=$(patsubst%.c,%.o,$(SR......
  • NET 实现 Cron 定时任务执行,告别第三方组件
    原文连接:(96条消息)NET实现Cron定时任务执行,告别第三方组件_.net定时任务_PhilArist的博客-CSDN博客 代码:usingSystem.Globalization;usingSystem.Text;us......
  • 杨氏矩阵
    有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。要求:时间复杂度小于O(N);......
  • CLR Resolve a referenced type
    CLR如何解析引用的类型CLR寻找类型只有三种可能地方相同文件(相同程序集)不同文件,相同程序集不同文件,不同程序集相同文件案例一:以下案例是执行Point_1.exe时,运行到st......
  • Yolov3的大致框架理解
                                                       ......
  • App自动化测试|原生app元素定位方法
    ##元素定位方法介绍及应用Appium方法定位原生app元素通过appiuminspector工具,可以获取元素的相关信息;在appium中提供了一系列的元素定位API,通过在这些API中输入指定的元素......
  • HTML5本地存储IndexedDB基础介绍(-)-数据库的简单增删改查
    //https://www.jianshu.com/p/4c74cbe60d83?_=1509695140<!DOCTYPEhtml><html><head><metacharset="utf-8"/><metaname="viewport"content="width=devi......