欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

uniapp定義動畫的幾種方式總結

 更新時間:2023年02月08日 09:28:29   作者:腦子沒墨水  
我們都知道,動畫其實是由一幀一幀圖片組成,快遞地播放一組圖片就形成了動畫,下面這篇文章主要給大家介紹了關于uniapp定義動畫的幾種方式,需要的朋友可以參考下

本章的前提就是大家都知道動畫的基本屬性,例如
animation-nameanimation-durationanimation-timing-function、animation-delay、animation-iteration-countanimation-direction 屬性。

了解更多 animation 相關的內容。

現在制作一個左右抖動的動畫效果,效果如下:

在 uniapp 中,可以通過如下兩種方式來完成。

1. 直接使用 CSS 動畫

1.1 定義動畫

@keyframes shakeX {
  from,
  to {
    transform: translate3d(0, 0, 0);
  }

  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translate3d(-10px, 0, 0);
  }

  20%,
  40%,
  60%,
  80% {
    transform: translate3d(10px, 0, 0);
  }
}

.shakeX {
  animation-name: shakeX;
  animation-duration: 1s;
}

1.2 使用

<view class="box shakeX"></view>
<style>
  .box {
    width: 100rpx;
    height: 100rpx;
    background-color: green;
  }
</style>

效果如下:

2. 通過 uniapp 提供編程式創(chuàng)建動畫

uniapp 提供 createAnimation 內置函數,用于創(chuàng)建一個動畫實例 animation

動畫定義步驟:

  • 創(chuàng)建動畫實例
  • 調用實例的方法來描述動畫
  • 通過動畫實例的 export 方法導出動畫數據
  • 導出的動畫數據傳遞給組件的 animation 屬性(uniapp 提供組件都支持 animation 屬性)

兼容性列表:

AppH5微信小程序支付寶小程序百度小程序字節(jié)跳動小程序、飛書小程序QQ小程序快手小程序京東小程序
HBuilderX 2.0.4+xx

注意??:

  • export方法每次調用后會清掉之前的動畫操作。
  • nvue 暫不支持

2.1 定義動畫

接下來通過編程實現上面抖動功能。

2.1.1 創(chuàng)建動畫實例

const animation = uni.createAnimation(); // 定義動畫實例

2.1.2 調用實例方法來描述動畫

在上面的 shakeX 動畫定義中,通過 translate3d 來定義動畫。 對應的在 animation 實例中去查找與 translate3d 相關的實例方法。

translate 相關的實例方法,如下:

方法參數說明
translatetx,[ty]一個參數時,表示在X軸偏移tx,單位px;兩個參數時,表示在X軸偏移tx,在Y軸偏移ty,單位px。
translateXtx在X軸偏移tx,單位px
translateYty在Y軸偏移ty,單位px
translateZtz在Z軸偏移tz,單位px
translate3d(tx,ty,tz)在X軸偏移tx,在Y軸偏移ty,在Z軸偏移tz,單位px

有了這些方法之后,我們可以描述動畫啦~

@keyframes shakeX {
  from,
  to {
    transform: translate3d(0, 0, 0);
  }

  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translate3d(-10px, 0, 0);
  }

  20%,
  40%,
  60%,
  80% {
    transform: translate3d(10px, 0, 0);
  }
}

上面 CSS 中 translate3d,對應到編程方式如下:

animation.translate3d(0, 0, 0); // 原始位置
animation.translate3d(-10, 0, 0); // 向左偏移
animation.translate3d(10, 0, 0); // 像右偏移

有上面方法后,可以把動畫描述出來,如下:

animation.animation3d(0, 0, 0) // 0%
    .animation3d(-10, 0, 0) // 10%
    .animation3d(10, 0, 0) // 20%
    .animation3d(-10, 0, 0) // 30%
    // ...
    .animation3d(0, 0, 0); // 100%

現在通過 export() 方法導出定義動畫:

<template>
    <view class="box" :animation="animationData"></view>
</template>
export default {
  data() {
    return {
        animationData: {}
    }
  },
  onLoad(){
    const animation = uni.createAnimation();
    animation.animation3d(0, 0, 0) // 0%
        .animation3d(-10, 0, 0) // 10%
        .animation3d(10, 0, 0) // 20%
        .animation3d(-10, 0, 0) // 30%
        // ...
        .animation3d(0, 0, 0); // 100%
    this.animationData = animation.export();
  }
}

代碼運行之后,并沒有如期出現預期抖動效果。為什么? 因為 uniapp 中在定義的一組動畫中是并行執(zhí)行的,所以并不會產生動畫效果。

再回過來,看上面 CSS 中把一個動畫周期劃分成不同的組(步驟),10% 時執(zhí)行 translate3d(-10px, 0, 0)20% 時執(zhí)行translate3d(10px, 0, 0)。

在 uni-app 中有沒有類似的方式呢? 通過 step 來定義。

animation
    .translateX(0) // 0%
    .translateX(10) // 20%
    .step();
  animation.translateX(-10).step(); // 30%
  animation.translateX(10).step(); // 40%
  animation.translateX(-10).step(); // 50%
  animation.translateX(10).step(); // 60%
  animation.translateX(-10).step(); // 70%
  animation.translateX(10).step(); // 80%
  animation.translateX(-10).step(); // 90%
  animation.translateX(0).step(); // 100%
  this.animationData = animation.export();

再來執(zhí)行代碼,發(fā)現會動了。

從效果來看發(fā)現跟預期效果差很多,為什么? 跟 animation 的 animation-duration 屬性有關。

animation-duration: 屬性指定一個動畫周期的時長。

也就是一組動畫運行完所需時間。 在 uni.createAnimation() 創(chuàng)建動畫時可以傳遞參數,在不顯示的指定 duration 值時,默認值為 400ms。 而 step() 會繼承該值。

參數類型必填默認值說明
durationInteger400動畫持續(xù)時間,單位ms
timingFunctionString"linear"定義動畫的效果
delayInteger0動畫延遲時間,單位 ms
transformOriginString"50% 50% 0"設置transform-origin

這就是 “慢” 的原因。

在明白“慢”之后,只要把動畫執(zhí)行時間 (duration) 調整,應該能看到預期效果。假設期望完成抖動時間 1s,把動畫拆分成 10 組,則每一組的動畫時間為 100 ms.

現在指定 step 的 duration 值為 100ms,更改后代碼如下:

animation
    .translateX(0) // 0%
    .translateX(10) // 20%
    .step({
      duration: 100,
    });

  animation.translateX(-10).step({
    duration: 100,
  }); // 30%

  animation.translateX(10).step({
    duration: 100,
  }); // 40%

  animation.translateX(-10).step({
    duration: 100,
  });

  // 50%
  animation.translateX(10).step({
    duration: 100,
  }); // 60%

  animation.translateX(-10).step({
    duration: 100,
  }); // 70%

  animation.translateX(10).step({
    duration: 100,
  }); // 80%

  animation.translateX(-10).step({
    duration: 100,
  }); // 90%

  animation.translateX(0).step({
    duration: 100,
  });
  this.animationData = animation.export();

再來執(zhí)行代碼,運行效果如下:

發(fā)現效果基本與預期效果一樣了。

更多 uni.createAnimation() 相關的內容,可以自行查看文檔

3. 什么情況下使用編程式創(chuàng)建動畫

當不能通過 css 方式或通過動態(tài)類名一些方式去添加動畫時,此時就可以考慮使用編程式來創(chuàng)建動畫。編程式可以很靈活創(chuàng)建動畫、控制動畫運行和監(jiān)聽動畫的結束。 其次從兼容列表來看,能很好在不同平臺運行。

現在看個實際例子: 在登錄時,通常需要 ?? 選用戶協(xié)議和隱私政策 之后才允許用戶登錄?,F在產品希望當用戶在未勾選時點擊登錄,希望通過抖動 用戶協(xié)議和隱私政策來提醒用戶。

