vue实现视频弹幕
实现思路
使用Vue实现视频弹幕功能,核心在于动态渲染弹幕元素并控制其移动。弹幕数据通常通过WebSocket或API实时获取,前端利用CSS动画或JavaScript定时器实现滚动效果。
基本实现步骤
安装依赖(可选)
如需使用WebSocket,可安装socket.io-client:
npm install socket.io-client
视频播放器与弹幕容器 在Vue组件中设置视频播放器和弹幕容器:
<template>
<div class="video-container">
<video ref="videoPlayer" controls width="800"></video>
<div class="danmu-container" ref="danmuContainer"></div>
</div>
</template>
样式设置 弹幕容器需绝对定位,覆盖在视频上方:
.video-container {
position: relative;
}
.danmu-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: hidden;
}
弹幕数据结构 定义弹幕数据格式:
data() {
return {
danmuList: [], // 弹幕数据 {text: '内容', color: '#fff', time: 5}
currentDanmu: [] // 当前正在显示的弹幕
}
}
弹幕渲染方法 使用CSS动画控制弹幕移动:
methods: {
addDanmu(danmu) {
const danmuEl = document.createElement('div')
danmuEl.textContent = danmu.text
danmuEl.style.color = danmu.color
danmuEl.classList.add('danmu-item')
// 随机设置弹幕轨道(顶部、中部、底部)
const track = Math.floor(Math.random() * 3)
danmuEl.style.top = `${20 + track * 30}%`
this.$refs.danmuContainer.appendChild(danmuEl)
// 触发动画
setTimeout(() => {
danmuEl.style.transform = `translateX(-100%)`
}, 10)
// 动画结束后移除元素
danmuEl.addEventListener('transitionend', () => {
danmuEl.remove()
})
}
}
弹幕动画CSS
.danmu-item {
position: absolute;
white-space: nowrap;
font-size: 20px;
text-shadow: 1px 1px 2px #000;
transition: transform 10s linear;
transform: translateX(100%);
}
实时弹幕处理 通过WebSocket或定时器获取新弹幕:
mounted() {
// 模拟WebSocket接收
setInterval(() => {
if (this.danmuList.length) {
this.addDanmu(this.danmuList.shift())
}
}, 500)
// 视频时间更新时发送对应时间点的弹幕
this.$refs.videoPlayer.addEventListener('timeupdate', () => {
const currentTime = this.$refs.videoPlayer.currentTime
// 筛选当前时间点的弹幕...
})
}
高级功能扩展
弹幕防遮挡 通过计算弹幕位置避免重叠:
checkCollision(danmuEl) {
const rect = danmuEl.getBoundingClientRect()
// 检测与其他弹幕元素的位置重叠...
}
弹幕互动
添加点击事件(需设置pointer-events: auto):
danmuEl.addEventListener('click', () => {
console.log('弹幕被点击')
})
弹幕过滤器 实现敏感词过滤或用户屏蔽:
filterDanmu(text) {
const bannedWords = ['敏感词1', '敏感词2']
return !bannedWords.some(word => text.includes(word))
}
性能优化 使用虚拟滚动技术处理大量弹幕:
// 只渲染可视区域内的弹幕
// 使用requestAnimationFrame优化动画
完整组件示例
<template>
<div class="video-danmu">
<video src="video.mp4" ref="video" controls></video>
<div class="danmu-stage" ref="stage"></div>
<div class="danmu-input">
<input v-model="inputText" @keyup.enter="sendDanmu" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
inputText: '',
danmuPool: []
}
},
methods: {
sendDanmu() {
if (!this.inputText.trim()) return
const newDanmu = {
text: this.inputText,
color: this.getRandomColor(),
time: this.$refs.video.currentTime
}
this.danmuPool.push(newDanmu)
this.inputText = ''
},
getRandomColor() {
return `#${Math.floor(Math.random()*16777215).toString(16)}`
}
}
}
</script>
注意事项
- 弹幕数量需做限制,避免性能问题
- 移动端需考虑触摸事件兼容性
- 视频全屏时需调整弹幕容器尺寸
- 对于长视频,可采用分段加载弹幕数据
以上实现可根据实际需求调整弹幕速度、样式、出现频率等参数。商业级应用还需考虑弹幕存储、用户认证、实时同步等后端支持。







