vue实现弹幕效果
实现弹幕效果的基本思路
在Vue中实现弹幕效果,通常需要创建多个动态移动的DOM元素,这些元素从屏幕右侧进入,向左移动直至完全离开屏幕。可以通过CSS动画或JavaScript控制元素的位置变化。
使用CSS动画实现弹幕
通过CSS的@keyframes定义弹幕的移动动画,结合Vue的动态渲染能力生成弹幕元素。

<template>
<div class="danmu-container">
<div
v-for="(item, index) in danmuList"
:key="index"
class="danmu-item"
:style="{ top: item.top + 'px' }"
>
{{ item.text }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
danmuList: []
};
},
mounted() {
setInterval(this.addDanmu, 1000);
},
methods: {
addDanmu() {
const text = '弹幕内容' + Math.random().toString(36).substr(2);
const top = Math.random() * 300;
this.danmuList.push({ text, top });
setTimeout(() => {
this.danmuList.shift();
}, 5000);
}
}
};
</script>
<style>
.danmu-container {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
border: 1px solid #ccc;
}
.danmu-item {
position: absolute;
white-space: nowrap;
animation: danmuMove 5s linear;
}
@keyframes danmuMove {
from {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
</style>
使用JavaScript控制弹幕位置
如果不使用CSS动画,可以通过requestAnimationFrame或setInterval动态计算弹幕位置。

<template>
<div class="danmu-container" ref="container">
<div
v-for="(item, index) in danmuList"
:key="index"
class="danmu-item"
:style="{
top: item.top + 'px',
left: item.left + 'px'
}"
>
{{ item.text }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
danmuList: [],
containerWidth: 0
};
},
mounted() {
this.containerWidth = this.$refs.container.offsetWidth;
setInterval(this.addDanmu, 1000);
requestAnimationFrame(this.updateDanmuPosition);
},
methods: {
addDanmu() {
const text = '弹幕内容' + Math.random().toString(36).substr(2);
const top = Math.random() * 300;
this.danmuList.push({
text,
top,
left: this.containerWidth,
speed: 2 + Math.random() * 3
});
},
updateDanmuPosition() {
this.danmuList.forEach(item => {
item.left -= item.speed;
});
this.danmuList = this.danmuList.filter(item => item.left > -100);
requestAnimationFrame(this.updateDanmuPosition);
}
}
};
</script>
<style>
.danmu-container {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
border: 1px solid #ccc;
}
.danmu-item {
position: absolute;
white-space: nowrap;
}
</style>
弹幕功能扩展
在实际项目中,弹幕功能可能需要更多扩展,比如用户输入弹幕、弹幕颜色设置、弹幕碰撞检测等。
<template>
<div>
<input v-model="inputText" @keyup.enter="sendDanmu" />
<div class="danmu-container" ref="container">
<div
v-for="(item, index) in danmuList"
:key="index"
class="danmu-item"
:style="{
top: item.top + 'px',
left: item.left + 'px',
color: item.color
}"
>
{{ item.text }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
inputText: '',
danmuList: [],
containerWidth: 0,
colors: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff']
};
},
mounted() {
this.containerWidth = this.$refs.container.offsetWidth;
requestAnimationFrame(this.updateDanmuPosition);
},
methods: {
sendDanmu() {
if (!this.inputText.trim()) return;
const color = this.colors[Math.floor(Math.random() * this.colors.length)];
const top = Math.random() * 300;
this.danmuList.push({
text: this.inputText,
top,
left: this.containerWidth,
speed: 2 + Math.random() * 3,
color
});
this.inputText = '';
},
updateDanmuPosition() {
this.danmuList.forEach(item => {
item.left -= item.speed;
});
this.danmuList = this.danmuList.filter(item => item.left > -100);
requestAnimationFrame(this.updateDanmuPosition);
}
}
};
</script>
性能优化建议
对于大量弹幕的情况,需要考虑性能优化。可以使用虚拟滚动技术,只渲染可见区域内的弹幕,或者使用Canvas渲染代替DOM操作。
// 使用Canvas渲染弹幕的示例方法
renderDanmu() {
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.danmuList.forEach(item => {
ctx.fillStyle = item.color;
ctx.font = '16px Arial';
ctx.fillText(item.text, item.left, item.top);
});
}
通过以上方法,可以在Vue中实现基本到高级的弹幕效果。根据项目需求选择合适的技术方案,CSS动画适合简单场景,JavaScript控制适合需要更复杂交互的情况,Canvas适合高性能要求的场景。






