在專案實踐中應該有很多場景會用到彈幕,那麼如何實現乙個完美版本的彈幕呢?接下來我們原理加**帶你實現乙個完整的彈幕元件(react版本)
水平彈幕的實現有兩種情況:
1、當彈幕的個數加起來的寬度不足以覆蓋螢幕的視覺化區域
2、當彈幕的個數加起來的寬度超過螢幕的視覺化區域
針對第一種情況,實現原理很簡單,當從初始化位置開始滾動的時候,計算滾動的距離,當滾動結束後,立馬讓其回到初始化位置。
第二種情況稍微複雜一些,我們需要利用人眼的視覺暫留效果,實現彈幕的偷梁換柱,具體怎麼實現呢?
初始化位置在螢幕最右側,也就是隱藏在螢幕外面,這一點和上一種情況一致
我們需要使用乙個計算好的速度做一次動畫滑到螢幕的最左側,也就是後面迴圈往復的動畫的初始化位置,這個初始化位置和第一點的初始化位置不是同乙個。 2.1. 計算這個速度很簡單,只需要知道我們做完全部動畫的時間以及彈幕的總長度,得到的便是平均速度,之後再乘以螢幕的視覺化區域寬度
需要計算好我們在原有彈幕個數的基礎上需要補充多少個彈幕才能超過螢幕視覺化區域,做這個步驟是因為,只有補充這些彈幕,才能保證補充的彈幕的第乙個滑到最左側的時候整個彈幕整體瞬間回到初始化位置的時候,不會讓使用者看出端倪,也就是沒有頓挫感。
定好keyframe的具體引數即可開始做動畫。
實現的**是乙個元件,這個元件有興趣的童鞋可以將其豐富化,增加更多的引數,支援各種方向的迴圈滾動。
class infinitescroll extends react.component = this.props
settimeout(() => }}
// 該引數記錄是否彈幕的寬度超過了螢幕視覺化區域的寬度
const isscrollwidthlargeviewport = scrollcontainerwidth > visiblewidth
// const stylesheet = document.stylesheets[0]
// 注意這裡的動畫初始化位置兩種情況是不一樣的,在之前的步驟上有說過的(垂直方向的沒實現,可以忽略掉~)
const keyframes = `
@keyframes $px)` : 'translatey(0px)'};
}to px)` : `translatex(-$px)`};}}
@-webkit-keyframes $px)` : 'translatey(0px)'};
}to px)` : `translatex(-$px)`};}}
`const style = document.createelement('style')
const head = document.head || document.getelementsbytagname('head')[0]
style.type = 'text/css'
const textnode = document.createtextnode(keyframes);
// 如果css是external的話會報錯:uncaught domexception: failed to read the 'cssrules' property from 'cssstylesheet': cannot access rules
// stylesheet.insertrule(keyframes, stylesheet.cssrules.length);
const previouswidth = scrollcontainerwidth
// 這個計算之後scrollcontainerwidth就會包含那些補充了的彈幕的寬度,所以需要保留乙個原始值,供後面的過渡動畫使用
if (isscrollwidthlargeviewport)
// todo: 動畫的速度以後需要使用props
// 因為初始化位置在視口外,但是我們動畫的初始位置都是在0px上,所以就會有乙個時差出現,
// 因為在animation生效之前需要有乙個過渡動畫,二者的時間是相等的
const delay = (this.scrollinstance.children.length * 3 * visiblewidth) / previouswidth
const styletext = isscrollwidthlargeviewport ? `
width: $px;
transform: translatex(0px);
-webkit-transform: translatex(0px);
transition: $s linear;
-webkit-transition: $s linear;
animation: $
$s linear $s infinite;
-webkit-animation: $
$s linear $s infinite;
` : `
width: $px;
animation: $
$s linear infinite;
-webkit-animation: $
$s linear infinite;
`this.scrollinstance.style.csstext = styletext
}}, 500)
} render
() = this.props
const scrollclasses = scrolldirection === 'vertical' ? `scroll-list vertical $` : `scroll-list horizon $`
return (
this.scrollinstance = ref}>
)) })}}
複製**
對應的css檔案如下:
.scroll-list
&.vertical
}複製**
完整的應用參考:jsfiddle 前端實現迴圈彈幕效果
這裡給的margin right是為了給彈幕乙個隨機的間距,這樣顯得比較隨機 js 獲取螢幕寬度,在呼叫test的方法時候,彈幕先從最右邊螢幕出來,如果不給box重置padding left,那彈幕每次都在螢幕的最左邊,無法實現效果,我剛開始把padding left放在標籤上了,後來樣式被重置,無...
Gallery 實現無限迴圈
通過設定最大值兩億來模擬迴圈 因為總數很大時,肯定數不過來,就相當於模擬了 但是你的實際資料可能只有十幾個 所以iv.setimageresource img.get position 8 通過position 會很大很大 模一下你的實際資料的大小,就行了 gallery.setselection ...
ViewPager實現無限迴圈
從乙個方向上一直滑動。麼有滑到盡頭的感覺。詳細是怎麼實現的呢?看以下的思路。此處畫了一幅圖來表達實現無限迴圈的思路,即在資料起始位置前插入最後一項資料。在最後一項資料後插入第一項資料,當滑動到此處時。更新頁面的索引位置就ok了 這種方法用於資料處理,當中medialist是原始資料,newmedia...