首頁  >  文章  >  web前端  >  手把手教你使用Vue3實現圖片散落效果

手把手教你使用Vue3實現圖片散落效果

青灯夜游
青灯夜游轉載
2022-04-27 10:57:192475瀏覽

基於Vue3怎麼實現圖片散落效果?以下這篇文章為大家介紹一下使用Vue3實現圖片散落效果的方法,希望對大家有幫助!

手把手教你使用Vue3實現圖片散落效果

今天又是美好的摸魚一天,剛剛進入職場,覺得一切都很新鮮,導師給的任務也不多(要是每天都是這樣就好了),於是開始有薪學習。 (學習影片分享:vuejs教學

做啥好呢

沒事在網路上亂逛的時候,偶然間看到一個動畫效果不錯,就決定上手做一些,簡單的說就是一個完整的圖片,在一段時間之後回突然破裂開來,覺得很有意思,就新建了一個資料夾。

問題

一下午的摸魚時光,間公司熙熙攘攘,我在其中卻格格不入(太閒了),不知多少人投來質疑的眼光(這傢伙不工作嗎),但我只沉浸在我的程式碼裡。終於勉強完成了一個不怎麼醜的版本。

手把手教你使用Vue3實現圖片散落效果

原理

圖片破裂效果說白了就是搞了100個div,每個div都有自己的背景圖片,透過backgroundPosition屬性來控制每個div的背景圖片方位,最後拼在一起,就像一張完整的圖片一樣,給每個div都加上動畫效果,每個div的旋轉角度不同,移動距離不同,移動方位不同來讓整個圖片像玻璃一樣散開。

HTML結構

這裡用到了兩個div,#break是用作為100個div的容器,#InBox是用來綁定下一張的背景圖片

r​​rreee

準備5張圖片

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

#建立div

透過createElement建立200個div,每個div綁定長寬,為div添加背景圖片,使用backgroundPosition來讓整個div變得像一張圖片,給div綁定動畫效果。

import bgImg5 from &#39;../../assets/img/1/y手把手教你使用Vue3實現圖片散落效果&#39;
import bgImg4 from &#39;../../assets/img/1/y手把手教你使用Vue3實現圖片散落效果&#39;
import bgImg3 from &#39;../../assets/img/1/y3.png&#39;
import bgImg2 from &#39;../../assets/img/1/y4.png&#39;
import bgImg6 from &#39;../../assets/img/1/y5.png&#39;
import { ref, onMounted, onUnmounted } from &#39;vue&#39;
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
    })
  })
  })

切換背景圖片

透過zIndex來讓目前展示的div是哪一個

前面說過,InBox是展示的下一張圖片,在breakBox散落完成之後,讓breakBox的zIndex降低,展示下一張圖片,隨後帶有100個div的breakBox完成下一張圖片的渲染,zIndex提高,展示出來

for (let i = 0; i < 100; i++) {
      let div = document.createElement(&#39;div&#39;)
      let div1 = document.createElement(&#39;div&#39;)
      div.style.width = &#39;76px&#39;
      div.style.height = &#39;41px&#39; // 这里为什么是41px后面会提到
      div1.style.width = &#39;76px&#39;
      div1.style.height = &#39;40px&#39;
      div1.style.overflow = &#39;hidden&#39;
      div.style.boxSizing = &#39;border-box&#39;
      div.style.backgroundImage = imageArr[0]
      let positionX = -(i % 10) * 76 + &#39;px&#39;
      let positionY = -Math.floor(i / 10) * 40 + &#39;px&#39;
      div.style.backgroundPosition = positionX + &#39; &#39; + positionY
      div.style.backgroundSize = &#39;760px 400px&#39;
      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)
}

每次動畫完成之後會去調上面這個方法,為了能在div碎片破碎完畢,展示下一張圖片,使用定時器將該方法進行延遲處理4s是因為div碎片在4s後完全消失。 (動畫在運行70%的時候,透明度為0)

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

div存在間隙的問題

手把手教你使用Vue3實現圖片散落效果

在100個div展示之後會出現這樣的線,在經過多次嘗試之後,找到了方法,將div的高度變大,div1設定overflow:hidden; 線回消失

程式碼詳情

const timer1 = ref<number>()
const timer2 = ref<number>()
for (let i = 0; i < 100; i++) {
      let div = document.createElement(&#39;div&#39;)
      let div1 = document.createElement(&#39;div&#39;)
      div.style.width = &#39;76px&#39;
      div.style.height = &#39;41px&#39;
      div1.style.width = &#39;76px&#39;
      div1.style.height = &#39;40px&#39;
      div1.style.overflow = &#39;hidden&#39;
      div.style.boxSizing = &#39;border-box&#39;
      div.style.backgroundImage = imageArr[0]
      let positionX = -(i % 10) * 76 + &#39;px&#39;
      let positionY = -Math.floor(i / 10) * 40 + &#39;px&#39;
      div.style.backgroundPosition = positionX + &#39; &#39; + positionY
      div.style.backgroundSize = &#39;760px 400px&#39;
      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(&#39;animationstart&#39;, () => {
        timer1.value = setTimeout(() => {
          changeImage(InBox)
          div.style.backgroundImage = imageArr[count]
        }, 4000)
      })
      div.addEventListener(&#39;animationiteration&#39;, () => {
        timer2.value = setTimeout(() => {
          changeImage(InBox)
          div.style.backgroundImage = imageArr[count]
        }, 4000)
      })
      div1.appendChild(div)
      dom.appendChild(div1)
    }

(學習影片分享:web前端開發程式設計入門

以上是手把手教你使用Vue3實現圖片散落效果的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除