canvas加vue实现弹幕
使用Canvas与Vue实现弹幕功能
核心思路
- 数据驱动渲染:利用Vue的响应式特性管理弹幕数据
- Canvas绘制:通过Canvas API实现高性能的弹幕渲染
- 动画控制:使用requestAnimationFrame实现平滑动画
实现步骤
组件结构
<template>
<div class="danmu-container">
<canvas ref="canvas" :width="width" :height="height"></canvas>
</div>
</template>
数据定义
data() {
return {
width: 800,
height: 400,
danmus: [], // 弹幕数据
ctx: null, // canvas上下文
animationId: null,
colors: ['#ff0000', '#00ff00', '#0000ff', '#ffff00'] // 弹幕颜色
}
}
Canvas初始化
mounted() {
this.initCanvas()
this.startAnimation()
},
methods: {
initCanvas() {
const canvas = this.$refs.canvas
this.ctx = canvas.getContext('2d')
this.ctx.font = '24px Microsoft YaHei'
}
}
弹幕动画核心逻辑
startAnimation() {
const animate = () => {
this.clearCanvas()
this.updateDanmus()
this.drawDanmus()
this.animationId = requestAnimationFrame(animate)
}
animate()
},
clearCanvas() {
this.ctx.clearRect(0, 0, this.width, this.height)
},
updateDanmus() {
this.danmus.forEach(danmu => {
danmu.x -= danmu.speed
if (danmu.x + danmu.width < 0) {
danmu.x = this.width
}
})
},
drawDanmus() {
this.danmus.forEach(danmu => {
this.ctx.fillStyle = danmu.color
this.ctx.fillText(danmu.text, danmu.x, danmu.y)
})
}
添加新弹幕
addDanmu(text) {
const y = Math.floor(Math.random() * (this.height - 30)) + 30
const color = this.colors[Math.floor(Math.random() * this.colors.length)]
const speed = Math.random() * 2 + 1
this.ctx.font = '24px Microsoft YaHei'
const width = this.ctx.measureText(text).width
this.danmus.push({
text,
x: this.width,
y,
color,
speed,
width
})
}
性能优化建议
- 对象池技术:复用弹幕对象减少GC压力
- 分层渲染:将静态和动态元素分开渲染
- 节流控制:限制弹幕发射频率
样式调整
.danmu-container {
position: relative;
background-color: #000;
overflow: hidden;
}
canvas {
display: block;
}
使用示例
// 在组件中调用
this.addDanmu('这是一条测试弹幕')
注意事项
- 组件销毁时需要取消动画循环
beforeDestroy() { cancelAnimationFrame(this.animationId) } - 弹幕密度控制可通过定时器限制添加频率
- 移动端需要考虑分辨率适配问题
这种实现方式结合了Vue的数据响应特性和Canvas的高性能渲染,适合需要大量动态元素的场景。通过调整弹幕速度、颜色和发射频率参数,可以创建不同风格的弹幕效果。







