前端实现弹幕功能,html怎么实现弹幕效果
在以前的移动终端的抽奖页面中,抽奖结果的显示窗口需要弹幕轮播显示。之前踩了一些小坑,现在总结一下前端弹幕效果的实现。
Css3实现乞丐弹幕css3弹幕性能优化画布实现弹幕canva弹幕扩展功能1. css3实现乞丐版的弹幕
(1)如何通过css3实现弹幕
首先,我们来看看css如何实现最简单的弹幕:
首先,在html中定义弹幕的dom结构:
Class= block 我是弹幕/div弹幕的移动可以通过移动这个方块来实现。以弹幕从右向左移动为例。拦网的初始位置在容器的最左侧,贴边是隐藏的(拦网的最左侧适合容器的最右侧),这可以通过绝对定位加变换来实现:块{位置:绝对;}初始位置:
从{左:100%;Transform:translateX(0)}移动到最左端位置(弹幕的最右端部分附加到容器的最左端部分):
到{ left:0;Transform:translateX(-100%)}起始位置和结束位置的具体示意图如下:
一个完整的两帧弹幕动画可以根据起始位置和结束位置来定义:
@关键帧弹幕{ from { left:100%;transform:translate x(0);}到{ left:0;transform:translate x(-100%);}}将此动画引入弹幕元素:块{位置:绝对;/*其他装修风格*/动画:弹幕5s线性0s;}这样就可以实现乞丐版的弹幕效果:
(2)通过绝对定位和left实现弹幕的缺陷
首先明确css的渲染流程。
I)根据HTML的结构生成DOM树(DOM树包含显示的节点:none) II)根据节点的几何属性(边距/填充/宽度/高度/左侧等)生成渲染树。)III)基于渲染树继续渲染属性,例如颜色、字体。
如果I)和II)中的属性被更改,将会发生reflow,如果只有III)中的属性被更改,将只会发生repaint。显然,我们也可以从css的渲染过程中看出:reflow(回流)必然伴随着重绘。
Reflow(回流):由于尺寸和边距等原因,部分或全部渲染树发生变化时的重建过程。被称为reflow repaint:当元素的某些属性发生变化时,比如外观背景色不会引起布局变化,而重新渲染的过程被称为redrawing。
回流(Reflow)会影响浏览器css的渲染速度,所以在优化网页性能时需要减少回流的发生。
第一节我们通过左属性实现了弹幕的效果。left会改变元素的布局,所以会发生回流,导致弹幕动画在移动页面上卡住。
2. css3弹幕性能优化
直到第一节的弹幕动画出现了卡顿的问题,我们再来看看如何解决动画的卡顿。
(1)CSS开启硬件加速
在浏览器中用css打开硬件加速,使用GPU(图形处理器)可以提高网页性能。有鉴于此,我们可以充分发挥GPU的威力,让我们的网站或者应用表达的更加流畅。
CSS动画、变换和过渡不会自动开启GPU加速,而是由浏览器缓慢的软件渲染引擎执行。那么如何才能切换到GPU模式呢?很多浏览器都提供了一些触发的CSS规则。
常见的方式是我们可以通过3d变化(translate3d属性)开启硬件加速。鉴于此,我们将动画修改为:
@关键帧弹幕{ from { left:100%;transform:translate3d(0,0,0);}到{ left:0;transform:translate3d(-100%,0,0);}}这样就可以通过开启硬件加速来优化网页的性能。但是,这种方法并没有从根本上解决问题。同时使用GPU增加了内存的使用,会降低移动设备的电池寿命等等。
(2)不要改变left属性。
第二种方法是想办法不改变弹幕动画前后left属性的值,这样就不会发生回流。
我们想只通过translateX来确定弹幕节点的初始位置,但是translateX(-100%)是相对于弹幕节点本身,而不是父元素,所以我们把js和css耦合起来,在js中得到弹幕节点所在父元素的宽度,然后根据宽度定义弹幕节点的初始位置。
以父元素为主体为例:
//css。块{位置:绝对;左:0;可见性:隐藏;/*其他装修风格*/动画:弹幕5s线性0s;}//jslet style=document . createelement( style );document . head . appendchild(style);let width=window.innerWidthlet from=` from { visibility:visible;-WebKit-transform:translate x($ { width } px);}`;let to=` to { visibility:visible;-WebKit-transform:translate x(-100%);}`;style . sheet . insert rule(`@-WebKit-关键帧弹幕{ ${from} ${to} } `,0);除了耦合js计算父元素的宽度,从而确定弹幕节点的初始位置,我们还在弹幕节点中增加了visibility:hidden属性,防止初始位置被显示。当初始位置未确定时,阻止弹幕节点显示在父容器中。弹幕只有在从初始位置开始滚动时才会变得可见。
但是这种css实现方式在实现弹幕的扩展功能上比较麻烦,比如如何控制弹幕暂停等等。
3. canvas实现弹幕
除了通过css实现弹幕的方法,弹幕还可以通过canvas实现。
通过canvas实现弹幕的原理是不时重绘文字。下面是如何一步步实现的。
获取画布
let canvas=document . getelementbyid( canvas );let CTX=canvas . get context( 2d );绘制文本
ctx.font=20px微软雅黑;ctx.fillStyle= # 000000Ctx.fillText(画布绘制文本,x,y);上面的fillText是实现弹幕效果的主要api,其中X代表横坐标,Y代表纵坐标。只要不时重画X和Y,就能实现动态弹幕效果。复制代码
清除绘图内容
ctx.clearRect(0,0,宽度,高度);具体实现
通过timer,定时改变X和Y,每次改变前清空屏幕,然后根据改变后的X和Y重新绘制,当有多个弹幕时,定义:
let coloarr=_ this . getcolor(color);颜色数组let numArrL=_this.getLeft()对应弹幕数组;x坐标位置数组let numArrT=_this.getTop()对应弹幕数组;y坐标位置数组let speedArr=_this.getSpeed()对应弹幕数组;弹幕移动速度阵列计时对应弹幕阵列的重绘弹幕功能如下:
_ this . timer=setInterval(function(){ CTX . clear rect(0,0,canvas.width,canvas . height);CTX . save();for(设j=0;jbarrageList.lengthj){ numArrL[j]-=speed arr[j];CTX . fill style=colorrar[j]CTX . fill text(barrage list[j],numArrL[j],numArrT[j]);CTX . restore();},16.7);实现的效果如下:
4. canva弹幕的扩展功能
通过canvas实现弹幕的方式,方便做暂停弹幕滚动等扩展功能。此外,还可以在弹幕中添加头像,给每个弹幕添加边框等等,以后再添加。
最后,给出一个简单的react弹幕组件;https://github.com/forthealllight/react-barrage
这就是本文的全部内容。希望对大家的学习和支持有帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。