当前位置:首页 > 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);
    }
  }
}

轨道系统实现

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

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);
    }
  }
}

碰撞检测算法

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

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 实现动态菜单的常见方法 基于路由配置生成菜单 Vue Router 的路由配置可以天然转化为菜单结构,适合权限与路由绑定的系统: // router/index.js const rout…

vue如何实现放大缩小

vue如何实现放大缩小

Vue实现放大缩小功能的方法 在Vue中实现元素的放大缩小功能,可以通过CSS变换、第三方库或直接操作DOM样式来实现。以下是几种常见的方法: 使用CSS transform属性 通过绑定Vue的…

vue实现简单的弹窗

vue实现简单的弹窗

使用 Vue 实现简单弹窗 组件基础结构 创建一个名为 Modal.vue 的组件文件,包含模板、脚本和样式部分: <template> <div class="modal-…

vue实现查询替换

vue实现查询替换

Vue 实现查询替换功能 在 Vue 中实现查询替换功能,可以通过数据绑定和字符串操作方法结合实现。以下是具体实现方式: 基础实现 <template> <div>…

vue实现按钮组轮换

vue实现按钮组轮换

实现按钮组轮换的方法 在Vue中实现按钮组轮换效果可以通过动态绑定类和事件处理来完成。以下是一种常见的实现方式: 模板部分 <template> <div class="bu…

vue实现走势图

vue实现走势图

Vue 实现走势图的方法 使用 ECharts 库 ECharts 是一个强大的数据可视化库,支持多种图表类型,包括走势图(折线图)。在 Vue 项目中可以通过 vue-echarts 封装库或直接使…