In order to facilitate future reuse, I packaged this as a separate component, use less directly on a single page can be
ordinary
Let’s look at the effect. The GIF screenshot tool has been a bit off lately… Go straight to code
Notice. WXML code
Change the CSS style of the image according to your personal situation
<! --components/notice/notice.wxml--> <view class="notice-container"> <image style="width:30rpx; height:30rpx; margin:0 20rpx" src="{{imagePath}}/station-nav.png"></image> <view class="content-wrapper"> <view class="content-text" animation="{{animationData}}"> <text id="text">{{text}}</text> </view> </view> <image style="width:30rpx; height:30rpx; margin-left:20rpx" src="{{imagePath}}/arrow-right.png"></image> </view>Copy the code
Notice the js code
Here part of the code can also be optimized, later have time to refactor it, for example, you can use ES6 deconstruction assignment; The scrolling time can also be dynamically passed in, as shown below
// components/notice/notice.js const { imageProPath } = require('.. /.. /utils/ imageurlutil.js ') Component({/** * list of Component properties */ properties: {// text: {type: String, value: }}, /** * initial data of component */ data: {animation: null, TextWidth: 0, wrapWidth: 0, // Container width setTimer: null, imagePath: imageProPath }, pageLifetimes: { show(){ this.initAnimation(this.data.text) }, hide(){ this.destroyTimer() this.setData({ timer: null, }) clearInterval(this.data.setTimer) } }, methods: InitAnimation (text){let that = this // Set the time this.data.duration = 10000 // Create the animation and select the animation node this.data.animation = wx.createAnimation({ duration: this.data.duration, timingFunction: 'linear' }) let query = wx.createSelectorQuery() query.select('.content-wrapper').boundingClientRect() Query. Select ('#text').boundingClientRect(); query. Exec ((rect) => {that.setData({wrapWidth: rect[0].width, textWidth: rect[1].width }, () => { this.startAnimation() }) }) }, // Set the timer startAnimation() {// Set the X offset and export the animation const resetAnimation = This. Data. Animation. TranslateX (this) data) wrapWidth). Step ({duration: 0}) / / export animation this. SetData ({animationData: resetAnimation.export() }) const animationData = this.data.animation.translateX(-this.data.textWidth).step({ duration: this.data.duration }) setTimeout(() => { this.setData({ animationData: animationData.export() }) }, 100) const timer = setTimeout(() => { this.startAnimation() }, this.data.duration) this.setData({ timer }) }, DestroyTimer () {if (this.data.timer) {clearTimeout(this.data.timer); // destroyTimer() {if (this.data.timer) {clearTimeout(this.data.timer); }}}})Copy the code
Notice. WXSS code
/* components/notice/notice.wxss */
.notice-container{
display: flex;
align-items: center;
justify-content: space-between;
padding: 10rpx 0;
margin: 16rpx 0 30rpx 0;
border-radius: 10rpx;
background-color: #FFCF80;
}
.content-wrapper {
width: 550rpx;
overflow: hidden;
}
.content-text {
color: #fff;
white-space: nowrap;
font-size: 24rpx;
}
Copy the code
use
It is introduced in the JSON file of the corresponding page and then used in WXML
More perverted
When I arrived at the company in the morning, the product told me that such scrolling was not good. I wanted to configure the color of the separate text and then scroll. I really wanted to **********!!!! . Anger hurts your body, so let’s function honestly
At first, WE wanted to iterate through the for loop directly and render each color directly, but after we finished, we found that there was a bug, because in this way, we have animation for each item and the time is the same: 10000. This is not good, let’s change the layout and JS slightly
Modified WXML
The outer envelope contains a box: box, which gets the box and each content-text width for dynamic calculation of textWidth and Duration
<view class="notice-wrapper" wx:if="{{noticeText.length}}"> <image style="width:30rpx; height:30rpx; margin:0 20rpx 0 50rpx" src="{{imagePath}}/icons/notice-icon.png"></image> <view class="box"> <! Here is a text scroll written using pure CSS --> <! -- <view class="animate" style="color:{{item.color}}" wx:for="{{noticeText}}" wx:key="index"> {{item.content}} </view> --> <view class="content-text" animation="{{animationData}}"> <view id="text" style="color:{{item.color}}" wx:for="{{noticeText}}" wx:key="index">{{item.content}}</view> </view> </view> </view>Copy the code
Box just adds a bit of plain CSS
/* Notification */. Notice-wrapper {display: flex; align-items: center; padding: 10rpx 0; border-radius: 10rpx; margin: 16rpx 0 30rpx 0; } .content-wrapper{ width: 450rpx; height: 40rpx; color: #F39800; overflow: hidden; } #text{ display: flex; margin-right: 30rpx; } .box { position: relative; display: flex; width: 450rpx; overflow: hidden; } .animate { display: flex; align-items: center; padding-left: 20px; font-size: 12px; color: #000; /* display: inline-block; white-space: nowrap; */ animation: 15s wordsLoopMarque linear infinite normal; } @keyframes wordsLoopMarque { 0% { transform: translateX(0px); -webkit-transform: translateX(0px); } 100% { transform: translateX(-100%); -webkit-transform: translateX(-100%); } } @-webkit-keyframes wordsLoopMarque { 0% { transform: translateX(0px); -webkit-transform: translateX(0px); } 100% { transform: translateX(-100%); -webkit-transform: translateX(-100%); }}Copy the code
Js can only modify the initAnimation and startAnimation methods
InitAnimation modify
initAnimation(text) { let that = this let query = wx.createSelectorQuery() Query.select ('.content-text').boundingClientRect() query.select('.box').boundingClientRect() // Sets the container width and text width Query. Exec ((rect) => {console.log(rect[1]) let boxWidth = rect[1].width // Set the time this.data.duration = 2500 * (rect[0].width/boxWidth) // Create the animation and select the animation node this.data.animation = wx.createAnimation({duration: this.data.duration, timingFunction: 'linear' }) that.setData({ textWidth: rect[0].width <= boxWidth ? boxWidth : rect[0].width, wrapWidth: boxWidth }, () => { this.startAnimation() }) }) },Copy the code
StartAnimation modify
StartAnimation () {/ / set the X axis offset and export animation const resetAnimation = this. Data. The animation. The translateX (this) data) wrapWidth). Step ({ Duration: 0}) // Export animation this.setData({animationData: Resetanimation.export ()}) const animationData = const animationData = this.data.animation.translateX(-(this.data.textWidth+this.data.wrapWidth)+100).step({ duration: this.data.duration }) setTimeout(() => { this.setData({ animationData: animationData.export() }) }, 100) const timer = setTimeout(() => { this.startAnimation() }, this.data.duration) this.setData({ timer }) },Copy the code