前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)

2019-01-28 11:59:28王振洲

在第一节,我们通过left属性,实现了弹幕的效果,left会改变元素的布局,因此会发生reflow(回流),表现在移动端页面上会造成弹幕动画的卡顿。

2. css3弹幕性能优化

我们直到了第一节中的弹幕动画存在卡顿的问题,下面我们看看如何解决动画的卡顿。

(1)CSS开启硬件加速

在浏览器中用css开启硬件加速,使用GPU(Graphics Processing Unit)可以提升网页性能。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

CSS animations, transforms 以及 transitions 不会自动开启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属性的值,这样就不会发生reflow。

我们想仅仅通过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实现弹幕的原理就是时时的重绘文字,下面来一步步的实现。