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

前端之家收集整理的这篇文章主要介绍了如何实现小程序动画?小程序动画的实现方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本篇文章给大家带来的内容是介绍如何实现@R_301_447@动画?@R_301_447@动画的实现方法。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。

在普通的网页开发中,动画效果可以通过css3来实现大部分需求,在小程序开发中同样可以使用css3,同时也可以通过api方式来实现。

API解读

@R_301_447@中,通过调用api来创建动画,需要先创建一个实例对象。这个对象通过wx.createAnimation返回,animation的一系列属性都基于这个实例对象。

创建这个对象

    let animation = wx.createAnimation({
        duration: 2000,delay: 0,timingFunction: "linear",});

这个animation就是通过wx.createAnimation之后返回的实例。在创建过程中,可以给这个实例添加一些属性,如以上代码所示,等同于css3animation:$name 2s linear的写法。

添加动效

实例创建完成之后,基于该实例,添加需要的动态效果,动态类型可以查阅文档得知,以最常见的移动,旋转为例:

    animation.translate($width,0).rotate($deg);

结束动画

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

    animation.step();

导出动画

动画效果添加完成了,如何给想要的dom添加动效呢。这里需要用到.export()导出动画队列,赋值给某个dom对象。

    this.setData({ moveOne: animation.export() })
    

例子

以下将通过2组动画,来对比一下css3api实现方式的不同。

一、模块移动动画

动画效果

下图有两组动画,分别为api方式(上)与css3方式(下)完成的效果,点击move按钮,动画启动。

代码实现

以下分别为css3api的核心代码

css3:

    
    
        
        
        
        
    
    // 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,50rpx,0rpx);
}

.four {
    @include blockStyle(grey,fourmove);
}

