千家信息网

怎么使用Vue3实现图片散落效果

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容介绍了"怎么使用Vue3实现图片散落效果"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!出现问
千家信息网最后更新 2025年11月07日怎么使用Vue3实现图片散落效果

本篇内容介绍了"怎么使用Vue3实现图片散落效果"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

出现问题

一下午的摸鱼时光,间公司熙熙攘攘,我在其中却格格不入(太闲了),不知多少人投来质疑的眼光(这家伙不工作吗),但我只沉浸在我的代码里。终于勉强完成了一个不怎么丑的版本。

原理

图片破裂效果说白了就是搞了100个div,每个div都有自己的背景图片,通过backgroundPosition属性来控制每个div的背景图片方位,最后拼在一起,就像一张完整的图片一样,给每个div都加上动画效果,每个div的旋转角度不同,移动距离不同,移动方位不同来让整个图片像玻璃一样散开来。

HTML结构

这里用到了两个div,#break是用作为100个div的容器,#InBox是用来绑定下一张的背景图片

准备5张图片

import bgImg5 from '../../assets/img/1/y1.png'import bgImg4 from '../../assets/img/1/y2.png'import bgImg3 from '../../assets/img/1/y3.png'import bgImg2 from '../../assets/img/1/y4.png'import bgImg6 from '../../assets/img/1/y5.png'import { ref, onMounted, onUnmounted } from 'vue'let index = 0onMounted(() => {  let imageSrcArr = [bgImg2, bgImg3, bgImg4, bgImg5, bgImg6]  let imgloadPromiseArr: Array> = []  let imageArr: Array = []  for (let i = 0; i < imageSrcArr.length; i++) {    imgloadPromiseArr[i] = new Promise((resolve, reject) => {      let img = new Image()      img.src = imageSrcArr[i]      img.onload = () => {        resolve(img)      }    })  }  imgloadPromiseArr.forEach(item => {    item.then(res => {      imageArr.push(`url(${(res).currentSrc})`)      index = imageArr.length    })  })  })

创建div

通过createElement创建200个div,每个div绑定长宽,给div添加背景图片,使用backgroundPosition来让整个div变得像一张图片,给div绑定动画效果。

for (let i = 0; i < 100; i++) {      let div = document.createElement('div')      let div1 = document.createElement('div')      div.style.width = '76px'      div.style.height = '41px' // 这里为什么是41px后面会提到      div1.style.width = '76px'      div1.style.height = '40px'      div1.style.overflow = 'hidden'      div.style.boxSizing = 'border-box'      div.style.backgroundImage = imageArr[0]      let positionX = -(i % 10) * 76 + 'px'      let positionY = -Math.floor(i / 10) * 40 + 'px'      div.style.backgroundPosition = positionX + ' ' + positionY      div.style.backgroundSize = '760px 400px'      let style = document.styleSheets[0]      style.insertRule(`@keyframes secondrotate${i}        {            0%,30%{                transform:scale(1)            }            70%            {transform: rotateX(${180 + Math.random() * 720}deg) rotateY(${180 + Math.random() * 720}deg)}            100%            {transform: rotateX(${180 + Math.random() * 720}deg) rotateY(${180 + Math.random() * 720}deg)}        }`)      style.insertRule(`@keyframes secondrotateS${i}        {            0%,32%{                transform:scale(1);opacity:1;            }70%            {transform: translateZ(${300 + Math.random() * 1500}px) translate(${(0.5 - Math.random()) * 500}px,${        (0.5 - Math.random()) * 500      }px);opacity:0}            100%            {transform: translateZ(${300 + Math.random() * 1500}px) translate(${(0.5 - Math.random()) * 500}px,${        (0.5 - Math.random()) * 500      }px);opacity:0}        }`)      div1.style.animation = `secondrotateS${i} 4.5s ease-out infinite`      div.style.animation = `secondrotate${i} 4.5s ease-out infinite`      div.style.transformOrigin = `center center`      div1.appendChild(div)      dom.appendChild(div1)}

切换背景图片

通过zIndex来让当前展示的div是哪一个

前面说过,InBox是展示的下一张图片,在breakBox散落完成之后,让breakBox的zIndex降低,展示出下一张图片,随后带有100个div的breakBox完成下一张图片的渲染,zIndex提高,展示出来

 let count = 0 let repeat = true let breakBox: HTMLDivElement = document.querySelector('#break')! let InBox: HTMLDivElement = document.querySelector('#InBox')!  function changeImage(InBox: HTMLDivElement) {    if (repeat) {      breakBox.style.zIndex = '-10'      count++      count = count === index ? 0 : count      repeat = false      setTimeout(() => {        repeat = true        breakBox.style.zIndex = '100'        let currentImageLength = count === index - 1 ? 0 : count + 1        InBox.style.backgroundImage = imageArr[currentImageLength]      }, 1000)    }  }

每次动画完成之后会去调上面这个方法,为了能在div碎片破碎完毕,展示下一张图片,使用定时器将该方法进行延迟处理 4s是因为div碎片在4s后完全消失。(动画在运行70%的时候,透明度为0)

const timer1 = ref()const timer2 = ref()for (let i = 0; i < 100; i++) {      let div = document.createElement('div')      let div1 = document.createElement('div')      div.style.width = '76px'      div.style.height = '41px'      div1.style.width = '76px'      div1.style.height = '40px'      div1.style.overflow = 'hidden'      div.style.boxSizing = 'border-box'      div.style.backgroundImage = imageArr[0]      let positionX = -(i % 10) * 76 + 'px'      let positionY = -Math.floor(i / 10) * 40 + 'px'      div.style.backgroundPosition = positionX + ' ' + positionY      div.style.backgroundSize = '760px 400px'      let style = document.styleSheets[0]      style.insertRule(`@keyframes secondrotate${i}        {            0%,30%{                transform:scale(1)            }            70%            {transform: rotateX(${180 + Math.random() * 720}deg) rotateY(${180 + Math.random() * 720}deg)}            100%            {transform: rotateX(${180 + Math.random() * 720}deg) rotateY(${180 + Math.random() * 720}deg)}        }`)      style.insertRule(`@keyframes secondrotateS${i}        {            0%,32%{                transform:scale(1);opacity:1;            }70%            {transform: translateZ(${300 + Math.random() * 1500}px) translate(${(0.5 - Math.random()) * 500}px,${        (0.5 - Math.random()) * 500      }px);opacity:0}            100%            {transform: translateZ(${300 + Math.random() * 1500}px) translate(${(0.5 - Math.random()) * 500}px,${        (0.5 - Math.random()) * 500      }px);opacity:0}        }`)      div1.style.animation = `secondrotateS${i} 4.5s ease-out infinite`      div.style.animation = `secondrotate${i} 4.5s ease-out infinite`      div.style.transformOrigin = `center center`      div.addEventListener('animationstart', () => {        timer1.value = setTimeout(() => {          changeImage(InBox)          div.style.backgroundImage = imageArr[count]        }, 4000)      })      div.addEventListener('animationiteration', () => {        timer2.value = setTimeout(() => {          changeImage(InBox)          div.style.backgroundImage = imageArr[count]        }, 4000)      })      div1.appendChild(div)      dom.appendChild(div1)    }

div存在间隙的问题

在100个div展示之后会出现这样的线,在经过多次尝试之后,找到了方法,将div的高度变大,div1设置overflow:hidden; 线回消失

代码详情

"怎么使用Vue3实现图片散落效果"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0