时间:2022-09-12来源:www.pcxitongcheng.com作者:电脑系统城
产品: 我们需要一个弹幕滚动效果,类似于微博热搜那种实时评论,但是我们的数据是固定的20条,你让他一直循环滚动
我 好的(os:要求真多)
你不是说要微博热搜弹幕那种效果吗?这好办啊,马上去微博看热搜(又看到那么多塌房的的明星),看了几十分钟,表面上是多研究研究,实则上班期间光明正大的摸鱼,感觉真好!!
分析一下,有以下几个功能点
一共三个功能点,对比我的需求只有一个功能点相差,我只需要把弹幕实时更新改成弹幕循环滚动。
如果要实现一个循环的感觉就必须要把数组拷贝一份,把他们一排排列,然后这样子让他去滚动,当滚动结尾的时候,展示第二个拷贝数组的开头。animate
动画帧的编写就改变transform:translateX
的值,从0
到单个数组所渲染的dom长度
,第一次的动画执行完成后,刚好是第二个拷贝数组的开头,然后又让动画帧执行从0
到单个数组所渲染的dom长度
,由于每一次动画执行完刚好是第二个拷贝数组的开头,所以执行第二次动画时不会有闪动的感觉
设置animation-iteration-count: infinite;
,循环执行,这样子就会无限的从0
到单个数组所渲染的dom长度
,无限的循环套娃,就会有循环滚动的感觉了,大概图如下
overflow: hidden
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<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> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
.z-bullet-test { width : 690 rpx; height : 88 rpx; display : flex; align-items: center ; background-color : saddlebrown; margin : 0 auto ; margin-top : 40 rpx; overflow : hidden ; } .z-container { display : flex; flex-wrap: nowrap ; } .z-single { padding : 10 rpx 40 rpx; color : white ; background-color : cadetblue; margin-right : 20 rpx; } .z-list { display : flex; flex-wrap: nowrap ; } |
效果如下
z-list
添加动画即可1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.z-list { display : flex; flex-wrap: nowrap ; animation: rowScrollTest 2 s linear infinite; } @keyframes rowScrollTest { 0% { /* 为0时,ios会闪动 */ transform: translateX( 1 ); } 100% { transform: translateX( -433.85px ); // 单个数组所渲染的dom长度 } } |
效果如下
通过以下几句代码,并且没有使用任何的js代码就把无限循环滚动实现好了,是不是觉得事情到这儿结束了呢???
并没有
上面实现的代码中,对于单个数组所渲染的dom长度
是通过开发者工具找到dom长度,并在代码中写死的,但是在开发中你并不能确定这个长度到底为多少,这个时候我们需要去动态获取这个dom长度
这个时候就有同学说了,那还不简单直接通过js去获取dom长度不就可以了吗?
想法很不错,先给你点个赞,但是重点来了!!!注意看,通过js获取dom长度可以得到一个长度变量,但是你如何动态赋值给@keyframes
动画帧呢??
1 2 3 4 5 6 7 8 9 10 |
@keyframes rowScrollTest { 0% { /* 为0时,ios会闪动 */ transform: translateX( 1 ); } 100% { transform: translateX(domWidth); // 单个数组所渲染的dom长度 } } |
思考一下?这个domWidth
应该如何去动态的赋值呢?
遇到这个问题时,感觉有点奇怪,这个动态的赋值一般是给css属性,如width
,height
,还没有给动画帧中的css属性动态赋值过,
于是照着给css属性动态赋值的方法,我把@keyframes
动画帧函数先写到了行内style
上,并把css中的@keyframes
动画帧函数删除
1 2 3 |
<view class= "z-list" style= "@keyframes rowScrollTest {0% { transform: translateX(1); } 100% { transform: translateX(-433.85px); }}" > <!-- 数组内容 --> </view> |
满心欢喜的打开开发者工具,一看~~ 嘿! 动都不动了
原因是因为style属性只能识别出css的属性名,我在这里写的动画帧函数,在它看来就是一串没有用的字符串,所以就根本不会编译成css的动画帧函数,就肯定不会有作用了
传统的给css属性动态赋值的方法走不通,应该怎么办呢?99%解决问题的办法:点开goole然后再输入栏输入这个问题,按下enter键,然后就去疯狂的寻找就可以了。
经过一番查找,嘿还真找到了一个东西,css自定义属性(变量),这是个啥呢?
MDN解释:自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black;
),由 var() 函数来获取值(比如: color: var(--main-color);
)复杂的网站都会有大量的 CSS 代码,通常也会有许多重复的值。
那我们是不是可以动态赋值给这个变量,并在css代码的@keyframes
动画帧函数中去使用这个变量的值,当作translateX
的值呢,立马试一下
1 2 3 |
<view class= "z-list" style= "--domWidth--:-433.85px;" > <!-- 数组内容 --> </view> |
1 2 3 4 5 6 7 8 9 10 |
@keyframes rowScrollTest { 0% { /* 为0时,ios会闪动 */ transform: translateX( 1 ); } 100% { transform: translateX(var(--domWidth--)); // 单个数组所渲染的dom长度 } } |
激动的打开开发者工具,见证奇迹的时刻到来了!!!!!!!!! 它动了,它在疯狂的滚动着
接下来是不是只需要将-433.85
改成js获取的单个数组所渲染的dom长度
就可以了呢?,于是我满心欢喜的去写js代码了,先定义一个变量domWidth: 0
,然后再去onLoad
中去获取z-container
的长度并赋值给domWidth
,动态的获取单个数组所渲染的dom长度
并赋值给@keyframes
动画帧函数,就大功告成了!!(其实并没有,不要看到这儿就不看了!)
1 2 3 |
<view class= "z-list" style= "--domWidth--:-{{domWidth}}px;" > <!-- 数组内容 --> </view> |
1 2 3 4 5 6 7 8 9 10 11 |
data: { domWidth: 0 }, onLoad () { wx.createSelectorQuery() .selectAll( ".z-container" ) .boundingClientRect((res) => { this.setData({ domWidth: res[ 0 ].width }); }) .exec(); } |
这个时候我轻松的点开开发者工具,心里想着这个问题被我轻松解决掉了,还剩很多开发时间,可以去摸鱼了,但是它不动了,一点都不动了!
为什么呢? 我立马点开控制台,找到了这个变量的值,发现他是有值的,说明问题不出在js获取长度,
我仔细一想瞬间明白了 domWidth
的值默认为0,animation
属性会在被渲染出来时立即执行,这个时候的domWidth
还为0,动画帧函数就相当于是从0到0,肯定就不会滚动了,你可以把domWidth
随便设置一个初始值,你就会发现它会动了
那为什么css属性为0时,动态设置会变化呢? 我觉得是因为微信小程序本身对于setData
这个函数,根据改变的data
去进行重新渲染时,就没有包含对**css自定义属性(变量)** 的对比,所以会导致渲染失效,这个值一直都是初始值
这个时候有一个简单的解决办法
domWidth
为0,就再渲染一个由这个数组循环成的静止dom,并不渲染下面两个数组组成的滚动弹幕domanimation
在初始化执行时,domWidth
的长度就已经是单个数组所渲染的dom长度
,就可以顺利的去执行动画了1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<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> |
这样子就真的大功告成了!!
多行弹幕滚动的话,你就多复制几行就可以了,并且可以给每一行设置一个animation-delay
属性,让他们不要同时执行animation,去岔开时间来执行,实现一个比较乱的弹幕效果。
对于一个循环动画,你如果要动态的设置它开始或停止,可以通过animation-play-state
属性设置running
或paused
来设置动画的开始或停止
2023-03-06
css3鼠标滑过实现动画线条边框2023-03-06
css scroll-snap控制滚动元素的实现2023-03-06
CSS实现多层嵌套列表自动编号的示例代码传统的灰色纯色边框你是不是觉得太难看了?你是否想设计一些精美的边框,例如渐变、圆角、彩色的边框?那你来对地方了,本文将介绍如何用纯CSS就能实现具有渐变和圆角的彩色边框...
2023-03-06
今天给大家带来一个如何实现圆角三角形的方案,这个方案虽然可以实现,但是也是借助拼凑等方式来实现的,假如想一个div来实现圆角三角形,还是比较困难的。之前文章讲了如何实现对话框,里面介绍了三角形的实现方式。今天讲讲...
2023-03-06