在普通的网页开发中,动画效果可以通过css3来实现大部分需求,在小程序开发中同样可以使用css3,同时也可以通过api方式来实现。
API解读
小程序中,通过调用api来创建动画,需要先创建一个实例对象。这个对象通过wx.createAnimation返回,animation的一系列属性都基于这个实例对象。
创建这个对象
let animation = wx.createAnimation({
duration: 2000,
delay: 0,
timingFunction: "linear",
});这个animation就是通过wx.createAnimation之后返回的实例。在创建过程中,可以给这个实例添加一些属性,如以上代码所示,等同于css3中animation:$name 2s linear的写法。
添加动效
实例创建完成之后,基于该实例,添加需要的动态效果,动态类型可以查阅文档得知,以最常见的移动,旋转为例:
animation.translate($width, 0).rotate($deg);
结束动画
.step()表示一组动画的结束
animation.step();
导出动画
动画效果添加完成了,如何给想要的dom添加动效呢。这里需要用到.export()导出动画队列,赋值给某个dom对象。
this.setData({ moveOne: animation.export() }) <view animation="{{moveOne}}"></view>例子
以下将通过2组动画,来对比一下css3与api实现方式的不同。
一、模块移动动画
动画效果:
下图有两组动画,分别为api方式(上)与css3方式(下)完成的效果,点击move按钮,动画启动。

代码实现
以下分别为css3与api的核心代码:
css3:
<!-- wxml -->
<view class='border'>
<view class='css-block {{isMove && "one"}}'></view>
<view class='css-block {{isMove && "two"}}'></view>
<view class='css-block {{isMove && "three"}}'></view>
<view class='css-block {{isMove && "four"}}'></view>
</view> // scss
@mixin movePublic($oldLeft,$oldTop,$left,$top) {
from {
transform:translate($oldLeft,$oldTop);
}
to {
transform:translate($left,$top);
}
}
@mixin blockStyle($color,$name) {
background: $color;
animation:$name 2s linear infinite alternate;
}
.one {
@include blockStyle(lightsalmon,onemove);
}
@keyframes onemove {
@include movePublic(50rpx,-25rpx,-150rpx,0rpx);
}
.two {
@include blockStyle(lightblue,twomove);
}
@keyframes twomove {
@include movePublic(0rpx,25rpx,-50rpx,0rpx);
}
.three {
@include blockStyle(lightgray,threemove);
}
@keyframes threemove {
@include movePublic(0rpx,25rpx,50rpx,0rpx);
}
.four {
@include blockStyle(grey,fourmove);
}
@keyframes fourmove {
@include movePublic(-50rpx,-25rpx,150rpx,0rpx);
} // js
moveFunction(){
this.setData({
isMove: true
})
}css3中通过动态改变class类名来达到动画的效果,如上代码通过one、two、three、four来分别控制移动的距离,通过sass可以避免代码过于冗余的问题。(纠结如何在小程序中使用sass的童鞋请看这里哦:wechat-mina-template)
api:
moveClick(){
this.move(-75,-12.5,25,'moveOne');
this.move(-25,12.5, 0,'moveTwo');
this.move(25, 12.5,0,'moveThree');
this.move(75, -12.5,-25,'moveFour');
this.moveFunction(); // 该事件触发css3模块进行移动
},
// 模块移动方法
move: function (w,h,m,ele) {
let self = this;
let moveFunc = function () {
let animation = wx.createAnimation({
duration: 2000,
delay: 0,
timingFunction: "linear",
});
animation.translate(w, 0).step()
self.setData({ [ele]: animation.export() })
let timeout = setTimeout(function () {
animation.translate(m, h).step();
self.setData({
// [ele] 代表需要绑定动画的数组对象
[ele]: animation.export()
})
}.bind(this), 2000)
}
moveFunc();
let interval = setInterval(moveFunc,4000)
}效果图可见,模块之间都是简单的移动,可以将他们的运动变化写成一个公共的事件,通过向事件传值,来移动到不同的位置。其中的参数w,h,m,ele分别表示发散水平方向移动的距离、聚拢时垂直方向、水平方向的距离以及需要修改animationData的对象。
通过这种方法产生的动画,无法按照原有轨迹收回,所以在事件之后设置了定时器,定义在执行动画2s之后,执行另一个动画。同时动画只能执行一次,如果需要循环的动效,要在外层包裹一个重复执行的定时器到。
查看源码,发现api方式是通过js插入并改变内联样式来达到动画效果,下面这张动图可以清晰地看出样式变化。

打印出赋值的animationData,animates中存放了动画事件的类型及参数;options中存放的是此次动画的配置选项,transition中存放的是wx.createAnimation调用时的配置,transformOrigin是默认配置,意为以对象的中心为起点开始执行动画,也可在wx.createAnimation时进行配置。

二、音乐播放动画
上面的模块移动动画不涉及逻辑交互,因此新尝试了一个音乐播放动画,该动画需要实现暂停、继续的效果。
动画效果:

两组不同的动画效果对比,分别为api(上)实现与css3实现(下):

代码实现
以下分别是css3实现与api实现的核心代码:
css3:
<!-- wxml -->
<view class='music musicTwo musicRotate {{playTwo ? " ": "musicPaused"}} ' bindtap='playTwo'>
<text class="iconfont has-music" wx:if="{{playTwo}}"></text>
<text class="iconfont no-music" wx:if="{{!playTwo}}"></text>
</view> // scss
.musicR

