当前位置:首页 > VUE

vue实现点击红包雨

2026-01-12 01:56:03VUE

Vue 实现点击红包雨效果

实现红包雨效果需要结合 Vue 的响应式数据绑定和动画效果。以下是具体实现方法:

创建红包组件

定义一个红包组件,包含红包图片和点击事件处理逻辑。可以使用 v-for 动态生成多个红包。

<template>
  <div 
    class="red-packet" 
    v-for="(packet, index) in packets" 
    :key="index"
    :style="{
      left: packet.left + 'px',
      top: packet.top + 'px',
      animation: `fall ${packet.duration}s linear infinite`
    }"
    @click="collectPacket(index)"
  >
    <img src="@/assets/red-packet.png" alt="红包">
  </div>
</template>

<script>
export default {
  data() {
    return {
      packets: []
    }
  },
  methods: {
    collectPacket(index) {
      this.packets.splice(index, 1)
      // 处理收集红包逻辑
    }
  }
}
</script>

添加红包雨动画

使用 CSS 动画实现红包下落效果。定义 fall 动画让红包从顶部移动到底部。

.red-packet {
  position: absolute;
  width: 50px;
  height: 60px;
  cursor: pointer;
  z-index: 100;
}

@keyframes fall {
  from {
    transform: translateY(-100px);
  }
  to {
    transform: translateY(100vh);
  }
}

控制红包生成

在 Vue 组件中设置定时器,定期生成新的红包并随机设置位置和下落速度。

export default {
  mounted() {
    this.startRain()
  },
  methods: {
    startRain() {
      setInterval(() => {
        if (this.packets.length < 20) { // 控制最大红包数量
          this.packets.push({
            left: Math.random() * window.innerWidth,
            top: -60,
            duration: 3 + Math.random() * 5 // 随机下落速度
          })
        }
      }, 300) // 每300毫秒生成一个红包
    }
  }
}

优化性能

对于大量红包元素,可以使用 Vue 的 v-show 替代 v-if 减少 DOM 操作,或者使用虚拟滚动技术优化性能。

<template>
  <div 
    class="red-packet" 
    v-for="(packet, index) in packets" 
    :key="index"
    v-show="packet.visible"
  >
    <!-- 红包内容 -->
  </div>
</template>

添加点击效果

为增强用户体验,可以在点击红包时添加动画效果或音效。

methods: {
  collectPacket(index) {
    this.packets[index].visible = false
    // 播放收集音效
    const audio = new Audio('collect-sound.mp3')
    audio.play()
    // 显示收集动画
    this.showCollectionEffect(this.packets[index])
  }
}

响应式调整

监听窗口大小变化,调整红包位置和动画参数。

mounted() {
  window.addEventListener('resize', this.adjustPackets)
},
beforeDestroy() {
  window.removeEventListener('resize', this.adjustPackets)
},
methods: {
  adjustPackets() {
    this.packets = this.packets.map(packet => ({
      ...packet,
      left: Math.random() * window.innerWidth
    }))
  }
}

完整示例

<template>
  <div class="red-packet-container">
    <div 
      class="red-packet" 
      v-for="(packet, index) in packets" 
      :key="index"
      :style="packetStyle(packet)"
      @click="collectPacket(index)"
    >
      <img src="@/assets/red-packet.png" alt="红包">
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      packets: [],
      maxPackets: 20
    }
  },
  mounted() {
    this.startRain()
    window.addEventListener('resize', this.adjustPackets)
  },
  beforeDestroy() {
    clearInterval(this.rainInterval)
    window.removeEventListener('resize', this.adjustPackets)
  },
  methods: {
    packetStyle(packet) {
      return {
        left: packet.left + 'px',
        top: packet.top + 'px',
        animation: `fall ${packet.duration}s linear infinite`,
        opacity: packet.visible ? 1 : 0
      }
    },
    startRain() {
      this.rainInterval = setInterval(() => {
        if (this.packets.length < this.maxPackets) {
          this.packets.push({
            left: Math.random() * window.innerWidth,
            top: -60,
            duration: 3 + Math.random() * 5,
            visible: true
          })
        }
      }, 300)
    },
    collectPacket(index) {
      this.packets[index].visible = false
      setTimeout(() => {
        this.packets.splice(index, 1)
      }, 500)
    },
    adjustPackets() {
      this.packets = this.packets.map(packet => ({
        ...packet,
        left: Math.min(packet.left, window.innerWidth - 50)
      }))
    }
  }
}
</script>

<style>
.red-packet-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

.red-packet {
  position: absolute;
  width: 50px;
  height: 60px;
  cursor: pointer;
  z-index: 100;
  transition: opacity 0.3s;
}

@keyframes fall {
  from {
    transform: translateY(-100px);
  }
  to {
    transform: translateY(100vh);
  }
}
</style>

vue实现点击红包雨

标签: 红包vue
分享给朋友:

相关文章

vue实现sql操作

vue实现sql操作

在Vue中实现SQL操作通常需要结合后端服务或本地数据库技术,因为前端JavaScript无法直接连接SQL数据库。以下是几种常见的实现方式: 通过API与后端交互 Vue前端通过HTTP请求(如…

vue优秀实现

vue优秀实现

Vue.js 优秀实现方法 响应式数据管理 使用 Vue 的 ref 和 reactive 处理基础类型和对象类型数据,结合 computed 计算属性优化渲染性能。对于复杂状态,推荐 Pinia 替…

vue实现公告

vue实现公告

Vue 实现公告功能的方法 公告功能通常需要实现滚动展示、自动切换或固定显示的效果。以下是几种常见的实现方式: 使用 marquee 标签实现滚动公告 <template> <…

vue实现素材

vue实现素材

Vue 实现素材的方法 使用 Vue 组件管理素材 在 Vue 项目中,可以通过组件化的方式管理素材。创建一个专门的组件来加载和显示素材,例如图片、视频或音频文件。组件可以接收素材的路径或 URL 作…

vue el 实现

vue el 实现

Vue 中使用 Element UI (el) 的实现方法 Element UI 是一个基于 Vue 的组件库,提供丰富的 UI 组件,常用于快速构建企业级中后台产品。以下介绍 Vue 项目中集成和使…

vue原理实现

vue原理实现

Vue 原理实现的核心机制 Vue.js 的核心原理基于响应式系统、虚拟 DOM 和模板编译。以下是其核心实现机制的分解: 响应式系统 Vue 使用 Object.defineProperty(V…