-

动画

界面动画的常见方式

在小程序中,通常可以使用 CSS 渐变 和 CSS 动画 来创建简易的界面动画。

动画过程中,可以使用 bindtransitionend bindanimationstart bindanimationiteration bindanimationend 来监听动画事件。

事件名含义
transitionendCSS 渐变结束或 wx.createAnimation 结束一个阶段
animationstartCSS 动画开始
animationiterationCSS 动画结束一个阶段
animationendCSS 动画结束

注意:这几个事件都不是冒泡事件,需要绑定在真正发生了动画的节点上才会生效。

同时,还可以使用 wx.createAnimation 接口来动态创建简易的动画效果。(新版小程序基础库中推荐使用下述的关键帧动画接口代替。)

关键帧动画

基础库 2.9.0 开始支持,低版本需做兼容处理

从小程序基础库 2.9.0 开始支持一种更友好的动画创建方式,用于代替旧的 wx.createAnimation 。它具有更好的性能和更可控的接口。

在页面或自定义组件中,当需要进行关键帧动画时,可以使用 this.animate 接口:

this.animate(selector, keyframes, duration, callback)

参数说明

属性类型默认值必填说明
selectorString选择器(同 SelectorQuery.select 的选择器格式)
keyframesArray关键帧信息
durationNumber动画持续时长(毫秒为单位)
callbackfunction动画完成后的回调函数

keyframes 中对象的结构

属性类型默认值必填说明
offsetNumber关键帧的偏移,范围[0-1]
easeStringlinear动画缓动函数
transformOriginString基点位置,即 CSS transform-origin
backgroundColorString背景颜色,即 CSS background-color
bottomNumber/String底边位置,即 CSS bottom
heightNumber/String高度,即 CSS height
leftNumber/String左边位置,即 CSS left
widthNumber/String宽度,即 CSS width
opacityNumber不透明度,即 CSS opacity
rightNumber右边位置,即 CSS right
topNumber/String顶边位置,即 CSS top
matrixArray变换矩阵,即 CSS transform matrix
matrix3dArray三维变换矩阵,即 CSS transform matrix3d
rotateNumber旋转,即 CSS transform rotate
rotate3dArray三维旋转,即 CSS transform rotate3d
rotateXNumberX 方向旋转,即 CSS transform rotateX
rotateYNumberY 方向旋转,即 CSS transform rotateY
rotateZNumberZ 方向旋转,即 CSS transform rotateZ
scaleArray缩放,即 CSS transform scale
scale3dArray三维缩放,即 CSS transform scale3d
scaleXNumberX 方向缩放,即 CSS transform scaleX
scaleYNumberY 方向缩放,即 CSS transform scaleY
scaleZNumberZ 方向缩放,即 CSS transform scaleZ
skewArray倾斜,即 CSS transform skew
skewXNumberX 方向倾斜,即 CSS transform skewX
skewYNumberY 方向倾斜,即 CSS transform skewY
translateArray位移,即 CSS transform translate
translate3dArray三维位移,即 CSS transform translate3d
translateXNumberX 方向位移,即 CSS transform translateX
translateYNumberY 方向位移,即 CSS transform translateY
translateZNumberZ 方向位移,即 CSS transform translateZ

示例代码

在开发者工具中预览效果


  this.animate('#container', [
    { opacity: 1.0, rotate: 0, backgroundColor: '#FF0000' },
    { opacity: 0.5, rotate: 45, backgroundColor: '#00FF00'},
    { opacity: 0.0, rotate: 90, backgroundColor: '#FF0000' },
    ], 5000, function () {
      this.clearAnimation('#container', { opacity: true, rotate: true }, function () {
        console.log("清除了#container上的opacity和rotate属性")
      })
  }.bind(this))

  this.animate('.block', [
    { scale: [1, 1], rotate: 0, ease: 'ease-out'  },
    { scale: [1.5, 1.5], rotate: 45, ease: 'ease-in', offset: 0.9},
    { scale: [2, 2], rotate: 90 },
  ], 5000, function () {
    this.clearAnimation('.block', function () {
      console.log("清除了.block上的所有动画属性")
    })
  }.bind(this))

调用 animate API 后会在节点上新增一些样式属性覆盖掉原有的对应样式。如果需要清除这些样式,可在该节点上的动画全部执行完毕后使用 this.clearAnimation 清除这些属性。

this.clearAnimation(selector, options, callback)

参数说明

属性类型默认值必填说明
selectorString选择器(同 SelectorQuery.select 的选择器格式)
optionsObject需要清除的属性,不填写则全部清除
callbackFunction清除完成后的回调函数

滚动驱动的动画

我们发现,根据滚动位置而不断改变动画的进度是一种比较常见的场景,这类动画可以让人感觉到界面交互很连贯自然,体验更好。因此,从小程序基础库 2.9.0 开始支持一种由滚动驱动的动画机制。

基于上述的关键帧动画接口,新增一个 ScrollTimeline 的参数,用来绑定滚动元素(目前只支持 scroll-view)。接口定义如下:

this.animate(selector, keyframes, duration, ScrollTimeline)

ScrollTimeline 中对象的结构

属性类型默认值必填说明
scrollSourceString指定滚动元素的选择器(只支持 scroll-view),该元素滚动时会驱动动画的进度
orientationStringvertical指定滚动的方向。有效值为 horizontal 或 vertical
startScrollOffsetNumber指定开始驱动动画进度的滚动偏移量,单位 px
endScrollOffsetNumber指定停止驱动动画进度的滚动偏移量,单位 px
timeRangeNumber起始和结束的滚动范围映射的时间长度,该时间可用于与关键帧动画里的时间 (duration) 相匹配,单位 ms

示例代码

在开发者工具中预览效果

  this.animate('.avatar', [{
    borderRadius: '0',
    borderColor: 'red',
    transform: 'scale(1) translateY(-20px)',
    offset: 0,
  }, {
    borderRadius: '25%',
    borderColor: 'blue',
    transform: 'scale(.65) translateY(-20px)',
    offset: .5,
  }, {
    borderRadius: '50%',
    borderColor: 'blue',
    transform: `scale(.3) translateY(-20px)`,
    offset: 1
  }], 2000, {
    scrollSource: '#scroller',
    timeRange: 2000,
    startScrollOffset: 0,
    endScrollOffset: 85,
  })

  this.animate('.search_input', [{
    opacity: '0',
    width: '0%',
  }, {
    opacity: '1',
    width: '100%',
  }], 1000, {
    scrollSource: '#scroller',
    timeRange: 1000,
    startScrollOffset: 120,
    endScrollOffset: 252
  })

高级的动画方式

在一些复杂场景下,上述的动画方法可能并不适用。

WXS 响应事件 的方式可以通过使用 WXS 来响应事件的方法来动态调整节点的 style 属性。通过不断改变 style 属性的值可以做到动画效果。同时,这种方式也可以根据用户的触摸事件来动态地生成动画。

连续使用 setData 来改变界面的方法也可以达到动画的效果。这样可以任意地改变界面,但通常会产生较大的延迟或卡顿,甚至导致小程序僵死。此时可以通过将页面的 setData 改为 自定义组件 中的 setData 来提升性能。下面的例子是使用 setData 来实现秒表动画的示例。