一、需求
- 公告文字仅限200字
- 公告内容仅限一行文字显示
- 公告内容持续滚动
二、解决思路
- 使用动画API(
),完成移动动画Animation.translate
- 使用定时器API(
),完成循环播放动画setInterval
注意:
- 微信小程序的动画API
,只有动画效果还原后,才能进行第二次动画translate
-
根据第一条,需要两个定时器:
第一个定时器:用于循环复原动画效果
第二个定时器:用于循环播放动画效果
- 两个定时器的执行回调函数之间的时间间隔不能相同,否则会导致动画无法正常播放
- 优化上述两个步骤为只用一个定时器来循环两个动画,采用中间睡眠一段时间,错开两个动画的播放开始时间
-
因为动画的偏移距离由公告内容长度决定,造成了动画播放速度与公告内容相关。
(动画的
:表示在该时间段内播放完整组动画)duration: 1000
三、实现效果
1.字幕第一次开始公告旁边(从右向左)滚动
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL0EjM4UDN1kTMxITMxgTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2.字幕第二次从屏幕左边从右向左)滚动
三、实现代码
1.
wxml
<view class='width border-box f-pl30 f-pr30 f-mt30 f-mb30'>
<form report-submit="true" bindsubmit="bindOpenAnnouncement">
<button class='btn-reset flex announcement order-box f-pl25 f-pr25' form-type="submit">
<view class='f-pl25 f-font24 f-pr25'>公告</view>
<view class='f-font24 s-32 announcement-context'>
<view animation="{{animationData}}" class="f-font24 s-32 announcement-text f-text-left">{{announcementText}}</view>
</view>
</button>
</form>
</view>
2.
wxss
(此处只展示关键样式,其余为基本样式不做展示)
.announcement {
color: #a0a0a0;
background: #fff0e3;
border-radius: 6rpx;
line-height: 66rpx;
height: 66rpx;
}
.announcement-context {
width: 580rpx;
/* 偏移出文本框的内容隐藏掉 */
overflow: hidden;
}
.announcement-text {
width: 570rpx;
/* 文字内容只做一行显示 */
white-space: nowrap;
}
3.
js
data: {
animationData: {}, //公告动画
announcementText: "营业时间从早上10点到晚上8点,支持预先下单,祝用餐愉快",//公告内容
},
onLoad: function(options) {
var that = this;
//创建动画实例
var animation = wx.createAnimation({
//此处以公告最长内容来设置动画持续时间(duration:决定整个动画播放的速度)
duration: 90000,
timingFunction: 'linear'
});
//偏移距离为公告内容的长度*字体大小(若字体大小使用rpx需要换算成px)
animation.translate(-Number(this.data.announcementText.length * 12),0).step();
this.setData({
animationData: animation.export()
});
// 循环播放动画关键步骤(使用两个定时器)
// 第一个定时器:将字幕恢复到字幕开始点(为屏幕左边)
this.recoveraAnimation = setInterval(function() {
animation.translate(255,0).step({duration:0});
this.setData({
animationData: animation.export()
});
}.bind(this), 90000);
// 第二个定时器:重新开始移动动画
this.restartAnimation = setInterval(function() {
animation.translate(-Number(this.data.announcementText.length * 12),0).step();
this.setData({
animationData: animation.export()
});
}.bind(this), 90001);
},
onUnload: function(){
//清除定时器
clearInterval(this.recoveraAnimation);
clearInterval(this.restartAnimation);
},
优化后的
js
/**
* 开启公告字幕滚动动画
* @param {String} announcementText 公告内容
* @return {[type]} [description]
*/
initAnimation: function(announcementText) {
var that = this;
//初始化动画
var animation = wx.createAnimation({
duration: 22500,
timingFunction: 'linear'
});
animation.translate(-Number(announcementText.length * 12), 0).step();
that.setData({
animationData: animation.export()
});
/****************************优化部分*******************************/
// 重新开始动画
that.restartAnimation = setInterval(function() {
animation.translate(255, 0).step({
duration: 0
});
that.setData({
animationData: animation.export()
});
// 延迟5再执行下个动画
that.sleep(5);
animation.translate(-Number(announcementText.length * 12), 0).step();
that.setData({
animationData: animation.export()
});
}.bind(this), 22500);
},
/**
* 睡眠时间
* @param {Number} num 需要延迟的时间长度
*/
sleep: function(num){
var nowTime = new Date();
var exitTime = nowTime.getTime() + num;
while(true){
nowTime = new Date();
if(nowTime.getTime() > exitTime)
return;
}
},