微信小程序純CSS實現(xiàn)無限彈幕滾動效果

啥也不說,先上效果圖
實現(xiàn)背景
產(chǎn)品: 我們需要一個彈幕滾動效果,類似于微博熱搜那種實時評論,但是我們的數(shù)據(jù)是固定的20條,你讓他一直循環(huán)滾動
我 好的(os:要求真多)
實現(xiàn)思路
你不是說要微博熱搜彈幕那種效果嗎?這好辦啊,馬上去微博看熱搜(又看到那么多塌房的的明星),看了幾十分鐘,表面上是多研究研究,實則上班期間光明正大的摸魚,感覺真好!!
- 先看看微博的效果
分析一下,有以下幾個功能點
- 彈幕實時更新
- 從右到左勻速運動
- 點擊某一個彈幕跳轉(zhuǎn)到詳情,返回時繼續(xù)移動
一共三個功能點,對比我的需求只有一個功能點相差,我只需要把彈幕實時更新改成彈幕循環(huán)滾動。
如何實現(xiàn)循環(huán)的感覺呢?
如果要實現(xiàn)一個循環(huán)的感覺就必須要把數(shù)組拷貝一份,把他們一排排列,然后這樣子讓他去滾動,當(dāng)滾動結(jié)尾的時候,展示第二個拷貝數(shù)組的開頭。animate
動畫幀的編寫就改變transform:translateX
的值,從0
到單個數(shù)組所渲染的dom長度
,第一次的動畫執(zhí)行完成后,剛好是第二個拷貝數(shù)組的開頭,然后又讓動畫幀執(zhí)行從0
到單個數(shù)組所渲染的dom長度
,由于每一次動畫執(zhí)行完剛好是第二個拷貝數(shù)組的開頭,所以執(zhí)行第二次動畫時不會有閃動的感覺
如何實現(xiàn)動畫執(zhí)行完又繼續(xù)執(zhí)行呢?
設(shè)置animation-iteration-count: infinite;
,循環(huán)執(zhí)行,這樣子就會無限的從0
到單個數(shù)組所渲染的dom長度
,無限的循環(huán)套娃,就會有循環(huán)滾動的感覺了,大概圖如下
代碼實現(xiàn)
- 先拷貝一份數(shù)組讓他們一排排列,注意最外層的容器需要設(shè)置
overflow: hidden
<view class="z-bullet-test"> <view class="z-list"> <view class="z-container"> <view class="z-single" wx:for="{{10}}" wx:key="index"> {{index}} </view> </view> <view class="z-container"> <view class="z-single" wx:for="{{10}}" wx:key="index"> {{index}} </view> </view> </view> </view>
.z-bullet-test { width: 690rpx; height: 88rpx; display: flex; align-items: center; background-color: saddlebrown; margin: 0 auto; margin-top: 40rpx; overflow: hidden; } .z-container { display: flex; flex-wrap: nowrap; } .z-single { padding: 10rpx 40rpx; color: white; background-color: cadetblue; margin-right: 20rpx; } .z-list { display: flex; flex-wrap: nowrap; }
效果如下
- 讓外層的容器滾動起來,只需要給
z-list
添加動畫即可
.z-list { display: flex; flex-wrap: nowrap; animation: rowScrollTest 2s linear infinite; } @keyframes rowScrollTest { 0% { /* 為0時,ios會閃動 */ transform: translateX(1); } 100% { transform: translateX(-433.85px); // 單個數(shù)組所渲染的dom長度 } }
效果如下
通過以下幾句代碼,并且沒有使用任何的js代碼就把無限循環(huán)滾動實現(xiàn)好了,是不是覺得事情到這兒結(jié)束了呢???
并沒有
如何動態(tài)計算單個數(shù)組所渲染的dom長度
上面實現(xiàn)的代碼中,對于單個數(shù)組所渲染的dom長度
是通過開發(fā)者工具找到dom長度,并在代碼中寫死的,但是在開發(fā)中你并不能確定這個長度到底為多少,這個時候我們需要去動態(tài)獲取這個dom長度
這個時候就有同學(xué)說了,那還不簡單直接通過js去獲取dom長度不就可以了嗎?
想法很不錯,先給你點個贊,但是重點來了?。?!注意看,通過js獲取dom長度可以得到一個長度變量,但是你如何動態(tài)賦值給@keyframes
動畫幀呢??
@keyframes rowScrollTest { 0% { /* 為0時,ios會閃動 */ transform: translateX(1); } 100% { transform: translateX(domWidth); // 單個數(shù)組所渲染的dom長度 } }
思考一下?這個domWidth
應(yīng)該如何去動態(tài)的賦值呢?
動態(tài)賦值動畫幀中的css參數(shù)
遇到這個問題時,感覺有點奇怪,這個動態(tài)的賦值一般是給css屬性,如width
,height
,還沒有給動畫幀中的css屬性動態(tài)賦值過,
于是照著給css屬性動態(tài)賦值的方法,我把@keyframes
動畫幀函數(shù)先寫到了行內(nèi)style
上,并把css中的@keyframes
動畫幀函數(shù)刪除
<view class="z-list" style="@keyframes rowScrollTest {0% { transform: translateX(1); } 100% { transform: translateX(-433.85px); }}"> <!-- 數(shù)組內(nèi)容 --> </view>
滿心歡喜的打開開發(fā)者工具,一看~~ 嘿! 動都不動了
原因是因為style屬性只能識別出css的屬性名,我在這里寫的動畫幀函數(shù),在它看來就是一串沒有用的字符串,所以就根本不會編譯成css的動畫幀函數(shù),就肯定不會有作用了
如何解決呢?
傳統(tǒng)的給css屬性動態(tài)賦值的方法走不通,應(yīng)該怎么辦呢?99%解決問題的辦法:點開goole然后再輸入欄輸入這個問題,按下enter鍵,然后就去瘋狂的尋找就可以了。
經(jīng)過一番查找,嘿還真找到了一個東西,css自定義屬性(變量),這是個啥呢?
MDN解釋:自定義屬性(有時候也被稱作CSS 變量或者級聯(lián)變量)是由 CSS 作者定義的,它包含的值可以在整個文檔中重復(fù)使用。由自定義屬性標(biāo)記設(shè)定值(比如: --main-color: black;
),由 var() 函數(shù)來獲取值(比如: color: var(--main-color);
)復(fù)雜的網(wǎng)站都會有大量的 CSS 代碼,通常也會有許多重復(fù)的值。
那我們是不是可以動態(tài)賦值給這個變量,并在css代碼的@keyframes
動畫幀函數(shù)中去使用這個變量的值,當(dāng)作translateX
的值呢,立馬試一下
<view class="z-list" style="--domWidth--:-433.85px;"> <!-- 數(shù)組內(nèi)容 --> </view>
@keyframes rowScrollTest { 0% { /* 為0時,ios會閃動 */ transform: translateX(1); } 100% { transform: translateX(var(--domWidth--)); // 單個數(shù)組所渲染的dom長度 } }
激動的打開開發(fā)者工具,見證奇跡的時刻到來了?。。。。。。。。?它動了,它在瘋狂的滾動著
接下來是不是只需要將-433.85
改成js獲取的單個數(shù)組所渲染的dom長度
就可以了呢?,于是我滿心歡喜的去寫js代碼了,先定義一個變量domWidth: 0
,然后再去onLoad
中去獲取z-container
的長度并賦值給domWidth
,動態(tài)的獲取單個數(shù)組所渲染的dom長度
并賦值給@keyframes
動畫幀函數(shù),就大功告成了!?。?strong>其實并沒有,不要看到這兒就不看了!)
<view class="z-list" style="--domWidth--:-{{domWidth}}px;"> <!-- 數(shù)組內(nèi)容 --> </view>
data: { domWidth: 0 }, onLoad () { wx.createSelectorQuery() .selectAll(".z-container") .boundingClientRect((res) => { this.setData({ domWidth: res[0].width }); }) .exec(); }
這個時候我輕松的點開開發(fā)者工具,心里想著這個問題被我輕松解決掉了,還剩很多開發(fā)時間,可以去摸魚了,但是它不動了,一點都不動了!
為什么呢? 我立馬點開控制臺,找到了這個變量的值,發(fā)現(xiàn)他是有值的,說明問題不出在js獲取長度,
我仔細(xì)一想瞬間明白了 domWidth
的值默認(rèn)為0,animation
屬性會在被渲染出來時立即執(zhí)行,這個時候的domWidth
還為0,動畫幀函數(shù)就相當(dāng)于是從0到0,肯定就不會滾動了,你可以把domWidth
隨便設(shè)置一個初始值,你就會發(fā)現(xiàn)它會動了
那為什么css屬性為0時,動態(tài)設(shè)置會變化呢? 我覺得是因為微信小程序本身對于setData
這個函數(shù),根據(jù)改變的data
去進行重新渲染時,就沒有包含對**css自定義屬性(變量)** 的對比,所以會導(dǎo)致渲染失效,這個值一直都是初始值
解決animation執(zhí)行時domWidth為0的問題
這個時候有一個簡單的解決辦法
- 先判斷如果
domWidth
為0,就再渲染一個由這個數(shù)組循環(huán)成的靜止dom,并不渲染下面兩個數(shù)組組成的滾動彈幕dom - 然后去獲取這個靜止dom的長度,獲取完成了之后,再去渲染下面的滾動彈幕dom,并把靜止dom給銷毀掉
- 那么當(dāng)
animation
在初始化執(zhí)行時,domWidth
的長度就已經(jīng)是單個數(shù)組所渲染的dom長度
,就可以順利的去執(zhí)行動畫了
<view class="z-bullet-test"> <block wx:if="{{domWidth === 0}}"> <view class="z-container"> <view class="z-single" wx:for="{{10}}" wx:key="index"> {{index}} </view> </view> </block> <block wx:else> <view class="z-list" style="--domWidth--:-{{domWidth}}px;"> <view class="z-container"> <view class="z-single" wx:for="{{10}}" wx:key="index"> {{index}} </view> </view> <!-- --> <view class="z-container"> <view class="z-single" wx:for="{{10}}" wx:key="index"> {{index}} </view> </view> </view> </block> </view>
這樣子就真的大功告成了??!
如何實現(xiàn)多行彈幕滾動?
多行彈幕滾動的話,你就多復(fù)制幾行就可以了,并且可以給每一行設(shè)置一個animation-delay
屬性,讓他們不要同時執(zhí)行animation,去岔開時間來執(zhí)行,實現(xiàn)一個比較亂的彈幕效果。
如何實現(xiàn)動畫的停止與開始呢?
對于一個循環(huán)動畫,你如果要動態(tài)的設(shè)置它開始或停止,可以通過animation-play-state
屬性設(shè)置running
或paused
來設(shè)置動畫的開始或停止
總結(jié)
這篇文章,我把自己對于實現(xiàn)一個無限彈幕滾動需求的過程一一描述了一遍,把自己遇到的問題和思考的過程通過文字表述了出來,寫的可能不是很好,希望可以勉勵自己的同時也能幫助到看到這篇文章的朋友,如果你覺得我的廢話太多,可以直接gitee地址去復(fù)制代碼自己看一下,實現(xiàn)的代碼量很少,也比較簡單。
到此這篇關(guān)于微信小程序純CSS實現(xiàn)無限彈幕滾動效果的文章就介紹到這了,更多相關(guān)CSS彈幕滾動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
css scroll-snap控制滾動元素的實現(xiàn)
本文主要介紹了css scroll-snap控制滾動元素的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)2023-02-22- 這篇文章介紹了使用CSS設(shè)置滾動條樣式,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-12-20
- 這篇文章主要介紹了CSS如何完成視差滾動效果,幫助大家更好的理解和學(xué)習(xí)使用CSS,感興趣的朋友可以了解下2021-04-27
CSS實現(xiàn)移動端橫向滾動導(dǎo)航條(PC端也適用)
這篇文章主要介紹了CSS實現(xiàn)移動端橫向滾動導(dǎo)航條(PC端也適用),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編2021-03-17CSS實現(xiàn)滾動高度自動變小的粘滯效果實現(xiàn)思路
粘滯效果是網(wǎng)頁設(shè)計中常見的特效之一,在這篇文章中,我們介紹了如何使用JavaScript監(jiān)聽窗口滾動事件,并根據(jù)滾動高度和下一個區(qū)域的高度來控制導(dǎo)航欄的表現(xiàn)方式,本文結(jié)合2023-06-13