vue实现弹幕
Vue 实现弹幕功能
弹幕功能的实现可以分为几个关键部分:弹幕数据的生成、弹幕的渲染、弹幕的动画控制以及用户交互。
弹幕数据管理
弹幕数据通常是一个数组,每个元素包含弹幕内容、颜色、速度、位置等信息。可以使用 Vue 的 data 或 ref 来管理弹幕数据。
data() {
return {
danmuList: [],
colors: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff'],
speeds: [5, 6, 7, 8, 9],
}
}
弹幕生成
弹幕可以通过用户输入或自动生成。可以使用 setInterval 定时生成弹幕,或通过事件触发。

methods: {
addDanmu(text) {
const danmu = {
id: Date.now(),
text,
color: this.colors[Math.floor(Math.random() * this.colors.length)],
speed: this.speeds[Math.floor(Math.random() * this.speeds.length)],
top: Math.floor(Math.random() * 100),
}
this.danmuList.push(danmu)
}
}
弹幕渲染
使用 Vue 的 v-for 指令渲染弹幕列表,并通过 CSS 控制弹幕的样式和位置。
<template>
<div class="danmu-container">
<div
v-for="danmu in danmuList"
:key="danmu.id"
class="danmu-item"
:style="{
color: danmu.color,
top: `${danmu.top}%`,
animationDuration: `${10 - danmu.speed}s`,
}"
>
{{ danmu.text }}
</div>
</div>
</template>
弹幕动画
通过 CSS 动画实现弹幕的移动效果。弹幕从右向左移动,可以通过 transform 或 left 属性控制。

.danmu-container {
position: relative;
width: 100%;
height: 300px;
overflow: hidden;
}
.danmu-item {
position: absolute;
white-space: nowrap;
animation: move linear;
}
@keyframes move {
from {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
用户交互
可以通过输入框让用户发送弹幕,并监听回车事件触发弹幕生成。
<input
v-model="inputText"
@keyup.enter="addDanmu(inputText)"
placeholder="输入弹幕内容"
/>
弹幕清理
弹幕移出屏幕后需要清理,避免内存泄漏。可以通过监听动画结束事件移除弹幕。
methods: {
handleAnimationEnd(id) {
this.danmuList = this.danmuList.filter(danmu => danmu.id !== id)
}
}
<div
v-for="danmu in danmuList"
:key="danmu.id"
class="danmu-item"
@animationend="handleAnimationEnd(danmu.id)"
>
{{ danmu.text }}
</div>
完整示例代码
<template>
<div>
<input
v-model="inputText"
@keyup.enter="addDanmu(inputText)"
placeholder="输入弹幕内容"
/>
<div class="danmu-container">
<div
v-for="danmu in danmuList"
:key="danmu.id"
class="danmu-item"
:style="{
color: danmu.color,
top: `${danmu.top}%`,
animationDuration: `${10 - danmu.speed}s`,
}"
@animationend="handleAnimationEnd(danmu.id)"
>
{{ danmu.text }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
inputText: '',
danmuList: [],
colors: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff'],
speeds: [5, 6, 7, 8, 9],
}
},
methods: {
addDanmu(text) {
const danmu = {
id: Date.now(),
text,
color: this.colors[Math.floor(Math.random() * this.colors.length)],
speed: this.speeds[Math.floor(Math.random() * this.speeds.length)],
top: Math.floor(Math.random() * 100),
}
this.danmuList.push(danmu)
},
handleAnimationEnd(id) {
this.danmuList = this.danmuList.filter(danmu => danmu.id !== id)
},
},
}
</script>
<style>
.danmu-container {
position: relative;
width: 100%;
height: 300px;
overflow: hidden;
background: #f0f0f0;
}
.danmu-item {
position: absolute;
white-space: nowrap;
animation: move linear;
}
@keyframes move {
from {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
</style>
优化建议
- 性能优化:对于大量弹幕,可以使用虚拟滚动技术减少 DOM 数量。
- 碰撞检测:避免弹幕重叠,可以动态调整弹幕的垂直位置。
- 暂停与恢复:通过控制 CSS 动画的
animation-play-state实现弹幕的暂停和恢复功能。






