微信开发者

滚动弹幕实现难?这样开发很简单

Image

开发大佬,我想提一个小小小需求Image

说吧……(通常说小需求,实际都很大Image)

Image
Image

我们的亲子教育小程序想要实现滚动弹幕效果

Image

固定显示20条分类信息

Image

一定要让用户看着觉得是实时滚动的感觉

听起来很简单,但其实做起来真的不容易……

Image

滚动弹幕效果不仅要求内容有序的匀速运动,而且要求不同长度的内容循环播放。生活中常见的滚动弹幕效果包含着非常多开发细节,同时也会遇到 “雷区”。接下来我们来看看如何实现滚动弹幕效果的全过程吧!

Image

01

Image

实现循环播放

滚动弹幕的突出特点便是循环不断地显示内容。对于相同的内容,循环播放则需要先将数组拷贝并且排列一排,使得第一个拷贝数组的结尾紧接着第二个拷贝数组的开头。

Image

<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 的 animation 属性,即可实现无限循环滚动。

Image

.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长度 }}
Image

02

Image

优化循环播放

实现固定内容循环播放后,我们就需要解决弹幕内容长度不一而导致的前后连接问题,因此需要获取单个数组所渲染的 dom 长度来得到长度变量。建议开发者按照以下步骤验证实现:
  • 判断 domWidth:如果 domWidth 为 0,先渲染由 1 个数组构成的静止 dom,不渲染 2 个数组组成的滚动弹幕 dom

  • 获取 domWidth:获取静止 dom 的长度,再渲染滚动弹幕 dom,最后把静止 dom 销毁

  • 执行动画:当 animation 进行初始化时,domWidth 的长度就是单个数组所渲染的 dom 长度,即可顺利执行动画

@keyframes rowScrollTest {  0% {    /* 为0时,ios会闪动 */    transform: translateX(1);  }
100% { transform: translateX(var(--domWidth--)); // 单个数组所渲染的dom长度 }}
<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>
对于多行弹幕的情况,开发者只需再执行 2 个步骤,即可实现多行滚动弹幕的效果:
  1. 复制多行数据,实现基本的样式设计

  2. 每一行数据设置 animation-delay 属性,错开执行动画

Image

Image

在信息量较多的小程序交互中,滚动弹幕效果是常见的交互方式,能够给予用户良好的体验。然而实现滚动弹幕效果并不简单,通过应用小程序 CSS 属性,开发者能够快速实现目标效果。还不快码下代码,创建你的滚动弹幕!

如有其他小程序应用相关的问题,可在 微信开放社区小程序交流专区 发帖互动,技术专员将为大家解答及进行深度交流。
原创|腾讯前端开发工程师 zelmazhou
Image