当前位置:首页 > VUE

vue弹幕实现不重叠

2026-01-12 02:04:36VUE

vue弹幕实现不重叠的方法

使用CSS定位和动态计算

通过动态计算每条弹幕的垂直位置,确保新弹幕不会与现有弹幕重叠。利用position: absolutetop属性控制每条弹幕的显示位置。

data() {
  return {
    danmuList: [],
    occupiedLines: new Set()
  }
},
methods: {
  addDanmu(text) {
    const lineHeight = 30; // 每行弹幕高度
    const maxLines = Math.floor(this.$el.clientHeight / lineHeight);

    let line = 0;
    while (line < maxLines && this.occupiedLines.has(line)) {
      line++;
    }

    if (line < maxLines) {
      this.occupiedLines.add(line);
      this.danmuList.push({
        text,
        top: line * lineHeight,
        id: Date.now()
      });

      setTimeout(() => {
        this.occupiedLines.delete(line);
        this.danmuList = this.danmuList.filter(item => item.id !== id);
      }, duration);
    }
  }
}

轨道系统实现

预先划分多条轨道,每条轨道同一时间只允许存在一条弹幕。通过维护轨道状态来避免重叠。

vue弹幕实现不重叠

data() {
  return {
    tracks: Array(5).fill(null), // 5条轨道
    danmus: []
  }
},
methods: {
  launchDanmu(text) {
    const availableTrack = this.tracks.findIndex(track => track === null);
    if (availableTrack !== -1) {
      this.tracks[availableTrack] = text;
      this.danmus.push({
        text,
        track: availableTrack,
        id: Date.now()
      });

      setTimeout(() => {
        this.tracks[availableTrack] = null;
      }, 3000);
    }
  }
}

碰撞检测算法

实现更精确的碰撞检测,计算每条弹幕的实时位置和宽度,确保新弹幕不会与运动中的弹幕重叠。

vue弹幕实现不重叠

checkCollision(newDanmu) {
  const newWidth = this.calculateTextWidth(newDanmu.text);
  return this.danmuList.some(danmu => {
    const currentWidth = this.calculateTextWidth(danmu.text);
    return (
      danmu.top === newDanmu.top &&
      Math.abs(danmu.left - newDanmu.left) < (currentWidth + newWidth) / 2
    );
  });
}

使用Web Workers处理计算

对于大量弹幕场景,可以将碰撞检测等计算密集型任务放到Web Worker中处理,避免阻塞主线程。

// worker.js
self.onmessage = function(e) {
  const { danmus, newDanmu } = e.data;
  const collision = /* 碰撞检测逻辑 */;
  postMessage(collision);
};

// Vue组件中
const worker = new Worker('worker.js');
worker.postMessage({ danmus: this.danmus, newDanmu });
worker.onmessage = (e) => {
  if (!e.data.collision) {
    this.addDanmu(newDanmu);
  }
};

第三方库解决方案

考虑使用成熟的弹幕库如rc-bulletsdanmaku,这些库已经实现了完善的防重叠机制。

import Danmaku from 'danmaku';
const danmaku = new Danmaku({
  container: document.getElementById('danmu-container'),
  engine: 'canvas',
  speed: 120,
  preventOverlap: true
});

注意事项

弹幕防重叠实现需要考虑性能问题,特别是在弹幕数量较多时。可以根据实际需求选择合适的方案,简单的轨道系统适合大多数场景,而需要精确防重叠时可采用碰撞检测算法。

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

相关文章

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { letters…

vue权限实现

vue权限实现

Vue 权限实现方案 基于路由的权限控制 通过路由守卫实现权限验证,在路由配置中添加meta字段标记权限要求。在router.beforeEach中检查用户权限与路由要求的匹配情况。 // rout…

vue router 实现

vue router 实现

Vue Router 的实现 Vue Router 是 Vue.js 的官方路由管理器,用于构建单页面应用(SPA)。以下是 Vue Router 的核心实现方式。 安装 Vue Router 通过…

vue实现长按

vue实现长按

Vue 实现长按功能的方法 在 Vue 中实现长按功能可以通过原生事件监听或自定义指令完成。以下是几种常见实现方式: 使用原生事件监听 通过 @mousedown 和 @mouseup 或 @tou…

vue实现list

vue实现list

Vue 实现列表渲染 在 Vue 中,可以使用 v-for 指令来渲染列表。v-for 指令基于一个数组或对象来渲染一个列表,可以遍历数组或对象的属性。 基本列表渲染 <template>…

vue实现tree

vue实现tree

Vue 实现 Tree 组件 使用 Vue 实现 Tree 组件可以通过递归组件的方式来实现层级结构展示。以下是一个完整的实现方法: 基础递归组件实现 创建 Tree 组件文件 Tree.vue,使…