首頁  >  文章  >  微信小程式  >  如何實作小程式動畫?小程式動畫的實作方法

如何實作小程式動畫?小程式動畫的實作方法

青灯夜游
青灯夜游轉載
2018-11-10 16:40:435431瀏覽

本篇文章帶給大家的內容是介紹如何實現小程式動畫?小程式動畫的實作方法。有一定的參考價值,有需要的朋友可以參考一下,希望對你們有幫助。

在普通的網頁開發中,動畫效果可以透過css3來實現大部分需求,在小程式開發中同樣可以使用css3,同時也可以透過api方式來實現。

API解讀

小程式中,透過呼叫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() })
    <view></view>

範例

以下將通過2組動畫,來比較一下css3api #實作方式的不同。

一、模組移動動畫

#動畫效果:

下圖有兩組動畫,分別為api方式(上)與css3方式(下)完成的效果,點選move按鈕,動畫啟動。

如何實作小程式動畫?小程式動畫的實作方法

程式碼實作

以下分別為css3api#的核心程式碼:

css3:

    
    
        <view></view>
        <view></view>
        <view></view>
        <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類別名稱來達到動畫的效果,如上程式碼透過onetwothreefour分別控制移動的距離,透過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插入並改變內聯樣式來達到動畫效果,下面這張動圖可以清楚地看出樣式變化。

如何實作小程式動畫?小程式動畫的實作方法

列印出賦值的

animationDataanimates中存放了動畫事件的類型及參數;options中存放的是此次動畫的配置選項,transition中存放的是wx.createAnimation調用時的配置,transformOrigin是預設配置,意思是以物件的中心為起點開始執行動畫,也可在wx.createAnimation時進行設定。

如何實作小程式動畫?小程式動畫的實作方法

二、音樂播放動畫

#上面的模組移動動畫不涉及邏輯交互,因此新嘗試了一個音樂播放動畫,該動畫需要實現暫停、繼續的效果。

動畫效果:

如何實作小程式動畫?小程式動畫的實作方法

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

如何實作小程式動畫?小程式動畫的實作方法

代码实现

以下分别是css3实现与api实现的核心代码:

css3:

    <!-- wxml -->
    <view>
        <text></text>
        <text></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>
        <text></text>
        <text></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方式存在较多局限性:

  1. 动画只能执行一次,循环效果需要通过定时器完成。

  2. 无法按照原有轨迹返回,需要返回必须定义定时器。

  3. 频繁借助定时器在性能上有硬伤。

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

以上是如何實作小程式動畫?小程式動畫的實作方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除

相關文章

看更多