微信小程序自定义组件内实现文字循环滚动,实现方法wx.createAnimation

722 阅读1分钟

1、wxml中代码

<view class='content-box'>
    <view class='content-text' animation="{{animationData}}">
        <text class="text">{{text}}</text>
    </view>
</view>

2、wxss中代码

// 因为是自定义组件,宽度是有组件外一层的view决定的,字体大小也是由外部继承
.content-box {
    overflow: hidden;
    width: 100%;
  }
  
  .content-text {
    white-space: nowrap;
    font-size: inherit;
  }

3、js中代码

Component({
    /**
     * 组件的属性列表
     */
    properties: {
        text: { // 文字从外部获取
            type: String,
            value: ''
        }
    },

    /**
     * 组件的初始数据
     */
    data: {
        animationData: null,
    },

    /**
     * 组件的方法列表
     */
    methods: {
        destroyTimer() {
            this.timer && clearTimeout(this.timer);
            this.timer = null;
        },
        /**
         * 开启公告字幕滚动动画
         */
        initAnimation() {
            const that = this
            // 无论滚动多少字都是15000ms
            this.duration = 15000
            // 创建动画
            this.animation = wx.createAnimation({
                duration: this.duration,
                timingFunction: 'linear'
            })
            // 这里有个坑,自定义组件用的是this.createSelectorQuery,页面里用的是wx.createSelectorQuery,一定注意,参考网址 
            // https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html
            const query = this.createSelectorQuery()
            query.select('.content-box').boundingClientRect()
            query.select('.text').boundingClientRect()
            query.exec((rect = []) => {
                // 外框宽度
                that.wrapWidth = (rect[0] || {}).width || 0;
                // 文字宽度
                that.textWidth = (rect[1] || {}).width || 0;
                // 如果文字宽度比外框宽度大,才会触发滚动
                if(that.wrapWidth < that.textWidth) {
                    that.startAnimation()
                }
            })
        },
        // 定时器动画
        startAnimation() {
            const that = this;
            // 将文字0s内放置到边框尾部动画(动画一)
            const resetAnimation = this.animation.translateX(this.wrapWidth).step({
                duration: 0
            })
            // 动画结束(动画一),其实就是位置改变,没有动画
            this.setData({
                animationData: resetAnimation.export()
            })
            // 将文字this.duration秒内移动到边框头部动画(动画二)
            const animationData = this.animation.translateX(-this.textWidth).step({
                duration: this.duration
            })
            // 动画结束(动画二)
            this.setData({
                animationData: animationData.export()
            })
            // 摧毁定时器
            this.destroyTimer();
            // 定义定时器,播放完成后,再次执行该方法动画
            this.timer = setTimeout(() => {
                that.startAnimation()
            }, this.duration)
        },
    },
    ready() { // 在组件布局完成后执行
        this.initAnimation();
    },
    detached() { // 组件移除时触发
        this.destroyTimer()
    }
})

4、页面中使用

1、肯定是在json文件里引用,路径一定要对;
2、在页面里运用;

<你的组件名 text="{{你的变量名}}" />