当前位置:首页 > VUE

vue实现平缓弹幕

2026-01-08 04:42:04VUE

Vue实现平缓弹幕的方法

在Vue中实现平缓弹幕效果,可以通过CSS动画和Vue的动态渲染结合完成。以下是具体实现方式:

使用CSS动画控制弹幕移动

通过CSS的@keyframes定义弹幕从右到左的平移动画,结合Vue的v-for动态渲染弹幕列表。

<template>
  <div class="danmu-container">
    <div 
      v-for="(item, index) in danmuList" 
      :key="index" 
      class="danmu-item"
      :style="{ top: `${item.top}px`, animationDuration: `${item.speed}s` }"
    >
      {{ item.text }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      danmuList: []
    }
  },
  methods: {
    addDanmu(text) {
      const top = Math.random() * 200 // 随机高度
      const speed = 5 + Math.random() * 5 // 随机速度
      this.danmuList.push({ text, top, speed })
    }
  }
}
</script>

<style>
.danmu-container {
  position: relative;
  width: 100%;
  height: 300px;
  overflow: hidden;
}

.danmu-item {
  position: absolute;
  white-space: nowrap;
  animation: danmuMove linear;
  animation-fill-mode: forwards;
}

@keyframes danmuMove {
  from { transform: translateX(100%); }
  to { transform: translateX(-100%); }
}
</style>

使用requestAnimationFrame实现更流畅动画

对于性能要求较高的场景,可以使用JavaScript控制动画帧。

<template>
  <div class="danmu-container" ref="container">
    <div 
      v-for="(item, index) in danmuList" 
      :key="index" 
      class="danmu-item"
      :style="{ top: `${item.top}px`, left: `${item.left}px` }"
    >
      {{ item.text }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      danmuList: [],
      animationId: null
    }
  },
  mounted() {
    this.startAnimation()
  },
  beforeDestroy() {
    cancelAnimationFrame(this.animationId)
  },
  methods: {
    addDanmu(text) {
      const top = Math.random() * 200
      const speed = 1 + Math.random() * 3
      this.danmuList.push({ 
        text, 
        top, 
        speed, 
        left: this.$refs.container.offsetWidth 
      })
    },
    startAnimation() {
      const animate = () => {
        this.danmuList = this.danmuList.map(item => {
          return {
            ...item,
            left: item.left - item.speed
          }
        }).filter(item => item.left > -100)

        this.animationId = requestAnimationFrame(animate)
      }
      animate()
    }
  }
}
</script>

使用第三方库优化性能

对于复杂弹幕场景,可以考虑使用专门的动画库如GSAP:

import { gsap } from 'gsap'

methods: {
  addDanmuWithGSAP(text) {
    const top = Math.random() * 200
    const el = document.createElement('div')
    el.className = 'danmu-item'
    el.textContent = text
    el.style.top = `${top}px`
    this.$refs.container.appendChild(el)

    gsap.fromTo(el, 
      { x: this.$refs.container.offsetWidth },
      { 
        x: -el.offsetWidth,
        duration: 5,
        ease: 'none',
        onComplete: () => el.remove()
      }
    )
  }
}

弹幕碰撞检测实现

为避免弹幕重叠,可以实现简单的碰撞检测:

methods: {
  getSafeTop(existingItems) {
    const containerHeight = this.$refs.container.offsetHeight
    const itemHeight = 30 // 假设每条弹幕高度

    for(let y = 0; y < containerHeight - itemHeight; y += itemHeight + 10) {
      const isSafe = !existingItems.some(item => 
        Math.abs(item.top - y) < itemHeight + 10 && 
        item.left > -100
      )
      if(isSafe) return y
    }
    return Math.random() * containerHeight
  }
}

以上方法可根据实际需求选择或组合使用,CSS动画方案适合简单场景,requestAnimationFrame提供更精细控制,而GSAP等库则能处理复杂动画需求。

vue实现平缓弹幕

标签: 平缓弹幕
分享给朋友: