看哔哩哔哩的时候,我对弹幕的实现产生了兴趣。一开始我想到用css3动画来实现。后来觉得这个表现不是很好。查资料后发现可以用画布实现,于是摸索着写了一个简单的弹幕。
弹幕功能
支持动态添加弹幕,非重叠自定义弹幕颜色渲染
演示
源地址
前端框架选择了熟悉的vuejs
弹幕翻滚的基本思路是通过计时器不断改变弹幕的位置,并不时重绘布面。
实施步骤
首先,添加一个画布标签。这里,有一张纸条。至于设备像素比对画布的影响,会出现画图模糊。
canvas width=' 600 ' height=' 600 '/canvas//如果只是这样写,画布会显得模糊。画布宽度=' 600 '高度=' 600 '样式=' width: 300pxHeight: 300px'/canvas//为了避免歧义,需要将canvas的css宽度和高度设置为上下文宽度和高度的1/DevicePixelLatio。本文为devicePixelRatio:2设置,可从window . devicepixellratio Canvas ref=' hidden Canvas ' width=' 0 ' height=' 0 ' style=' display : none '/Canvas//后面我们将定义一个数组来存储弹幕数据和一条弹幕信息,包括文本内容、x,y坐标位置、颜色、速度(可以是随机的也可以是固定的,这里采用这个数组进行简单计算。
var DMarr=[];var间隙=80;//弹幕顶部和底部的距离var隐藏画布=这个。$ refs .隐藏画布;//添加弹幕函数pushdm (text,color)的方法{ let y=get y();//确保跑道容x=600//初始x坐标是画布的右边界,让delayWidth=0;//相同的跑道为(让i=0,len=dmArr.length我透镜;I){ let DM=DMarr[I];If(y====DM . y){//如果是在同一条跑道上,回去设置一定的间隔,保证弹幕不会重叠;delayWidth=math . floor(hiddencanvas . getcontext(' 2d ')。measureText(dm.text)。宽度* 4 50);} } dmArr.push({ text: text,x: x delayWidth,y: y,speed: 8,color : color | | getColor()});}//获取y坐标函数gety(){让range=math。地板(600/间隙)随意;//跑道号返回数学。地板(数学。random()* range 1)* gap;}//获取color函数getcolor () {return` $ {math。地板(数学。random () * 16777215)。tostring(16)} `;}//写一个for循环,初始化30个弹幕for(让I=0;i 30i ) { pushDm(`是弹幕$ { I } `);}接下来设置一个20毫秒的定时器,实现弹幕翻滚效果
var计时器=nullvar ctx=这个。$ refs . canvas . GetContext(' 2d ');函数start(){ timer=setInterval(()={ CTX . clear rect(0,0,600,600);//每次需要清空画布CTX . save();ctx.font='30px微软雅黑';//在这里,您需要将字体大小设置为要显示的css大小的两倍(当devicePixelRatio为2时)if(!dmarr . length)stop();//如果没有新的弹幕,停止定时器(让I=0,len=this . dmarr . length;我透镜;I){ let DM=DMarr[I];让over range=-CTX . measure text(DM . text)。宽度* 2;DM . x-=DM . speed;if (dm.x超量程){ dmArr.splice(i,1);//当弹幕在画布中不可见时,从数组中移除continue项;} CTX . FillStyle=`# $ { DM . color } `;ctx.fillText(dm.text,dm.x,dm . y);} CTX . restore();}, 20);}函数stop() { clearInterval(计时器);ctx.clearRect(0,0,600,600);}我们还需要一个输入框来实现手动添加弹幕的功能
input type=' text ' @ keyup . enter=' send ' v-model=' dmin put ' maxlength=' 20 ' button type=' button ' @ click=' send ' publish/button var dmin put=' ';var color=//可以自定义弹幕函数sent()的颜色{if(!dmInput)返回;stop();pushDm(dmInput,颜色);start();dmInput=}需要改进的地方和问题?当速度不恒定时,如何保持弹幕不重叠?视频弹幕根据弹幕的发送时间定位每一帧视频。如何实现?
摘要
以上是使用canvas实现一个vue弹幕组件的介绍,对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!