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

  • 记录–手把手教学,实现一个优雅的图片预览已关闭评论
  • 232 次浏览
  • A+
所属分类:Web前端
摘要

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


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

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

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

最终效果图

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

基础版本

实现方式

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

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

效果图

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

代码

<!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="记录--手把手教学,实现一个优雅的图片预览" 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属性,避免引起页面布局变化。
  • 为蒙层添加点击事件
    • 点击蒙层后,删除蒙层元素,实现关闭预览功能

效果图

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

代码

<!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="记录--手把手教学,实现一个优雅的图片预览" 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毫秒的过渡时间,为了能在克隆图片会到原图位置的时候,再显示原图,并删除蒙层。

效果图

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

代码

查看下个步骤

滚动时取消预览

实现方式

  • 在点击图片的时候,存储当前页面滚动的距离: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="记录--手把手教学,实现一个优雅的图片预览" 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

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

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