小程序文字通告栏(文字向左无限滚动)

这个功能我是封装成了组件,方便以后的复用,如果用的少的可以单独在页面写


普通的


先看效果。gif截图工具最近有点不太正常。。。。。。上代码
在这里插入图片描述

notice.wxml代码

图片的css样式根据个人情况修改下吧

<!--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>

notice.js代码

这里部分代码还能优化一下,以后有时间在重构一下吧,比如可以用es6的解构赋值;
还有像下面的滚动时间也可以是动态传入的,懒得改了

// components/notice/notice.js
const { imageProPath } = require('../../utils/imageUrlUtil.js')

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //文字内容
    text: {
      type: String,
      value: '我是文字我是文字我是文字我是文字'
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    animation: null, //文字滚动动画集
    timer: null, //定时器
    duration: 0, //设置滚动速度,数值越大速度越慢
    textWidth: 0, //文本宽度
    wrapWidth: 0, //容器宽度
    setTimer: null,
    imagePath: imageProPath
  },

  pageLifetimes: {
    show(){
      this.initAnimation(this.data.text)
    },
    hide(){
      
      this.destroyTimer()
      this.setData({
        timer: null,
      })
      clearInterval(this.data.setTimer)
    }
  },

  methods: {
    //初始化动画,text为公告内容
    initAnimation(text){
      let that = this
      //设置时间
      this.data.duration = 10000
      //创建动画并选择动画节点
      this.data.animation = wx.createAnimation({
        duration: this.data.duration,
        timingFunction: 'linear'
      })
      let query = this.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()
        })
      })
    },
    // 为定时器设置动画
    startAnimation() {
      // 设置X轴的偏移位置并导出动画
      const resetAnimation = this.data.animation.translateX(this.data.wrapWidth).step({
        duration: 0
      })
      //导出动画
      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);
      }
    }
  }
})

notice.wxss代码

/* 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;
}

使用

在json文件中引入这个组件
在这里插入图片描述

在wxml调用
在这里插入图片描述


更加变态的


大早上刚到公司,产品和我说这样的滚动不太好啊,我想配置单独文字的颜色,然后进行滚动,我当时真想**********!!!!。生气伤身体,老老实实实现功能吧

刚开始本想直接for循环遍历的,然后直接渲染每个颜色的,做完之后发现不对有bug啊,因为这样每个item我们都带有animation,并且时间都是一样的:10000,这样不行,来稍微改一下布局和js

修改后的wxml

最外面包裹了一个盒子:box,获取到box和每个content-text宽度进行动态计算textWidth和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">
		<!-- 这里是使用纯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>

box只是加了一点普通的css

/* 通知栏 */
.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%);
  }
}

js也只是修改initAnimation和startAnimation这两个方法就好

initAnimation修改

initAnimation(text) {
      let that = this
      let query = wx.createSelectorQuery()
      query.select('.content-text').boundingClientRect()
      query.select('.box').boundingClientRect()
      // 设置容器宽度和文本宽度
      query.exec((rect) => {
        console.log(rect[1])
        let boxWidth = rect[1].width
        //设置时间
        this.data.duration = 2500 * (rect[0].width / boxWidth)
        //创建动画并选择动画节点
        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()
        })
      })
    },

startAnimation修改

startAnimation() {
      // 设置X轴的偏移位置并导出动画
      const resetAnimation = this.data.animation.translateX(this.data.wrapWidth).step({
        duration: 0
      })
      //导出动画
      this.setData({
        animationData: resetAnimation.export()
      })
      //这里是主要修改的地方
      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
      })
    },
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值