初版
用css3來實現(xiàn)彈幕確實比較簡單,只需要設(shè)置動畫讓彈幕從屏幕右側(cè)移動到屏幕左側(cè)即可,一開始是這樣實現(xiàn)的
.danmu {
position: fixed;
left: 100%;
animation: danmu 5s linear 0s 1;
}
@keyframes danmu {
from {
left: 100%;
transform: translateX(0);
}
to {
left: 0;
transform: translateX(-100%);
}
}
在pc端測試挺流暢,效果不錯,但是一拿到移動端上試,就發(fā)現(xiàn)這個動畫不流暢,有卡頓,ios稍好,android的話即使是配置高的機器也是有卡頓,配置低的機器就更是明顯。
緣由
一番研究,發(fā)現(xiàn)是因為keyframes中使用left,這樣的話left的改變會在渲染的過程中導致reflow,從而造成卡頓。那么改進的思路就比較明確了,移除left,只使用translate。
新問題
但是全部使用translate又有新的問題,使用left:100%可以達到讓彈幕從屏幕右側(cè)開始出現(xiàn),但是translate使用的百分比單位是相對于自身的,我們需要明確的給出屏幕寬度來translate,而屏幕寬度只有運行時用js才能獲取到。這樣一來,動畫的keyframes看來是需要使用js來動態(tài)生成了。
解決方案
在需要展示動畫前,動態(tài)生成一個style,根據(jù)當前屏幕寬度定義好keyframes。
// css
.danmu {
position: fixed;
left: 0;
visibility: hidden;
animation: danmu 5s linear 0s 1;
}
// 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 danmu { ${from} ${to} }`, 0);
注意,這里.danmu里設(shè)置了visibility為隱藏,不然彈幕會堆積顯示在屏幕左側(cè),而keyframes里則設(shè)置visibility為顯示,這樣就使得彈幕只在動畫過程中才能被看見。
這么做的原因是彈幕的初始位置為left: 0才能方便的設(shè)置彈幕頭部從屏幕右側(cè)出現(xiàn)然后從右向左移動到彈幕尾部消失在屏幕左側(cè)為止。