当前位置:首页 > VUE

vue 实现弹幕js

2026-03-10 12:34:14VUE

在Vue中实现弹幕功能,可以通过动态渲染DOM元素并结合CSS动画或JavaScript定时器实现。以下是两种常见的实现方法:

基于CSS动画的实现

创建一个弹幕组件,利用CSS的@keyframes实现横向移动效果:

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

<script>
export default {
  data() {
    return {
      danmuList: []
    }
  },
  methods: {
    addDanmu(text) {
      const height = 30 // 每条弹幕高度
      const top = Math.floor(Math.random() * (300 - height)) // 随机位置
      const duration = 5 + Math.random() * 5 // 随机速度

      this.danmuList.push({ text, top, duration })

      // 动画结束后移除
      setTimeout(() => {
        this.danmuList.shift()
      }, duration * 1000)
    }
  }
}
</script>

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

.danmu-item {
  position: absolute;
  white-space: nowrap;
  animation: danmuMove linear;
  color: #fff;
  text-shadow: 1px 1px 2px #000;
}

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

基于JavaScript定时器的实现

使用requestAnimationFrame实现更精确的弹幕控制:

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

<script>
export default {
  data() {
    return {
      danmuQueue: [],
      activeDanmu: [],
      animationId: null
    }
  },
  mounted() {
    this.startAnimation()
  },
  beforeDestroy() {
    cancelAnimationFrame(this.animationId)
  },
  methods: {
    addDanmu(text) {
      const height = 30
      const top = Math.floor(Math.random() * (300 - height))
      const speed = 2 + Math.random() * 3

      this.danmuQueue.push({
        text,
        top,
        speed,
        left: this.$refs.container.offsetWidth,
        width: this.calculateTextWidth(text)
      })
    },

    calculateTextWidth(text) {
      const span = document.createElement('span')
      span.style.visibility = 'hidden'
      span.style.whiteSpace = 'nowrap'
      span.innerText = text
      document.body.appendChild(span)
      const width = span.offsetWidth
      document.body.removeChild(span)
      return width
    },

    startAnimation() {
      const animate = () => {
        // 处理队列中的新弹幕
        if (this.danmuQueue.length > 0) {
          this.activeDanmu.push(...this.danmuQueue)
          this.danmuQueue = []
        }

        // 更新所有活跃弹幕位置
        this.activeDanmu = this.activeDanmu.map(item => {
          return {
            ...item,
            left: item.left - item.speed
          }
        }).filter(item => item.left + item.width > 0)

        this.animationId = requestAnimationFrame(animate)
      }

      animate()
    }
  }
}
</script>

性能优化建议

对于大量弹幕场景,考虑使用Canvas渲染代替DOM操作:

vue 实现弹幕js

export default {
  mounted() {
    this.initCanvas()
    this.startDraw()
  },
  methods: {
    initCanvas() {
      this.canvas = this.$refs.canvas
      this.ctx = this.canvas.getContext('2d')
      this.canvas.width = this.canvas.offsetWidth
      this.canvas.height = this.canvas.offsetHeight
    },

    drawDanmu() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)

      this.activeDanmu.forEach(item => {
        this.ctx.fillStyle = item.color || '#fff'
        this.ctx.font = '16px sans-serif'
        this.ctx.fillText(item.text, item.x, item.y)
        item.x -= item.speed
      })

      this.activeDanmu = this.activeDanmu.filter(item => item.x + item.width > 0)
    },

    startDraw() {
      const animate = () => {
        this.drawDanmu()
        this.animationId = requestAnimationFrame(animate)
      }
      animate()
    }
  }
}

功能扩展方向

  1. 弹幕碰撞检测:计算每条弹幕的宽度和位置,避免重叠
  2. 弹幕样式自定义:支持颜色、大小、字体等样式配置
  3. 弹幕互动:实现点击暂停、屏蔽特定用户弹幕等功能
  4. 弹幕池管理:控制同时显示的弹幕数量,避免性能问题

以上实现可以根据具体需求调整参数,如弹幕速度、出现频率、显示区域等。Canvas版本性能更好但实现复杂度较高,DOM版本更易扩展样式和交互功能。

标签: 弹幕vue
分享给朋友:

相关文章

vue实现倒计时抢券

vue实现倒计时抢券

Vue 实现倒计时抢券功能 核心逻辑 倒计时抢券功能需要结合时间计算、状态管理和界面交互。通过 Vue 的响应式特性和生命周期钩子,可以高效实现这一需求。 实现步骤 1. 数据准备 在 Vue 组件…

vue实现groupbox

vue实现groupbox

Vue 实现 GroupBox 组件 在 Vue 中实现类似 GroupBox 的效果可以通过自定义组件完成。GroupBox 通常是一个带有标题的边框容器,用于将相关控件分组显示。 基本实现方法…

vue实现弹幕

vue实现弹幕

Vue 实现弹幕功能 弹幕功能通常包括动态生成、滚动显示、颜色和速度随机化等特性。以下是基于 Vue 3 的实现方法。 核心思路 使用 CSS 动画控制弹幕从右向左滚动。 动态生成弹幕数据,随机设置…

vue 实现折叠

vue 实现折叠

Vue 实现折叠功能的方法 在 Vue 中实现折叠功能可以通过多种方式完成,以下是几种常见的实现方法: 使用 v-if 或 v-show 控制显示隐藏 通过绑定一个布尔值变量,结合 v-if 或 v…

vue实现select

vue实现select

Vue 实现 Select 组件的方法 在 Vue 中实现 Select 组件可以通过多种方式完成,以下是几种常见的方法: 使用原生 HTML select 元素 原生 HTML 的 <sel…

vue watch实现

vue watch实现

在 Vue 中实现 watch 监听数据变化 Vue 的 watch 选项用于监听数据变化并执行相应的回调函数。以下是几种常见的实现方式: 基础用法 export default { data(…