返回顶部
首页 > 资讯 > 前端开发 > JavaScript >基于Vue3实现的图片散落效果实例
  • 168
分享到

基于Vue3实现的图片散落效果实例

2024-04-02 19:04:59 168人浏览 薄情痞子
摘要

目录背景做啥好呢出现问题原理html结构准备5张图片创建div切换背景图片div存在间隙的问题代码详情总结背景 今天又是美好的摸鱼一天,刚刚进入职场,觉得一切都很新鲜,导师给的任务也

背景

今天又是美好的摸鱼一天,刚刚进入职场,觉得一切都很新鲜,导师给的任务也不多(要是每天都是这样就好了),于是开始带薪学习

做啥好呢

没事在网上乱逛的时候,偶然间看到一个动画效果不错,就决定上手做一些,简单的说就是一个完整的图片,在一段时间之后回突然破裂开来,觉得很有意思,就新建了一个文件夹。

出现问题

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

原理

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

HTML结构

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

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

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

创建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<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存在间隙的问题

在100个div展示之后会出现这样的线,在经过多次尝试之后,找到了方法,将div的高度变大,div1设置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>

总结

到此这篇关于基于vue3实现的图片散落效果的文章就介绍到这了,更多相关Vue3图片散落内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 基于Vue3实现的图片散落效果实例

本文链接: https://lsjlt.com/news/146265.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 基于Vue3实现的图片散落效果实例
    目录背景做啥好呢出现问题原理HTML结构准备5张图片创建div切换背景图片div存在间隙的问题代码详情总结背景 今天又是美好的摸鱼一天,刚刚进入职场,觉得一切都很新鲜,导师给的任务也...
    99+
    2024-04-02
  • 基于Vue3怎么实现图片散落效果
    这篇文章主要介绍“基于Vue3怎么实现图片散落效果”,在日常操作中,相信很多人在基于Vue3怎么实现图片散落效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于Vue3怎么实现图片散落效果”的疑惑有所帮助!...
    99+
    2023-06-30
  • 怎么使用Vue3实现图片散落效果
    本篇内容介绍了“怎么使用Vue3实现图片散落效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!出现问题一下午的摸鱼时光,间公司熙熙攘攘,我在...
    99+
    2023-06-30
  • 基于html5如何实现的图片墙效果
    小编给大家分享一下基于html5如何实现的图片墙效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! 代码如下: <!DOCTYPE html> <html ng-a...
    99+
    2024-04-02
  • 基于openlayers4如何实现点的扩散效果
    这篇文章主要为大家展示了“基于openlayers4如何实现点的扩散效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“基于openlayers4如何实现点的扩散...
    99+
    2024-04-02
  • Vue3实现图片放大镜效果
    本文实例为大家分享了Vue3实现图片放大镜效果的具体代码,供大家参考,具体内容如下 实现效果 代码 <template> <div class="good...
    99+
    2024-04-02
  • 基于Echarts实现饼图效果
    本文实例为大家分享了Echarts实现饼图效果的具体代码,供大家参考,具体内容如下 1 显示数值效果 series 下的label 饼图的文字显示2 半径 圆环 radius3 南丁...
    99+
    2024-04-02
  • 基于Unity3D实现3D照片墙效果
    一、前言 Unity3D不仅仅可以开发游戏,还有非常多的开发方向,秉承着兴趣为先,将可以使用Unity制作的各种应用案例,分享如何进行开发,如何实现,希望大家可以在感兴趣的地方,学习...
    99+
    2024-04-02
  • 基于jquery实现轮播图效果
    本文实例为大家分享了jquery实现轮播图效果的具体代码,供大家参考,具体内容如下 轮播图左切换原理图 黄色的方框表示的是  slides ,而  slide ...
    99+
    2024-04-02
  • 基于Vue3实现列表虚拟滚动效果
    目录前言完成效果思路和需要解决的问题vue3+setup 写的组件使用组件前言 近期在做一个网页播放器项目中,用到很多需要展示歌单的列表 一个歌单动辄千百首歌曲,页面中的元素太多导致...
    99+
    2024-04-02
  • 基于Vue3实现旋转木马动画效果
    做的比较丑 最后图片 本来打算用vue-carousel-3d这个组件的,但是这个组件一直报源码错误,修改了半天也没有解决 效果图 实现代码 使用了swiper组件 html部分...
    99+
    2024-04-02
  • Python基于pygame实现图片代替鼠标移动效果
    本文实例讲述了Python基于pygame实现图片代替鼠标移动效果。分享给大家供大家参考,具体如下: 想想现在学校pygame有几个钟了,就写了一个小程序:图片代替鼠标移动 程序的运行效果: 当鼠标移动...
    99+
    2022-06-04
    鼠标 效果 图片
  • 基于three.js实现简易照片墙效果
    学习three.js的过程中,写的一个简易照片墙,可以使用鼠标滚轮上下浏览,采用的是移动相机的方式。 代码贴出来,供学习这一块的朋友们参考和指导:  <!DOCTYPE HTM...
    99+
    2024-04-02
  • 基于Echarts如何实现饼图效果
    这篇文章主要讲解了“基于Echarts如何实现饼图效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于Echarts如何实现饼图效果”吧!1 显示数值效果 series 下的label 饼...
    99+
    2023-06-30
  • 基于jquery实现的上传图片及图片大小验证、图片预览效果代码
    jquery实现上传图片及图片大小验证、图片预览效果代码 上传图片验证 复制代码 代码如下: */ function submit_upload_picture(){ var fil...
    99+
    2022-11-21
    上传图片 图片大小验证 预览
  • vue3使用useMouseInElement实现图片局部放大预览效果实例代码
    目录1、首先要安装@vueuse/core2、实现过程如下:3、使用:在其他的.vue文件中导入组件即可使用4、效果如下:总结1、首先要安装@vueuse/core npm i @v...
    99+
    2023-03-19
    vue图片预览放大缩小 vue点击图片放大 vue实现文件预览功能
  • Android基于TextView实现的跑马灯效果实例
    本文实例讲述了Android基于TextView实现的跑马灯效果。分享给大家供大家参考,具体如下: package sweet.venst.act; import java....
    99+
    2022-06-06
    跑马灯 Android
  • 如何基于jQuery插件jqzoom实现的图片放大镜效果
    这篇文章主要介绍如何基于jQuery插件jqzoom实现的图片放大镜效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!jqzoom插件实现图片放大镜效果。图1.1jqzoom插件实现...
    99+
    2024-04-02
  • 基于JS实现点击图片在弹出层显示大图效果
    Javascript是个好东西。 Jquery是基于这个好东西的一个强大的库。 今天要实现的功能是基于这两个玩意儿的。 点击图片,在弹出层显示原图。 大概效果是这样的: 上代码: ...
    99+
    2022-11-13
    JS弹出层显示大图 JS 显示大图 JS 大图
  • 基于Unity3D如何实现3D照片墙效果
    这篇文章主要介绍了基于Unity3D如何实现3D照片墙效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、前言Unity3D不仅仅可以开发游戏,还有非常多的开发方向,秉承着...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作