溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

基于Vue3怎么實(shí)現(xiàn)圖片散落效果

發(fā)布時(shí)間:2022-04-18 09:07:49 來(lái)源:億速云 閱讀:122 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“基于Vue3怎么實(shí)現(xiàn)圖片散落效果”,在日常操作中,相信很多人在基于Vue3怎么實(shí)現(xiàn)圖片散落效果問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”基于Vue3怎么實(shí)現(xiàn)圖片散落效果”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

效果圖

基于Vue3怎么實(shí)現(xiàn)圖片散落效果

原理

圖片破裂效果說(shuō)白了就是搞了100個(gè)div,每個(gè)div都有自己的背景圖片,通過(guò)backgroundPosition屬性來(lái)控制每個(gè)div的背景圖片方位,最后拼在一起,就像一張完整的圖片一樣,給每個(gè)div都加上動(dòng)畫(huà)效果,每個(gè)div的旋轉(zhuǎn)角度不同,移動(dòng)距離不同,移動(dòng)方位不同來(lái)讓整個(gè)圖片像玻璃一樣散開(kāi)來(lái)。

HTML結(jié)構(gòu)

這里用到了兩個(gè)div,#break是用作為100個(gè)div的容器,#InBox是用來(lái)綁定下一張的背景圖片

<div id="animateBox" v-show="showImg">
        <div id="break"></div>
        <div id="InBox"></div>
</div>

準(zhǔn)備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 = 0
onMounted(() => {
  let imageSrcArr = [bgImg2, bgImg3, bgImg4, bgImg5, bgImg6]
  let imgloadPromiseArr: Array<Promise<HTMLImageElement>> = []
  let imageArr: Array<string> = []
  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(${(<HTMLImageElement>res).currentSrc})`)
      index = imageArr.length
    })
  })
  })

創(chuàng)建div

通過(guò)createElement創(chuàng)建200個(gè)div,每個(gè)div綁定長(zhǎng)寬,給div添加背景圖片,使用backgroundPosition來(lái)讓整個(gè)div變得像一張圖片,給div綁定動(dòng)畫(huà)效果。

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后面會(huì)提到
      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)
}

切換背景圖片

通過(guò)zIndex來(lái)讓當(dāng)前展示的div是哪一個(gè)

前面說(shuō)過(guò),InBox是展示的下一張圖片,在breakBox散落完成之后,讓breakBox的zIndex降低,展示出下一張圖片,隨后帶有100個(gè)div的breakBox完成下一張圖片的渲染,zIndex提高,展示出來(lái)

 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)
    }
  }

每次動(dòng)畫(huà)完成之后會(huì)去調(diào)上面這個(gè)方法,為了能在div碎片破碎完畢,展示下一張圖片,使用定時(shí)器將該方法進(jìn)行延遲處理 4s是因?yàn)閐iv碎片在4s后完全消失。(動(dòng)畫(huà)在運(yùn)行70%的時(shí)候,透明度為0)

const timer1 = ref<number>()
const timer2 = ref<number>()
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存在間隙的問(wèn)題

基于Vue3怎么實(shí)現(xiàn)圖片散落效果

在100個(gè)div展示之后會(huì)出現(xiàn)這樣的線,在經(jīng)過(guò)多次嘗試之后,找到了方法,將div的高度變大,div1設(shè)置overflow:hidden; 線回消失

代碼詳情

<template>
  <div>
    <transition name="fadeIn">
      <div id="animateBox" v-show="showImg">
        <div id="break"></div>
        <div id="InBox"></div>
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
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'
const timer1 = ref<number>()
const timer2 = ref<number>()
const showImg = ref<boolean>(false)

onMounted(() => {
  let imageSrcArr = [bgImg2, bgImg3, bgImg4, bgImg5, bgImg6]
  let imgloadPromiseArr: Array<Promise<HTMLImageElement>> = []
  let imageArr: Array<string> = []
  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(${(<HTMLImageElement>res).currentSrc})`)
      index = imageArr.length
    })
  })
  showImg.value = true
  let repeat = true
  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)
    }
  }
  let count = 0
  let index = 0
  let breakBox: HTMLDivElement = document.querySelector('#break')!
  let InBox: HTMLDivElement = document.querySelector('#InBox')!
  InBox.style.backgroundImage = imageArr[1]
  const appendDom = (dom: HTMLElement) => {
    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)
    }
  }
  appendDom(breakBox)
})
onUnmounted(() => {
  typeof timer1 === 'number' && clearTimeout(timer1)
  typeof timer2 === 'number' && clearTimeout(timer2)
})
</script>

<style scoped lang="scss">
@import url('../../css/comment/animate.css');
#animateBox {
  width: 100vw;
  height: calc(100vh - 50px);
  //  background-color: rgba(255, 255, 255, 0.6);
  #break {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    width: 760px;
    height: 400px;
    display: flex;
    perspective: 1000px;
    transform-style: preserve-3d;
    flex-wrap: wrap;
    z-index: 100;
  }
  #InBox {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    width: 760px;
    height: 400px;
    display: flex;
    perspective: 1000px;
    transform-style: preserve-3d;
    flex-wrap: wrap;
    z-index: 10;
    background-size: 760px 400px;
  }
}
</style>

到此,關(guān)于“基于Vue3怎么實(shí)現(xiàn)圖片散落效果”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI