复制链接
所有者
为所有光明评论•
已编辑
后端实现弹幕效果的方法总结(包括css3和canvas的实现方法)
此前,联通侧中奖页面,中奖结果展示窗口需要弹幕轮播展示。 之前也遇到过一些坑,现在总结一下如何实现后端弹幕的效果。
1、CSS3实现乞丐版弹幕(一)如何通过css3实现弹幕
首先我们看一下如何通过CSS实现最简单的弹幕:
首先在HTML中定义一个弹幕的dom结构:
我是弹幕
” >
我是弹幕
通过连接这个块就可以实现弹幕的连接。 以从右向左连接的弹幕为例,弹幕的初始位置在容器的最左侧弹幕css3,并沿边缘隐藏(弹幕的最左侧与容器的最右侧相同) 。 拟合)可以通过绝对定位和变换来实现:
.block{
position:absolute;
}
初始位置:
from{
left:100%;
transform:translateX(0)
}
联通向右的结束位置是(弹幕最左边贴合容器最左边):
to{
left:0;
transform:translateX(-100%)
}
起始位置和结束位置的具体说明如下:
根据起始位置和结束位置可以定义一个完整的两帧弹幕动画:
@keyframes barrage{
from{
left:100%;
transform:translateX(0);
}
to{
left:0;
transform:translateX(-100%);
}
}
将这个动画引入到弹幕元素中:
.block{
position:absolute;
/* other decorate style */
animation:barrage 5s linear 0s;
}
这样就可以实现乞丐版的弹幕效果了:
(2)通过绝对定位和左侧实现弹幕的缺陷
首先我们先理清楚css的渲染流程
如果I)和II)中的属性发生变化,就会发生回流。 如果只有III)中的属性发生变化,则只会发生重绘。 看来我们从css的渲染过程中也可以看出:回流必须伴随着专注于绘画。
回流:当部分或全部渲染树由于尺寸、行距等问题发生变化时,需要重新构建的过程称为回流。
repaint:当元素的某些属性发生变化,例如形状、背景颜色等,不会引起布局变化,需要重新渲染时弹幕css3,该过程称为重绘。
回流会影响浏览器CSS的渲染速率,因此在优化网页性能时应减少回流的发生。
第一节我们通过left属性实现了弹幕的效果。 Left会改变元素的布局,因此会发生回流,从而导致联通页面弹幕动画卡顿。
2.css3弹幕性能优化
我们发现第一节的弹幕动画存在卡顿问题。 接下来我们就来看看如何解决动画卡顿的问题。
(1)CSS开启硬件加速
使用CSS在浏览器中启用硬件加速,并使用GPU(GraphicsProcessingUnit)来提高网页性能。 鉴于此,我们可以利用GPU的强大功能,让我们的网站或者应用程序执行得更加流畅。
CSS 动画、转换和过渡不是手动启用 GPU 加速,而是由浏览器的温和软件渲染引擎执行。 那么我们如何切换到GPU模式呢? 许多浏览器提供单独触发的 CSS 规则。
比较常见的方法是我们可以通过3D变化(translate3d属性)来开启硬件加速。 鉴于此,我们将动画改为:
@keyframes barrage{
from{
left:100%;
transform:translate3d(0,0,0);
}
to{
left:0;
transform:translate3d(-100%,0,0);
}
}
这样就可以通过开启硬件加速来优化网页性能。 而这些方法并没有从根本上解决问题。 同时,使用GPU减少了显存的使用,会降低联通设备的电池寿命等。
(2)不要改变left属性
第二种办法就是想办法在弹幕动画前后不改变left属性的值,这样就不会出现回流的情况。
我们想要通过translateX来确定弹幕节点的初始位置,而translateX(-100%)是相对于弹幕节点本身的,而不是相对于父元素的,所以我们将js和css耦合起来,得到js中弹幕的长度节点所在父元素的位置,然后根据长度定义弹幕节点的初始位置。
以父元素为body时为例:
//css
.block{
position:absolute;
left:0;
visibility:hidden;
/* other decorate style */
animation:barrage 5s linear 0s;
}
//js
let style = document.createElement('style');
document.head.appendChild(style);
let width = window.innerWidth;
let from = `from { visibility: visible; -webkit-transform: translateX(${width}px); }`;
let to = `to { visibility: visible; -webkit-transform: translateX(-100%); }`;
style.sheet.insertRule(`@-webkit-keyframes barrage { ${from} ${to} }`, 0);
不仅耦合js估计父元素的长度然后确定弹幕节点的初始位置,这里在弹幕节点我们减少visibility:hidden属性来避免显示初始位置。 防止弹幕节点在初始位置确定之前就显示在父容器中。 仅当弹幕从初始位置开始滚动时,弹幕才会显示为可见。
但这些CSS实现方式在实现弹幕的扩展功能时比较麻烦,比如如何控制弹幕的暂停等等。
3.Canvas实现弹幕
除了通过css实现弹幕之外,还可以通过canvas来实现弹幕。
通过canvas实现弹幕的原理是时不时的重画文字。 让我们一步一步地实现它。
通过定时器,x和y定期改变。 每次改变之前,先清空屏幕,然后根据改变的x和y重新绘制屏幕。 当有多个弹幕时,定义:
let colorArr=_this.getColor(color); 弹幕数组多对应的颜色数组
let numArrL=_this.getLeft(); 弹幕数组所对应的x坐标位置数组
let numArrT=_this.getTop(); 弹幕数组所对应的y坐标位置数组
let speedArr=_this.getSpeed(); 弹幕数组所对应的弹幕移动速度数组
定时重画弹幕函数为:
_this.timer=setInterval(function(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
for(let j=0;j<barrageList.length;j++){
numArrL[j]-=speedArr[j];
ctx.fillStyle = colorArr[j]
ctx.fillText(barrageList[j],numArrL[j],numArrT[j]);
ctx.restore();
},16.7);
达到的效果是:
4.画布弹幕扩展功能
使用canvas来实现弹幕的形式,非常方便添加暂停弹幕滚动等扩展功能。 此外,还可以给弹幕添加头像、给每个弹幕下边框等,以后再添加。
最后给出一个简单的react弹幕组件;
文本已成功更新,但这些错误已被纠正: