您好,欢迎访问一九零五行业门户网

如何实现小程序动画?小程序动画的实现方法

本篇文章给大家带来的内容是介绍如何实现小程序动画?小程序动画的实现方法。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。
在普通的网页开发中,动画效果可以通过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    .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中循环执行。
对比
通过上述两个小例子对比,无论是便捷度还是代码量,通过css3来实现动画效果相对来说是更好的选择。api方式存在较多局限性:
动画只能执行一次,循环效果需要通过定时器完成。
无法按照原有轨迹返回,需要返回必须定义定时器。
频繁借助定时器在性能上有硬伤。
综合以上,推荐通过css3来完成动画效果。
以上就是如何实现小程序动画?小程序动画的实现方法的详细内容。
其它类似信息

推荐信息