看B站时,对弹幕的实现产生了兴趣,一开始想到用css3动画去实现,后来感觉这样性能不是很好,查了下资料,发现可以用帆布实现,于是就摸索着写了一个简单的弹幕。
-
<李>支持动态添加弹幕李>
<李>弹幕不重叠李>
<李>自定义弹幕颜色李>
效果图
demo
源码地址
前端框架选了比较熟悉的vuejs
弹幕滚动的基本思路就是通过定时器不断地改变弹幕的位置,时时重绘画布。
先加入一个画布标签,这里有个注意点,关于设备像素比对画布的影响,会出现绘图模糊。
& lt;画布的宽度==?00”“600”高度祝辞& lt;/canvas>//如果单纯这样写,画布会出现模糊 & lt;画布的宽度==?00”“600”高度比; & lt;/canvas>//为了不出现模糊,需要设置画布的css宽高为上下文宽高的1/devicePixelRatio, 本文是对于devicePixelRatio: 2的设备设置的,该值可从window.devicePixelRatio取得。 & lt;帆布ref=" hiddenCanvas "宽度=" 0 "高度=" 0 "比; & lt;/canvas>//后面会用的到 >之前我们先定义一个数组来存放弹幕数据,一条弹幕信息,包括文本内容,x, y坐标位置,颜色,速度(可以是随机或者固定,为了计算简单,我们这里采用了固定的速度)
var dmArr=[]; var差距=80;//弹幕的上下间距 var hiddenCanvas=efs.hiddenCanvas美元;//增加弹幕的方法 函数pushDm(文本、颜色){ 让y=getY ();//先确定跑道 让x=600;//初始x坐标为画布的右边界 让delayWidth=0;//同跑道 (让我=0,len=dmArr.length;我& lt;兰;我+ +){ 让dm=dmArr[我]; 如果(y===dm.y){//如果是同跑道,则往后排,设置一定的间隔,保证弹幕不会重叠; delayWidth +=Math.floor (hiddenCanvas.getContext (2 d) .measureText (dm.text)。宽度* 4 + 50); }} dmArr.push ({ 文本:文本, :x + delayWidth, y: y, 速度:8 颜色:颜色| |色鬼() }); }//随机获得y坐标 函数getY () { 让数学范围=5匕?600/差距);//跑道数量 返回Math.floor范围(math . random() * + 1) *差距; }//随机获得颜色 函数色鬼(){ 返回“$ {Math.floor (math . random () * 16777215) .toString (16)} '; }//写一个为循环,初始化30条弹幕 (让我=0;我& lt;30;我+ +){ pushDm(这是接二连三${我}”); }接下来设置一个20 ms的定时器,实现弹幕滚动效果
var计时器=零; var ctx=C涝猺efs.canvas.getContext (2 d); 函数开始(){ 计时器=setInterval(()=比;{ ctx。clearRect (0, 0, 600, 600);//每次需要清空画布 ctx.save (); ctx。字体=30 px微软YaHei”;//这里需要把字体大小设为需要显示的css大小的2倍(devicePixelRatio为2时) 如果(! dmArr.length)停止();//如果没有新弹幕了,就停止计时器 (让我=0,len=this.dmArr.length;我& lt;兰;我+ +){ 让dm=dmArr[我]; 让超量程的=-ctx.measureText (dm.text)。宽* 2; dm.x -=dm.speed; 如果(dm.x & lt;超量程的){ dmArr。拼接(我,1);//弹幕在画布中不可见时,从数组中移除该项 继续; } ctx。fillStyle=" # $ {dm.color} '; ctx.fillText (dm。文本、dm.x dm.y); } ctx.restore (); },20); } 函数停止(){ clearInterval(计时器); ctx。clearRect (0, 0, 600, 600); }我们还需要一个输入框,来实现手动添加弹幕功能
@keyup & lt;输入类型=拔谋尽薄J淙?"发送" v模型=" dmInput "最大长度=?0”比; & lt;按钮类型=鞍磁ァ盄click=胺⑺汀钡脑诜⒈? lt;/button> var dmInput="; var="颜色;//可自定义弹幕的颜色 函数发送(){ 如果(! dmInput)返回; 停止(); pushDm (dmInput、颜色); 开始(); dmInput="; }有待改进的地方和疑问?速度不恒定时,怎么保持弹幕不重叠视频弹幕是根据弹幕发送时间点来定位到视频的每一帧?如何实现?
以上所述是小编给大家介绍的使用帆布实现一个vue弹幕组件功能,希望对大家有所帮助,如果大家有任何疑问请给我留的言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
使用帆布实现一个vue弹幕组件功能