微信小程序--动画animation

967 阅读3分钟

TOC

一. 获取需要实现动画效果的元素

1. 微信小程序获取元素节点:

注意获取元素节点方法为 异步调用 ,因此使用promise,确保节点获取到值后再返回获取的width宽度。

//  参数:select -> 想要获取的节点的类名,使用: getRect(".className") 
 getRect(select) {
      const _this = this;
      return new Promise((resolve,reject)=>{
        _this.createSelectorQuery()
            .select(select)
            .boundingClientRect(rects => {
                if(rects){
                    resolve(Math.ceil(rects.width));
                }
        }).exec();
      })
    },

2. 合适的生命周期调用

工具函数写完后,调用获取元素属性,注意生命周期函数使用 ready而非 create 。另外,前面提到获取元素属性的函数是异步的,因此使用了promise,因此在这个步骤使用 promise.all() 获取得到的全部数据并赋值给data中的数据。

ready(){
	Promise.all([
        this.getRect('.text'),
        this.getRect('.wrap')
      ]).then( (arr) => {

        this.setData ({
          textRect : arr[0],
          wrapRect : arr[1]
        })
        ... 逻辑 ....
      })
}

二、动画

1. 创建动画

(1)使用 wx.createAnimation() 函数创建一个动画对象,内含四个参数(参数不细说,详情参考官方API)。

官方API:developers.weixin.qq.com/miniprogram…

(2)在创建后的动画对象上执行操作,例子中是比较简单的平行移动,注意,在每一个动画结束后用.step()函数,根据这一特性,可有多个动画,如:

animation.translateX(50).step().translateX(-50).step();

// 动画逻辑函数
 scroll(duration,timingFunction,delay) {
      var animation = wx.createAnimation({
        duration: duration, 
        timingFunction: timingFunction,
        delay: delay
      });
      
      animation.translateX(50).step(); // 移动

      this.setData({
        animation:  animation.export()
      });
    },

2. 监听动画

在实际运用中,我们往往不止是让动画动起来,有时可能还需要监听动画的状态,来进行不同时期的逻辑操作。

动画状态官方API:developers.weixin.qq.com/miniprogram…

此处贴上绑定动画此刻状态的函数,如下所示:

//  page页面标签  绑定监听
<view class="wrap">
      <view 
         class="text" 
         animation="{{ani}}" 
         bindtransitionend="transitionEnd"  ---动画结束
         bindanimationstart="animationStart"  ---动画开始
         bindanimationiteration="animationIteration"  ---动画进行中>
         {{ text }}
      </view>
   </view>

下面是js中对应的方法:

// index.js函数中的监听方法
 methods: {
    transitionEnd () {
      console.log('动画已结束');
      ...逻辑处理...
    },
    animationStart() {
      console.log('动画已开始');
      ...逻辑处理...
    },
    animationIteration () {
      console.log('动画进行中');
      ...逻辑处理...
    },
}

3. 动画循环播放

实现动画循环播放这里可能会有争议,我在其他的文章里看见基本上所有的逻辑就是对动画计数,不太适合我这里的逻辑,因此我根据自己的想法实现这个循环的效果,后续如果有更好的方式,会附加在下面。 逻辑:

做微信小程序组件库中的noticeBar循环播放的效果,在一条消息移动结束后,又从头开始播放,实现一个广播的动画。

 transitionEnd() {
      const _this = this;
      // 复位操作
      this.initAnimation(0, 'linear', 0, 0);
      // 延时,没有延时函数动画不生效
      setTimeout(()=>{
        _this.scroll(....参数);
      },20);
    },

关于这部分代码中心想法: 因为循环在我看来就是动画结束之后再进行一遍刚刚的动作,因此我将循环的逻辑放在了每一个动画的结尾,上面提到监听动画结束的函数作用就在此,在每一个动画结束后,对元素进行复位操作,将其恢复到初始的状态,再重新执行动画。 注意:这里scroll函数外必须有延时函数,延时时间也不能过短,否则循环不生效。