当前位置:首页 > 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 element实现

vue element实现

Vue Element UI 实现 Vue Element UI 是基于 Vue.js 的组件库,提供丰富的 UI 组件,适合快速开发企业级中后台产品。以下是一些关键实现方法和步骤: 安装 Vue…

vue滚动实现

vue滚动实现

Vue 滚动实现方法 使用原生滚动 在 Vue 中可以通过 ref 获取 DOM 元素,调用原生滚动方法实现滚动效果。适用于简单场景。 <template> <div ref=…

vue实现selectable

vue实现selectable

Vue 实现可选择的 Select 组件 在 Vue 中实现一个可选择的 Select 组件,可以通过以下几种方式: 使用原生 HTML select 元素 <template> &…

vue 实现评分

vue 实现评分

Vue 实现评分功能 在 Vue 中实现评分功能可以通过多种方式完成,包括使用第三方组件库或自定义实现。以下是两种常见的方法: 使用第三方组件库(如 Element UI) Element UI 提…

vue最佳实现

vue最佳实现

Vue 最佳实践 组件设计 组件应遵循单一职责原则,每个组件只负责一个功能模块。命名采用 PascalCase(如 UserProfile.vue),模板中使用 kebab-case(如 <us…

vue实现反馈

vue实现反馈

Vue 实现反馈功能的方法 在 Vue 中实现反馈功能可以通过多种方式,包括弹窗提示、Toast 消息、表单提交等。以下是几种常见的实现方法。 弹窗反馈 使用 Vue 的组件化特性创建一个弹窗组件,…