基于Canvas+Vue的弹幕组件的实现

2020-04-21 23:08:55易采站长站整理

最近由于项目需要定制化一个弹幕功能,所以尝试使用canvas来开发组件。经过测试在一些低端机的效果也没有明显的卡顿,和大家交流一下

弹幕效果

 功能介绍

支持循环弹幕
弹幕不重叠
支持选择轨道数
支持弹幕发送

使用

npm i vue-barrage

参数配置 

nametypedefaultdesc
barrageListArray[]弹幕数据
speedNumber4弹幕滚动速度
loopBooleantrue是否循环滚动
channelsNumber2弹幕轨道数

功能实现

html样式


<template>
<div class="barrage-container">
<div
class="container"
:style="{height: barrageHeight/2+'px'}">
<canvas
id="canvas"
ref="canvas"
:width="barrageWidth"
:height="barrageHeight"
:style="{'width': barrageWidth/2 + 'px','height': barrageHeight/2 + 'px'}"/>
</div>
</div>
</template>

js实现

监听数据源


watch: {
barrageList (val) {
if (val.length !== 0) {
this.initData() // 数据初始化
this.render() // 开始渲染
}
}
}

数据初始化

barrageArray
是存储弹幕数据用的,包括默认弹幕列表和新增弹幕项


/**
* 数据初始化
*/
initData () {
for (let i = 0; i < this.barrageList.length; i++) { // 此处处理只显示40个字符
let content = this.barrageList[i].content.length > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content
this.pushMessage(content, this.barrageList[i].color)
}
},
/**
* 增加数据
* @param content
* @param color
*/
pushMessage (content, color) {
let position = this.getPosition() // 确定跑道位置
let x = this.barrageWidth // 初始位置
let offsetWidth = 0
for (let i = 0, len = this.barrageArray.length; i < len; i++) {
let item = this.barrageArray[i]if (position === item.position) { // 如果同跑道,则往后排
offsetWidth += Math.floor(this.ctx.measureText(item.content).width * 3 + 60)
}
}
this.barrageArray.push({
content: content, // 弹幕内容
x: x + offsetWidth, // 确定每一条弹幕的初始位置