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