vue弹幕实现不重叠
实现 Vue 弹幕不重叠的方法
CSS 定位与动画控制 通过绝对定位和动态计算弹幕轨道高度,确保弹幕在不同轨道上运行。每条弹幕占据固定高度的轨道,避免重叠。
// 弹幕轨道高度计算
const trackHeight = 30;
const tracks = Math.floor(containerHeight / trackHeight);
随机轨道分配 弹幕发射时随机分配空闲轨道,若当前轨道被占用则选择下一可用轨道。通过数组记录轨道占用状态。

function getAvailableTrack() {
for (let i = 0; i < tracks; i++) {
if (!occupiedTracks[i]) {
occupiedTracks[i] = true;
return i;
}
}
return -1; // 无可用轨道时处理
}
碰撞检测算法 使用矩形碰撞检测判断弹幕位置,动态调整新弹幕的发射时间或轨道。通过弹幕宽度和速度计算碰撞可能性。
function checkCollision(barrage, track) {
const existing = activeBarrages.filter(b => b.track === track);
return existing.some(b => {
const distance = b.speed * (Date.now() - b.startTime);
return distance < containerWidth + barrage.width;
});
}
动态速度调整 根据弹幕密度自动调整速度,高密度时加快速度减少重叠概率。可设置不同速度档位对应不同轨道数量。

const speedLevels = [3, 4, 5]; // px/ms
const currentSpeed = speedLevels[Math.floor(activeBarrages.length / 10)];
可视区域外缓冲 在容器外设置缓冲区存放待显示弹幕,通过IntersectionObserver API监测可视区域,动态加载弹幕。
<div class="barrage-buffer" ref="buffer"></div>
性能优化建议 使用虚拟滚动技术,对不可见弹幕进行DOM回收。限制同时显示的弹幕数量,超过阈值时进入队列等待。
const MAX_BARRAGES = 50;
if (activeBarrages.length >= MAX_BARRAGES) {
queue.push(newBarrage);
}
完整示例组件结构
<template>
<div class="barrage-container" ref="container">
<div
v-for="(item, index) in activeBarrages"
:key="index"
class="barrage-item"
:style="{
top: `${item.track * trackHeight}px`,
animation: `move ${item.duration}s linear`
}"
>
{{ item.text }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
trackHeight: 30,
occupiedTracks: [],
activeBarrages: [],
queue: []
}
},
mounted() {
this.initTracks();
this.startEmitter();
},
methods: {
initTracks() {
const containerHeight = this.$refs.container.clientHeight;
this.tracks = Math.floor(containerHeight / this.trackHeight);
this.occupiedTracks = new Array(this.tracks).fill(false);
},
emitBarrage(text) {
const track = this.getAvailableTrack();
if (track >= 0) {
this.activeBarrages.push({
text,
track,
duration: this.calcDuration(),
startTime: Date.now()
});
setTimeout(() => {
this.occupiedTracks[track] = false;
}, this.duration * 1000);
} else {
this.queue.push(text);
}
}
}
}
</script>
<style>
.barrage-container {
position: relative;
height: 300px;
overflow: hidden;
}
.barrage-item {
position: absolute;
white-space: nowrap;
animation-fill-mode: forwards;
}
@keyframes move {
from { transform: translateX(100%); }
to { transform: translateX(-100%); }
}
</style>
关键参数调优建议
- 轨道高度建议30-40px,平衡显示密度与可读性
- 动画时长控制在5-15秒区间,根据内容长度动态计算
- 碰撞检测间隔设置为200-300ms,平衡性能与精确度
- 缓冲区大小建议为可视区域的2-3倍宽度






