8.7.4 动画
wx.createAnimation(OBJECT)
创建一个动画实例animation。调用实例的方法来描述动画。最后通过动画实例的export方法导出动画数据传递给组件的animation属性。
OBJECT参数说明(表8-63):
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
duration | Integer | 否 | 动画持续时间,单位ms,默认值 400 |
timingFunction | String | 否 | 定义动画的效果,默认值"linear",有效值:"linear","ease","ease-in","ease-in-out","ease-out","step-start","step-end" |
delay | Integer | 否 | 动画延迟时间,单位 ms,默认值 0 |
transformOrigin | String | 否 | 设置transform-origin,默认为"50% 50% 0" |
示例代码:
var animation = wx.createAnimation({
transformOrigin: "50% 50%",
duration: 1000,
timingFunction: "ease",
delay: 0
})
这四个属性里比较简单的是duration与delay,timingFunction定义了动画的播放方式,其定义如下:
- linear 默认为linear 动画一直较为均匀
- ease 开始时缓慢中间加速到快结束时减速
- ease-in 开始的时候缓慢
- ease-in-out 开始和结束时减速
- ease-out 结束时减速
- step-start 动画一开始就跳到 100% 直到动画持续时间结束 一闪而过
- step-end 保持 0% 的样式直到动画持续时间结束 一闪而过
在示例代码里定义了timingFunction为ease,如果动画效果为从左向右平移的话,设置ease会导致一开始移动速度较慢,然后逐渐加速,在路程中间速度达到最大值,然后再减速直到终点时停止。不设置此属性的话,采用默认值则会已匀速平移。
在解释transformOrigin之前我们先明确小程序上的坐标轴(图8-12):
图8-12 小程序坐标示意图
x轴,y轴分别代表了手机上的水平方向与竖直方向,z轴则是垂直于手机屏幕的轴。
transformOrigin里的三个参数就是在这三个轴上的坐标,通过这三点来获取空间上的一个点,动画效果则是以这个点为中心来实现的。默认的值为“50% 50% 0”也就是组件的中心位置,改变这个属性会影响动画的效果,在后边会举例说明。
animation
动画实例可以调用以下方法来描述动画,调用结束后会返回自身,支持链式调用的写法,具体的步骤为:
创建一个动画实例animation。调用实例的方法来描述动画。最后通过动画实例的export方法导出动画数据传递给组件的animation属性。
调用动画操作方法后要调用 step() 来表示一组动画完成,可以在一组动画中调用任意多个动画方法,一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。step 可以传入一个跟 wx.createAnimation() 一样的配置参数用于指定当前组动画的属性。
注意: export 方法每次调用后会清掉之前的动画操作。
样式(表8-64): 表8-64
方法 | 参数 | 说明 |
---|---|---|
opacity | value | 透明度,参数范围 0~1 |
backgroundColor | color | 颜色值 |
width | length | 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值 |
height | length | 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值 |
top | length | 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值 |
left | length | 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值 |
bottom | length | 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值 |
right | length | 长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值 |
这些属性大家肯定不陌生,这与我们在编写wxss文件时使用的属性值一样,即我们可以通过调用动画API来直接更改组件的属性以达到动画的效果。
Page({
data: { //设置用于存储animation的data
animationData: {}
},
onShow: function(){
var animation = wx.createAnimation({ //创建animation实例
duration: 1000,
timingFunction: 'ease',
})
this.animation = animation //获取实例
animation.width(400).height(400).step() //将组件的宽高设置为400
this.setData({
animationData:animation.export() //使用export()将写好的动画效果加载进去
})
})
在布局文件里我们为想要实现动画的组件添加animation的属性:
<view class="animation-element" animation="{{animation}}"></view>
如果这个组件的宽高为200px的话,则我们的动画效果会使他变大一倍。
旋转(表8-65): 表8-65
方法 | 参数 | 说明 |
---|---|---|
rotate | deg | deg的范围-180~180,从原点顺时针旋转一个deg角度 |
rotateX | deg | deg的范围-180~180,在X轴旋转一个deg角度 |
rotateY | deg | deg的范围-180~180,在Y轴旋转一个deg角度 |
rotateZ | deg | deg的范围-180~180,在Z轴旋转一个deg角度 |
rotate3d | (x,y,z,deg) | 同transform-function rotate3d |
缩放(表8-66): 表8-66
方法 | 参数 | 说明 |
---|---|---|
scale | sx,[sy] | 一个参数时,表示在X轴、Y轴同时缩放sx倍数;两个参数时表示在X轴缩放sx倍数,在Y轴缩放sy倍数 |
scaleX | sx | 在X轴缩放sx倍数 |
scaleY | sy | 在Y轴缩放sy倍数 |
scaleZ | sz | 在Z轴缩放sy倍数 |
scale3d | (sx,sy,sz) | 在X轴缩放sx倍数,在Y轴缩放sy倍数,在Z轴缩放sz倍数 |
偏移(表8-67): 表8-67
方法 | 参数 | 说明 |
---|---|---|
translate | tx,[ty] | 一个参数时,表示在X轴偏移tx,单位px;两个参数时,表示在X轴偏移tx,在Y轴偏移ty,单位px。 |
translateX | tx | 在X轴偏移tx,单位px |
translateY | ty | 在Y轴偏移tx,单位px |
translateZ | tz | 在Z轴偏移tx,单位px |
translate3d | (tx,ty,tz) | 在X轴偏移tx,在Y轴偏移ty,在Z轴偏移tz,单位px |
倾斜(表8-68): 表8-68
方法 | 参数 | 说明 |
---|---|---|
skew | ax,[ay] | 参数范围-180~180;一个参数时,Y轴坐标不变,X轴坐标延顺时针倾斜ax度;两个参数时,分别在X轴倾斜ax度,在Y轴倾斜ay度 |
skewX | ax | 参数范围-180~180;Y轴坐标不变,X轴坐标延顺时针倾斜ax度 |
skewY | ay | 参数范围-180~180;X轴坐标不变,Y轴坐标延顺时针倾斜ay度 |
矩阵变形(表8-69): 表8-69
方法 | 参数 | 说明 |
---|---|---|
matrix | (a,b,c,d,tx,ty) | 同transform-function matrix |
matrix3d | 同transform-function matrix3d |
示例代码:
<view class="animation-element-wrapper">
<view class="animation-element" animation="{{animation}}"></view>
</view>
<view class="btn-area">
<button class="animation-button" bindtap="rotate">旋转</button>
<button class="animation-button" bindtap="scale">缩放</button>
<button class="animation-button" bindtap="translate">移动</button>
<button class="animation-button" bindtap="skew">倾斜</button>
</view>
Page({
onReady: function () {
this.animation = wx.createAnimation()
},
rotate: function () {
this.animation.rotate(Math.random() * 720 - 360).step()
this.setData({animation: this.animation.export()})
},
scale: function () {
this.animation.scale(Math.random() * 2).step()
this.setData({animation: this.animation.export()})
},
translate: function () {
this.animation.translate(Math.random() * 100 - 50, Math.random() * 100 - 50).step()
this.setData({animation: this.animation.export()})
},
skew: function () {
this.animation.skew(Math.random() * 90, Math.random() * 90).step()
this.setData({animation: this.animation.export()})
},
})
这里面使用了Math.random()来随机生成一个0~1之间的数,以此来实现每次点击旋转随机角度等效果。
运行结果为:
原图(图8-13):
图8-13 动画API示例-原图
动画后(图8-14):
图8-14 动画API示例-效果图
回到一开始所说的问题,现在我们在createAnimation()里添加transformOrigin属性。
onReady: function () {
this.animation = wx.createAnimation({
transformOrigin:"0% 0%"
})
},
结果是(图8-15):
图8-15 动画API示例-改变动画基准点后效果图
可以看到除了偏移以外,其他结果都有了明显变化,这是因为动画的中心点发生了变化。以旋转来说,默认(50% 50%)是以白色方块的中心旋转,所以在旋转后白色方块还处于整个屏幕中间,而改成“0% 0%”之后,旋转动画就是以白色方块的左上角坐标来旋转了,所以产生了不同的效果。
除了这样一次执行一个动画以外,我们还可以让多个动画效果同时发生:
rotateAndScale: function () {
this.animation.rotate(Math.random() * 720 - 360)
.scale(Math.random() * 2)
.step()
this.setData({animation: this.animation.export()})
},
也可以让动画依次按顺序发生:
rotateThenScale: function () {
this.animation.rotate(Math.random() * 720 - 360).step()
.scale(Math.random() * 2).step()
this.setData({animation: this.animation.export()})
},
可以看到代码通过step()来将动画分为一段一段,每个step前的动画会同时发生,多个step依次发生。
另外在参数表里未详细说明的rotate3d表示组件在三维空间旋转,4个参数(x,y,z,deg)分别代表是否沿x轴,y轴,z轴旋转以及旋转的角度,“1”表示是,“0”表示否。例如(1,0,0,45deg)表示沿x轴旋转45度。
矩阵部分:matrix利用传入的6个参数构建矩阵,再用这个矩阵与现有坐标相乘,从而使坐标改变,达到动画效果。实际上本节所有的动画API都是用矩阵完成的。图8-16说明了这种坐标是如何改变的。
图8-16 matrix原理图
现有坐标(x,y)调用matrix(a,b,c,d,e,f)后,坐标变为(ax+cy+e,bx+dy+f)。
matrix3d则更复杂,需要的参数也更多,但本质上与matrix相同。