vue弹幕实现不重叠
vue弹幕实现不重叠的方法
使用CSS定位和动态计算
通过动态计算每条弹幕的垂直位置,确保新弹幕不会与现有弹幕重叠。利用position: absolute和top属性控制每条弹幕的显示位置。
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-bullets或danmaku,这些库已经实现了完善的防重叠机制。
import Danmaku from 'danmaku';
const danmaku = new Danmaku({
container: document.getElementById('danmu-container'),
engine: 'canvas',
speed: 120,
preventOverlap: true
});
注意事项
弹幕防重叠实现需要考虑性能问题,特别是在弹幕数量较多时。可以根据实际需求选择合适的方案,简单的轨道系统适合大多数场景,而需要精确防重叠时可采用碰撞检测算法。







