当前位置:首页 > VUE

vue 实现弹幕js

2026-03-10 12:34:14VUE

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

vue 实现弹幕js

基于CSS动画的实现

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

vue 实现弹幕js

<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操作:

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 实现pc

vue 实现pc

Vue 实现 PC 端应用的核心要点 Vue.js 是一个渐进式框架,适合构建 PC 端单页应用(SPA)或复杂的前端界面。以下是实现 PC 端应用的关键方法和注意事项: 项目初始化与工程化配置 使…

vue实现rtc

vue实现rtc

Vue 实现 RTC 的步骤 安装依赖 在 Vue 项目中安装 WebRTC 相关依赖,如 simple-peer 或 peerjs,用于简化 WebRTC 的实现。 运行以下命令安装 simple-…

vue实现节流

vue实现节流

vue实现节流的方法 在Vue中实现节流(throttle)功能,通常用于限制高频事件的触发频率,例如滚动、输入或按钮点击。以下是几种常见的实现方式: 使用Lodash的throttle函数 安装L…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

vue实现pwa

vue实现pwa

Vue 实现 PWA 的步骤 Vue 结合 PWA(Progressive Web App)可以创建离线可用的 Web 应用。以下是实现方法: 安装 Vue CLI 并创建项目 确保已安装 Vue…

vue 实现loading

vue 实现loading

Vue 实现 Loading 的方法 使用 v-if 和 v-show 控制显示 在 Vue 中可以通过 v-if 或 v-show 控制 loading 组件的显示与隐藏。v-if 会动态创建或销毁…