宝哥软件园

开发小程序动画的两种方案

编辑:宝哥软件园 来源:互联网 时间:2021-12-04

在普通的网页开发中,动画效果可以通过css3达到大部分的要求。在小程序开发中,也可以使用css3,也可以通过api实现。

指南:applet animatom动画API

API解读

小程序中,要通过调用api创建动画,需要先创建一个实例对象。这个对象是通过wx.createAnimation返回的,Animation的一系列属性都是基于这个实例对象的。

创建这个对象

让动画=wx . createanimation({ duration : 2000,delay: 0,timingFunction: ' linear ',});复制代码的动画是传递wx.createAnimation后返回的实例,在创建的过程中,可以给这个实例添加一些属性,如上面的代码所示,相当于在css3中编写了animation: $ name 2s linear。

创建

添加动效

实例后,基于该实例添加所需的动态效果,通过查阅文档可以找到动态类型。以最常见的运动和旋转为例:

animation.translate($width,0)。旋转($ deg);复制代码

结束动画

。step()表示一组动画的结束。

animation . step();复制代码

导出动画

。添加了动画效果。如何给想要的dom添加动画效果?在这里,我们需要使用。export()导出动画队列并将其分配给dom对象。

这个。setdata({ move : animation . export()})复制代码view animation=' { { move 360010 } '/view复制代码

例子

下面两组动画将用于比较css3和api实现之间的差异。

一、模块移动动画

动画效果:

下图有两组动画,分别是api方法(上图)和css3方法(下图)的效果。单击移动按钮开始动画。

两种方案开发小程序动画(图1)

代码实现

以下分别是css3和api的核心代码:

css3:

!-wxml-View class=' border ' View class=' CSS-block { { is move ' one ' } } '/View View class=' CSS-block { { is move ' two ' } } '/View class=' CSS-block { { is move ' three ' } '/View class=' CSS-block { { is move ' four ' } '/View/View copy code//SCSS @ mixinmovepublic($ old left,$ oldtop,$left,$ top){ from { transform : translate($ old left} to { transform : translate($ left,$ top);} } @mixin blockStyle($color,$ name){ background : $ color;animation: $ name 2s线性无限交替;} .one { @ include block style(light almon,one move);} @关键帧one move { @ include move public(50 rpx,-25rpx,-150rpx,0rpx);} .两个{ @包含blockStyle(浅蓝色,two move);

} @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插入并改变内联样式来达到动画效果,下面这张动图可以清晰地看出样式变化。

两种方案开发小程序动画(图2)

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

两种方案开发小程序动画(图3)

二、音乐播放动画

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

动画效果:

两种方案开发小程序动画(图4)

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

两种方案开发小程序动画(图5)

代码实现

以下分别是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    .musicRotate{        animation: rotate 3s linear infinite;    }        @keyframes rotate{        from{            transform: rotate(0deg)        }        to{            transform: rotate(359deg)        }    }        .musicPaused{        animation-play-state: paused;    }复制代码
// js    playTwo(){        this.setData({            playTwo: !this.data.playTwo        },()=>{            let back = this.data.backgroundAudioManager;            if(this.data.playTwo){                back.play();            } else {                back.pause();            }        })    }复制代码

通过playTwo这个属性来判断是否暂停,并控制css类的添加与删除。当为false时,添加.musicPaused类,动画暂停。

api:

<!-- wxml -->    <view class='music' bindtap='play'  animation="{{play && musicRotate}}">        <text class="iconfont has-music" wx:if="{{play}}"></text>        <text class="iconfont no-music" wx:if="{{!play}}"></text>    </view>复制代码
// js    play(){        this.setData({            play: !this.data.play        },()=>{            let back = this.data.backgroundAudioManager;            if (!this.data.play) {                back.pause();               // 跨事件清除定时器               clearInterval(this.data.rotateInterval);            } else {                back.play();                // 继续旋转,this.data.i记录了旋转的程度                this.musicRotate(this.data.i);            }        })    },    musicRotate(i){        let self = this;        let rotateFuc = function(){            i++;            self.setData({                i:i++            });            let animation = wx.createAnimation({                duration: 1000,                delay: 0,                timingFunction: "linear",            });            animation.rotate(30*(i++)).step()            self.setData({ musicRotate: animation.export() });        }        rotateFuc();        let rotateInterval = setInterval(            rotateFuc,1000        );        // 全局定时事件        this.setData({            rotateInterval: rotateInterval        })    }复制代码

通过api实现的方式是通过移除animationData来控制动画,同时暂停动画也需要清除定时器,由于清除定时器需要跨事件进行操作,所以定了一个全局方法rotateInterval。

api方式定义了旋转的角度,但旋转到该角度之后便会停止,如果需要实现重复旋转效果,需要通过定时器来完成。因此定义了变量i,定时器每执行一次便加1,相当于每1s旋转30°,对animation.rotate()中的度数动态赋值。暂停之后继续动画,需要从原有角度继续旋转,因此变量i需要为全局变量。

代码变化

下图可以看出,api方式旋转是通过不断累加角度来完成,而非css3中循环执行。

两种方案开发小程序动画(图6)

对比

通过上述两个小例子对比,无论是便捷度还是代码量,通过css3来实现动画效果相对来说是更好的选择。api方式存在较多局限性:

  1. 动画只能执行一次,循环效果需要通过定时器完成。
  2. 无法按照原有轨迹返回,需要返回必须定义定时器。
  3. 频繁借助定时器在性能上有硬伤。

综合以上,推荐通过css3来完成动画效果。

更多资讯
游戏推荐
更多+