当前位置:首页 > VUE

vue弹幕实现不重叠

2026-02-25 20:07:49VUE

实现 Vue 弹幕不重叠的核心思路

弹幕不重叠的关键在于动态计算每条弹幕的垂直位置,确保新弹幕与已有弹幕在运动轨迹上不发生碰撞。可以通过轨道管理、实时碰撞检测或固定轨道分配来实现。

基于轨道分配的实现方案

轨道预计算 将屏幕垂直方向划分为若干虚拟轨道,每条弹幕在固定轨道上运动。初始化时创建轨道状态数组,记录每个轨道是否被占用。

data() {
  return {
    tracks: 5, // 轨道数量
    trackStatus: Array(5).fill(false), // 轨道占用状态
    danmus: [] // 弹幕数据
  }
}

轨道分配算法 新弹幕生成时遍历轨道状态,找到第一个空闲轨道并标记为占用。弹幕离开屏幕后释放轨道。

methods: {
  addDanmu(text) {
    const trackIndex = this.trackStatus.findIndex(used => !used)
    if (trackIndex === -1) return // 无可用轨道

    this.trackStatus[trackIndex] = true
    this.danmus.push({
      text,
      track: trackIndex,
      left: '100%',
      id: Date.now()
    })
  },

  releaseTrack(trackIndex) {
    this.trackStatus[trackIndex] = false
  }
}

CSS 轨道定位 通过计算轨道位置确定弹幕的 top 值,使用 CSS 动画控制水平移动。

.danmu-item {
  position: absolute;
  white-space: nowrap;
  animation: move linear;
}

@keyframes move {
  from { transform: translateX(100%); }
  to { transform: translateX(-100%); }
}

基于动态碰撞检测的实现方案

实时位置检测 记录所有活跃弹幕的当前水平位置和宽度,新弹幕生成时计算垂直位置避免重叠。

checkCollision(newDanmu) {
  const newWidth = this.calculateWidth(newDanmu.text)
  return this.activeDanmus.some(danmu => {
    return danmu.top === newDanmu.top && 
           danmu.left + danmu.width > newDanmu.left
  })
}

动态定位调整 未找到合适位置时可延迟生成或调整弹幕速度,确保不会与现有弹幕冲突。

findAvailableTop() {
  let top = 0
  while (top < maxHeight) {
    if (!this.checkCollision({ top, left: screenWidth })) {
      return top
    }
    top += rowHeight
  }
  return null
}

性能优化建议

  • 使用 requestAnimationFrame 替代 CSS 动画实现更精确控制
  • 对弹幕文本进行宽度预计算,避免频繁 DOM 操作
  • 设置合理的轨道数量和弹幕速度,平衡视觉效果和性能
  • 对于大量弹幕考虑虚拟滚动技术,只渲染可视区域内元素

完整示例组件

<template>
  <div class="danmu-container">
    <div 
      v-for="danmu in activeDanmus" 
      :key="danmu.id"
      class="danmu-item"
      :style="{
        top: `${danmu.track * 30}px`,
        color: danmu.color
      }"
    >
      {{ danmu.text }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tracks: 8,
      trackStatus: Array(8).fill(false),
      activeDanmus: []
    }
  },
  methods: {
    addDanmu(text, color = '#fff') {
      const track = this.findAvailableTrack()
      if (track === null) return

      const id = Date.now()
      this.activeDanmus.push({
        id,
        text,
        color,
        track
      })

      setTimeout(() => {
        this.releaseTrack(track)
        this.activeDanmus = this.activeDanmus.filter(d => d.id !== id)
      }, 10000)
    },

    findAvailableTrack() {
      return this.trackStatus.findIndex(used => !used)
    },

    releaseTrack(track) {
      this.trackStatus[track] = false
    }
  }
}
</script>

<style>
.danmu-container {
  position: relative;
  height: 240px;
  overflow: hidden;
}

.danmu-item {
  position: absolute;
  left: 100%;
  white-space: nowrap;
  animation: danmu-move 10s linear;
}

@keyframes danmu-move {
  to { transform: translateX(-100vw); }
}
</style>

vue弹幕实现不重叠

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

相关文章

vue实现横向导航

vue实现横向导航

vue实现横向导航的方法 使用Flex布局实现横向导航 在Vue中可以通过Flex布局快速实现横向导航。创建一个组件,使用display: flex和flex-direction: row属性使导航项…

vue 实现菜单

vue 实现菜单

Vue 实现菜单的方法 使用 Vue 实现菜单可以通过多种方式,以下是几种常见的方法: 使用 Vue Router 实现动态路由菜单 通过 Vue Router 可以动态生成菜单,根据路由配置自动渲…

vue页面实现

vue页面实现

Vue 页面实现方法 创建 Vue 组件 使用 Vue 单文件组件(SFC)方式创建页面,文件扩展名为 .vue。一个基本的 Vue 组件包含三个部分:模板(template)、脚本(script)和…

vue实现画图

vue实现画图

Vue 实现画图功能 在 Vue 中实现画图功能通常需要结合 HTML5 的 <canvas> 元素或第三方库。以下是几种常见的方法: 使用原生 Canvas API 通过 Vue 直接…

vue实现异步

vue实现异步

Vue 实现异步操作的常见方法 Vue 提供了多种方式来处理异步操作,包括数据获取、事件处理等场景。 使用 async/await 在 Vue 方法中可以直接使用 async/await 语法处理异…

vue 实现表单

vue 实现表单

Vue 表单实现方法 Vue.js 提供了多种方式实现表单,包括双向数据绑定、表单验证和动态表单生成。以下是常见的实现方法: 基础表单绑定 使用 v-model 指令实现表单元素与数据的双向绑定:…