上面需求需要完成幾個功能點:

  • 定義抖動動畫類
  • 未勾選時動態(tài)添加動畫類
  • 動畫結束時移除動畫類(用戶下一次點擊時,需要繼續(xù)抖動)

通??梢赃@樣做:

<view ref="agreement" class="agreement" :class="{ 'shakeX': actived }">
      <radio
        @click="onChecked"
        style="transform: scale(0.6)"
        :color="color"
        :checked="agreement"
      ></radio>
      我已閱讀并同意<text class="service"
        >用戶協(xié)議</text
      >和<text class="privacy">隱私政策</text>
</view>
<button @click="onLogin">登錄</button>
export default {
      data() {
        return {
            actived: false // false
        };
      },
      mounted(){
    this.$refs.agreement.$el.addEventListener("animationend", ()=> {
            this.actived = false; // 動畫結束移除類
    });
      },
      methods: {
          onLogin(){
             // 動態(tài)添加
             this.actived = true;
          }
      },
 };
@keyframes shakeX {
  from,
  to {
    transform: translate3d(0, 0, 0);
  }

  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translate3d(-10px, 0, 0);
  }

  20%,
  40%,
  60%,
  80% {
    transform: translate3d(10px, 0, 0);
  }
}

.shakeX {
  animation-name: shakeX;
  animation-duration: 1s;
}

發(fā)現在 app、小程序 上運行時,發(fā)現 this.$refs.agreement.$el 為空,這是為什么,這里就是跟 uniapp 底層設計有關,如下圖所示:

上面引用微信小程序,uniapp 在設計跟小程序是一樣的。 也可以在上底層設計鏈接中了解到 uniapp 設計。

如果不能獲取元素并注冊animationend事件,沒辦法很好知道動畫結束,不知道何時應該移除。當然有的人想可以通過定時器完成,這樣不能精細話控制。

此時通過編程式就可以很好解決兼容的問題,現在稍微調整下:

<view class="agreement" :animation="animationData">
      <radio
        @click="onChecked"
        style="transform: scale(0.6)"
        :color="color"
        :checked="agreement"
      ></radio>
      我已閱讀并同意<text class="service"
        >用戶協(xié)議</text
      >和<text class="privacy">隱私政策</text>
</view>
<button @click="onLogin">登錄</button>
export default {
      data() {
        return {
            animationData: {}
        };
      },
      onLoad(){
    const animation = uni.createAnimation({
          timingFunction: "linear",
        });
        this.animation = animation;
      },
      methods: {
          shakeX() {
              const animation = this.animation;
              animation
                .translateX(0) // 0%
                .translateX(10) // 20%
                .step({
                  duration: 100,
                });

              animation.translateX(-10).step({
                duration: 100,
              }); // 30%

              animation.translateX(10).step({
                duration: 100,
              }); // 40%

              animation.translateX(-10).step({
                duration: 100,
              });

              // 50%
              animation.translateX(10).step({
                duration: 100,
              }); // 60%

              animation.translateX(-10).step({
                duration: 100,
              }); // 70%

              animation.translateX(10).step({
                duration: 100,
              }); // 80%

              animation.translateX(-10).step({
                duration: 100,
              }); // 90%

              animation.translateX(0).step({
                duration: 100,
              });
              this.animationData = animation.export();
          },
          onLogin(){
             this.shakeX();
          }
      },
 };

通過編程方式,為什么不需要像動態(tài)類名的方式,動畫結束必須移除類名否則下次不會生效? 這里留給大家去思考了。

4. 總結

  • 具體采用哪種方式創(chuàng)建動畫,可以根據實際業(yè)務場景來定。
  • uniapp 編程方式,通過 step 來進行動畫分組,同一個分組內動畫函數會并行執(zhí)行。
  • 多個動畫分組之間的執(zhí)行是串行的,也就是需等待上一個結束才會執(zhí)行下一個。

到此這篇關于uniapp定義動畫的幾種方式的文章就介紹到這了,更多相關uniapp定義動畫方式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論