以前在1个挪动端抽奖网页页面中,在抽奖結果的展现对话框必须弹幕轮播显示信息,以前踩过1些小坑,如今总结1下前端开发弹幕实际效果的完成方法。
1. css3完成乞讨者版的弹幕
(1)怎样根据css3完成弹幕
最先看来怎样根据css的方式完成1个最简易的弹幕:
最先在html中界定1条弹幕的dom构造:
<div class="block">我是弹幕</div>
弹幕的挪动能够根据挪动这个block来完成,以从右向左挪动的弹幕为例,弹幕的原始部位在器皿的最左边且贴边掩藏(弹幕的最左侧与器皿的最右贴合),能够根据肯定精准定位加transform来完成:
.block{ position:absolute; }
原始部位:
from{ left:100%; transform:translateX(0) }
挪动到最左侧的完毕部位为(弹幕的最右侧与器皿的最左侧贴合):
to{ left:0; transform:translateX(⑴00%) }
起止部位和完毕部位的实际图示以下所示:
依据起止部位和完毕部位能够界定详细的两帧弹幕动漫:
@keyframes barrage{ from{ left:100%; transform:translateX(0); } to{ left:0; transform:translateX(⑴00%); } }
给弹幕元素引进这个动漫:
.block{ position:absolute; /* other decorate style */ animation:barrage 5s linear 0s; }
这样便可以完成1个乞讨者版的弹幕实际效果:
(2)根据肯定精准定位和left完成弹幕的缺点
最先确立1下css的3D渲染全过程
I)依据HTML的构造转化成DOM树(DOM树中包括了display:none的连接点) II)在DOM树的基本上,依据连接点的几何图形特性(margin/padding/width/height/left等)转化成render树 III)在render树的基本上再次3D渲染color,font等特性
在其中假如I)中合II)中的特性产生转变会产生reflow(回流),假如仅仅III)中的特性产生更改,只会产生repaint(重绘)。明显从css的3D渲染全过程大家还可以看出来:reflow(回流)必随着侧重绘。
reflow(回流):当render树中的1一部分或所有由于尺寸边距等难题产生更改而必须复建的全过程叫做回流 repaint(重绘):当元素的1一部分特性产生转变,如外型情况色不容易引发合理布局转变而必须再次3D渲染的全过程叫做重绘
reflow(回流)会危害访问器css的3D渲染速率,因而在做网页页面特性提升的情况下要降低回流的产生。
在第1节,大家根据left特性,完成了弹幕的实际效果,left会更改元素的合理布局,因而会产生reflow(回流),主要表现在挪动端网页页面上会导致弹幕动漫的卡顿。
2. css3弹幕特性提升
大家直至了第1节中的弹幕动漫存在卡顿的难题,下面大家看看怎样处理动漫的卡顿。
(1)CSS打开硬件配置加快
在访问器选用css打开硬件配置加快,应用GPU(Graphics Processing Unit)能够提高网页页面特性。鉴于此,大家能够充分发挥GPU的能量,从而使大家的网站或运用主要表现的更加顺畅。
CSS animations, transforms 和 transitions 不容易全自动打开GPU加快,而是由访问器的迟缓的手机软件3D渲染模块来实行。那大家如何才能够切换到GPU方式呢,许多访问器出示了一些开启的CSS标准。
较为普遍的方法是,大家能够根据3d转变(translate3d特性)来打开硬件配置加快,鉴于此,大家改动动漫为:
@keyframes barrage{ from{ left:100%; transform:translate3d(0,0,0); } to{ left:0; transform:translate3d(⑴00%,0,0); } }
这样便可以根据打开硬件配置加快的方法,提升网页页面特性。可是这类方法沒有从压根上处理难题,另外应用GPU提升了运行内存的应用,会降低挪动机器设备的电池使用寿命这些。
(2)不更改left特性
第2种方式,便是想方法在弹幕动漫的前后左右不更改left特性的值,这样就不容易产生reflow。
大家想仅仅根据translateX来明确弹幕连接点的原始部位,可是translateX(⑴00%)是相对弹幕连接点自身的,而并不是相对父元素,因而大家藕合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(⑴00%); }`; style.sheet.insertRule(`@-webkit-keyframes barrage { ${from} ${to} }`, 0);
除藕合js测算了父元素的宽度,从而明确弹幕连接点的原始部位以外,这里在弹幕连接点中大家以便避免原始部位就有显示信息,提升了visibility:hidden特性。避免弹幕连接点在未明确原始部位时就显示信息在父器皿内。仅有弹幕刚开始从原始部位翻转,才会变得可见。
可是这类css的完成方法,在完成弹幕的拓展作用层面较为不便,例如怎样操纵弹幕中止这些。
3. canvas完成弹幕
除根据css完成弹幕的方式以外,根据canvas还可以完成弹幕。
根据canvas完成弹幕的基本原理便是时刻的重绘文本,下面来1步步的完成。
获得画布
let canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d');
绘图文本
ctx.font = '20px Microsoft YaHei'; ctx.fillStyle = '#000000'; ctx.fillText('canvas 绘图文本', x, y);
上面的fillText便是完成弹幕实际效果的关键api,在其中x表明横方位的座标,y表明纵方位的座标,要是时刻的更改x,y开展重绘,便可以完成动态性的弹幕实际效果。拷贝编码
消除绘图內容
ctx.clearRect(0, 0, width, height);
实际完成
根据定时执行器,定时执行更改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. canva弹幕的拓展作用
根据canvas完成弹幕的方法,很便捷做例如中止弹幕翻转等拓展作用,另外,还可以给弹幕提升头像,给每条弹幕提升边框这些作用,之后再填补。
最终给1个简易的react弹幕组件;https://github.com/forthealllight/react-barrage
以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。