广告位联系
返回顶部
分享到

微信小程序纯CSS实现无限弹幕滚动效果

css 来源:互联网 作者:佚名 发布时间:2022-09-03 21:27:05 人浏览
摘要

啥也不说,先上效果图 实现背景 产品:我们需要一个弹幕滚动效果,类似于微博热搜那种实时评论,但是我们的数据是固定的20条,你让他一直循环滚动 我好的(os:要求真多) 实现

啥也不说,先上效果图

实现背景

产品: 我们需要一个弹幕滚动效果,类似于微博热搜那种实时评论,但是我们的数据是固定的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: 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添加动画即可

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 2s linear infinite;

}

 

@keyframes rowScrollTest {

  0% {

    /* 为0时,ios会闪动 */

    transform: translateX(1);

  }

 

  100% {

    transform: translateX(-433.85px); // 单个数组所渲染的dom长度

  }

}

效果如下

通过以下几句代码,并且没有使用任何的js代码就把无限循环滚动实现好了,是不是觉得事情到这儿结束了呢???

并没有

如何动态计算单个数组所渲染的dom长度

上面实现的代码中,对于单个数组所渲染的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参数

遇到这个问题时,感觉有点奇怪,这个动态的赋值一般是给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自定义属性(变量)** 的对比,所以会导致渲染失效,这个值一直都是初始值

解决animation执行时domWidth为0的问题

这个时候有一个简单的解决办法

  • 先判断如果domWidth为0,就再渲染一个由这个数组循环成的静止dom,并不渲染下面两个数组组成的滚动弹幕dom
  • 然后去获取这个静止dom的长度,获取完成了之后,再去渲染下面的滚动弹幕dom,并把静止dom给销毁掉
  • 那么当animation在初始化执行时,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来设置动画的开始或停止

总结

这篇文章,我把自己对于实现一个无限弹幕滚动需求的过程一一描述了一遍,把自己遇到的问题和思考的过程通过文字表述了出来,写的可能不是很好,希望可以勉励自己的同时也能帮助到看到这篇文章的朋友,如果你觉得我的废话太多,可以直接gitee地址去复制代码自己看一下,实现的代码量很少,也比较简单。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • CSS3浏览器兼容的介绍

    CSS3浏览器兼容的介绍
    一、浏览器兼容 1.1、概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题。不同浏览器其内核
  • CSS元素定位之通过元素的标签或者元素的id、cl

    CSS元素定位之通过元素的标签或者元素的id、cl
    大部分人在使用selenium定位元素时,用的是xpath元素定位方式,因为xpath元素定位方式基本能解决定位的需求。xpath元素定位方式更直观,更好
  • 微信小程序纯CSS实现无限弹幕滚动效果

    微信小程序纯CSS实现无限弹幕滚动效果
    啥也不说,先上效果图 实现背景 产品:我们需要一个弹幕滚动效果,类似于微博热搜那种实时评论,但是我们的数据是固定的20条,你让他
  • 使用CSS构建强大且酷炫的粒子动画效果

    使用CSS构建强大且酷炫的粒子动画效果
    粒子动画,顾名思义,就是页面上存在大量的粒子构建而成的动画。传统的粒子动画主要由 Canvas、WebGL 实现。 当然,不使用 HTML + CSS 的主要
  • flex:1的详细介绍

    flex:1的详细介绍
    简单的来说一下在别人问你这个问题的时候怎么来回答它 前端新人,如有错误求大佬指出~求教???? 情景复现 大佬提问:你知道flex: 1;的更深
  • 新的CSS伪类函数 :is 和 :where()示例介绍

    新的CSS伪类函数 :is 和 :where()示例介绍
    在编写 CSS 时,有时可能会使用很长的选择器列表来定位具有相同样式规则的多个元素。例如,如果您想对标题中的 b 标签进行颜色调整,我
  • 纯CSS打字动画的实现方法

    纯CSS打字动画的实现方法
    在一些技术网站中,经常会看到这样一种展示效果:逐个显示一段文本中的字符,模拟出一种打字的效果。通过这种方式可以显著地提升网
  • 实现el-form每行显示两列底部按钮居中效果的教程

    实现el-form每行显示两列底部按钮居中效果的教程
    el-form 每行显示两列,底部按钮居中 问题: 以前的解决办法是:el-col,el-row。但是这里只有一个el-form-item的label数据是已知的,其余项都是循
  • CSS实现六边形的图片效果的代码

    CSS实现六边形的图片效果的代码
    前言 在CodePen上看到一个有意思的效果: 这个效果的难点在于六边形的绘制, 那么接下来我们就一起来看下作者是怎么实现他的吧 实现思路
  • CSS浮动引起的高度塌陷问题的详细介绍

    CSS浮动引起的高度塌陷问题的详细介绍
    正常页面布局 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 style *{ margin:0; padding: 0; } .content{ width:400px; border:1px solid #000; } .box{ width:200px;
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计