The demand is sombre:
The speaker notification at the top of the page, the content is not fixed, the width is not fixed, it is a carousel (carousel) effect, from left to right carousel (carousel), each play is paused for 1500ms ~ 2000ms
The first thing I thought about was css position: relative + animation. If the width is fixed, it’s okay to say, but the width is not fixed. If you use a percentage, the imagination is very good, but the reality is very skinny. The percentage is relative to the width of the parent element... so the pass is dropped
I also thought of dynamically generating keyframes, so as to dynamically obtain the width of sub-elements, then dynamically generate keyframes, and dynamically pass in offsets. I really can't
Then search for animation directly from the applet document, and I really found
the Animation API
So it's natural to use
look at the result
Don't nag, just click to view the code snippet: https://developers.weixin.qq.com/s/Ju3T3amk7oKc
Ideas:
page structure
<view class="integral-notice common-flex-between">
<view class="integral-notice-left">
<image class="integral-notice-left-icon" src="icon-horn.png" mode="aspectFill"></image>
</view>
<view class="integral-notice-right common-flex-start">
<view class="integral-notice-right-item notice_1" animation="{
{animationData}}">各位憧橙会员大家好,积分商城发货周期为一个月2次,每个月15号和30号发货,有问题请联系客服,谢谢!</view>
<!-- 这里之所以放两个一样的,是为了无缝衔接的滚动 -->
<view class="integral-notice-right-item notice_1" animation="{
{animationData}}">各位憧橙会员大家好,积分商城发货周期为一个月2次,每个月15号和30号发货,有问题请联系客服,谢谢!</view>
</view>
</view>
style code
/*通用flex水平方向垂直居中布局*/
.common-flex-between {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
}
.common-flex-around {
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: nowrap;
}
.common-flex-center {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
}
.common-flex-start {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
}
.integral-notice{
position: fixed;
left: 0;
top: 0;
background: #FEF6F0;
width: 750rpx;
height: 98rpx;
box-sizing: border-box;
padding-left: 24rpx;
padding-right: 24rpx;
}
.integral-notice-left{
box-sizing: border-box;
padding-right: 20rpx;
}
.integral-notice-left-icon{
display: block;
width: 38rpx;
height: 34rpx;
}
.integral-notice-right{
overflow: hidden;
}
.integral-notice-right-item{
white-space: nowrap;
color: #141418;
font-size: 28rpx;
letter-spacing: 2rpx;
height: 32rpx;
line-height: 34rpx;
position: relative;
left: 0;
top: 0;
}
Step One: Make It Move
js code
/**
* 页面的初始数据
*/
data: {
animationData: {
},
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
const query = wx.createSelectorQuery()
query.selectAll('.notice_1').boundingClientRect((res)=>{
let noticeWidth = res[0].width
this.startAnimation(noticeWidth)
})
query.exec()
},
startAnimation(left, duration = 10000) {
this.animation = wx.createAnimation()
let offset = -left
this.animation.left(offset).step({
duration,
timingFunction: 'linear'
})
this.setData({
animationData: this.animation.export()
})
},
备注
: Here you will find that it is activated, and it is executed once
No matter, change the code and let it execute回到起点
startAnimation(left, duration = 10000) {
this.animation = wx.createAnimation()
let offset = -left
this.animation.left(offset).step({
duration,
timingFunction: 'linear'
})
this.setData({
animationData: this.animation.export()
})
// 这里,让它回去起点,便于后边无限循环
setTimeout(() => {
this.animation.left(0).step({
duration: 0, // 时间为 0
timingFunction: 'step-start' // 这个是 动画第一帧就跳至结束状态直到结束
})
this.setData({
animationData: this.animation.export()
})
}, duration)
},
Seeing this, you will know how to do the animation played in an infinite loop. Wouldn’t it be good to do a recursion? Don't believe me, let's try it?
startAnimation(left, duration = 10000) {
this.animation = wx.createAnimation()
let offset = -left
this.animation.left(offset).step({
duration,
timingFunction: 'linear'
})
this.setData({
animationData: this.animation.export()
})
setTimeout(() => {
this.animation.left(0).step({
duration: 0,
timingFunction: 'step-start'
})
this.setData({
animationData: this.animation.export()
})
// 递归,无限循环播放
this.startAnimation(left, duration)
}, duration)
},
注意
: You will find that there are good times and bad times, nothing, add delay, add asynchronous, because although the code is executed synchronously, code execution + running takes time, 1ms, 5ms, 10ms is also time
startAnimation(left, duration = 10000, wait = 2000) {
this.animation = wx.createAnimation()
let offset = -left
this.animation.left(offset).step({
duration,
timingFunction: 'linear'
})
this.setData({
animationData: this.animation.export()
})
setTimeout(() => {
this.animation.left(0).step({
duration: 0,
timingFunction: 'step-start'
})
this.setData({
animationData: this.animation.export()
})
// 加上延迟,加上需求上的等待时间 wait
let minWait = 12 // 之所以给了个 minWait,是防止 bug,就是那个代码执行/运行时间,经测试,我这里 12ms 的延迟比较合适
setTimeout(() => {
this.startAnimation(left, duration, wait)
}, wait < minWait ? minWait : wait)
}, duration)
},
Ola, you're done,