@keyframes fourmove {
    @include movePublic(-50rpx,150rpx,0rpx);
}</pre><pre >    // js
moveFunction(){
    this.setData({
        isMove: true
    })
}</pre><p><code>css3</code>中通过动态改变<code>class</code>类名来达到动画的<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>,如上<a href="/tag/daima/" target="_blank" class="keywords">代码</a>通过<code>one</code>、<code>two</code>、<code>three</code>、<code>four</code>来分别控制移动的距离,通过sass可以避免<a href="/tag/daima/" target="_blank" class="keywords">代码</a>过于冗余的问题。<strong>(纠结如何在@R_<a href="/tag/301/" target="_blank" class="keywords">301</a>_447@中使用<code>sass</code>的童鞋请看这里哦:wechat-mina-template)</strong></p><p><strong><span >api:</span></strong></p><pre >    moveClick(){
    this.move(-75,-12.5,25,&#39;moveOne&#39;);
    this.move(-25,12.5,&#39;moveTwo&#39;);
    this.move(25,&#39;moveThree&#39;);
    this.move(75,-25,&#39;moveFour&#39;);
    this.moveFunction(); // 该事件触发css3模块进行移动
},// 模块移动<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>
move: function (w,h,m,ele) {
    let self = this;
    let moveFunc = function () {
    let animation = wx.createAnimation({
        duration: 2000,});

    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)
}</pre><p><a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>图可见,模块之间都是简单的移动,可以将他们的运动变化写成一个公共的事件,通过向事件传值,来移动到不同的位置。其中的参数<code>w,ele</code>分别表示发散水平方向移动的距离、聚拢时垂直方向、水平方向的距离以及需要<a href="/tag/xiugai/" target="_blank" class="keywords">修改</a><code>animationData</code>的对象。</p><p>通过这种<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>产生的动画,无法按照原有轨迹收回,所以在事件之后设置了定时器,定义在执行动画2s之后,执行另一个动画。同时<strong>动画只能执行一次</strong>,如果需要循环的动效,要在外层包裹一个重复执行的定时器到。</p><p>查看源码,发现<code>api</code>方式是通过<code>js</code>插入并改变内联样式来达到动画<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>,下面这张动图可以清晰地看出样式变化。</p><p><p class="pic_center"><img src="/res/2019/01-08/21/98c84e37e6d0ddc10dd78cd2c9aafffa.gif"&gt;</p></p><p>打印出赋值的<code>animationData</code>,<code>animates</code>中存放了动画事件的类型及参数;<code>options</code>中存放的是此次动画的配置选项,<code>transition</code>中存放的是<code>wx.createAnimation</code><a href="/tag/diaoyong/" target="_blank" class="keywords">调用</a>时的配置,<code>transformOrigin</code>是默认配置,意为以对象的中心为起点开始执行动画,也可在<code>wx.createAnimation</code>时进行配置。</p><p ><p class="pic_center"><img src="/res/2019/01-08/21/e9d2bd48ccc3fe66a3a5b3342e065c56.jpg"&gt;</p></p><p><strong><span >二、音乐播放动画</span></strong></p><p>上面的模块移动动画不涉及逻辑交互,因此新尝试了一个音乐播放动画,该动画需要实现暂停、继续的<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>。</p><p><strong>动画<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>:</strong></p><p ><p class="pic_center"><img src="/res/2019/01-08/21/785d4f2dd97d6bc564a24cd49728c31f.gif"&gt;</p></p><p>两组不同的动画<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>对比,分别为<code>api</code>(上)实现与<code>css3</code>实现(下):</p><p ><p class="pic_center"><img src="/res/2019/01-08/21/ee1423cecab7668927a584bed86246a8.gif"&gt;</p></p><p><strong><a href="/tag/daima/" target="_blank" class="keywords">代码</a>实现</strong></p><p>以下分别是<code>css3</code>实现与<code>api</code>实现的核心<a href="/tag/daima/" target="_blank" class="keywords">代码</a>:</p><p>css3:</p><pre >    <!-- wxml -->
<view class=&#39;music musicTwo musicRotate {{playTwo ? " ": "musicPaused"}} &#39; bindtap=&#39;playTwo&#39;>
    <text class="iconfont has-music" wx:if="{{playTwo}}"></text>
    <text class="iconfont no-music" wx:if="{{!playTwo}}"></text>
</view></pre><pre >    // scss
.musicRotate{
    animation: rotate 3s linear infinite;
}

@keyframes rotate{
    from{
        transform: rotate(0deg)
    }
    to{
        transform: rotate(359deg)
    }
}

.musicPaused{
    animation-play-state: paused;
}</pre><pre >    // js
playTwo(){
    this.setData({
        playTwo: !this.data.playTwo
    },()=>{
        let back = this.data.backgroundAu<a href="/tag/dio/" target="_blank" class="keywords">dio</a>Manager;
        if(this.data.playTwo){
            back.play();
        } else {
            back.pause();
        }
    })
}</pre><p>通过<code>playTwo</code>这个<a href="/tag/shuxing/" target="_blank" class="keywords">属性</a>来判断是否暂停,并控制<code>css</code>类的<a href="/tag/tianjia/" target="_blank" class="keywords">添加</a>与<a href="/tag/shanchu/" target="_blank" class="keywords">删除</a>。当为<code>false</code>时,<a href="/tag/tianjia/" target="_blank" class="keywords">添加</a><code>.musicPaused</code>类,动画暂停。</p><p>api:</p><pre >    <!-- wxml -->
<view class=&#39;music&#39; bindtap=&#39;play&#39;  animation="{{play &amp;&amp; musicRotate}}">
    <text class="iconfont has-music" wx:if="{{play}}"></text>
    <text class="iconfont no-music" wx:if="{{!play}}"></text>
</view></pre><pre >    // js
play(){
    this.setData({
        play: !this.data.play
    },()=>{
        let back = this.data.backgroundAu<a href="/tag/dio/" target="_blank" class="keywords">dio</a>Manager;
        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,});
        animation.rotate(30*(i++)).step()
        self.setData({ musicRotate: animation.export() });
    }
    rotateFuc();
    let rotateInterval = setInterval(
        rotateFuc,1000
    );
    // 全局定时事件
    this.setData({
        rotateInterval: rotateInterval
    })
}</pre><p>通过<code>api</code>实现的方式是通过移除<code>animationData</code>来控制动画,同时暂停动画也需要清除定时器,由于清除定时器需要跨事件进行操作,所以定了一个全局<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a><code>rotateInterval</code>。</p><p><code>api</code>方式定义了旋转的角度,但旋转到该角度之后便会停止,如果需要实现重复旋转<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>,需要通过定时器来完成。因此定义了变量i,定时器每执行一次便加1,相当于每1s旋转30°,对<code>animation.rotate()</code>中的度数动态赋值。暂停之后继续动画,需要从原有角度继续旋转,因此变量i需要为<a href="/tag/quanjubianliang/" target="_blank" class="keywords">全局变量</a>。</p><p><a href="/tag/daima/" target="_blank" class="keywords">代码</a>变化:</p><p>下图可以看出,<code>api</code>方式旋转是通过不断累加角度来完成,而非<code>css3</code>中循环执行。</p><p ><p class="pic_center"><img src="/res/2019/01-08/21/3d313d1bd2c3b8d394b25de3c6eb4f2a.gif"&gt;</p></p><p><strong><span >对比</span></strong></p><p>通过上述两个小例子对比,无论是便捷度还是<a href="/tag/daima/" target="_blank" class="keywords">代码</a>量,通过<code>css3</code>来实现动画<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>相对来说是更好的选择。<code>api</code>方式存在较多局限性:</p><ol ><li><p>动画只能执行一次,循环<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>需要通过定时器完成。</p></li><li><p>无法按照原有轨迹返回,需要返回必须定义定时器。</p></li><li><p>频繁借助定时器在<a href="/tag/xingneng/" target="_blank" class="keywords">性能</a>上有硬伤。</p></li></ol><p>综合以上,推荐通过<code>css3</code>来完成动画<a href="/tag/xiaoguo/" target="_blank" class="keywords">效果</a>。

猜你在找的微信小程序相关文章