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

uniapp定義動(dòng)畫的幾種方式總結(jié)

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

本章的前提就是大家都知道動(dòng)畫的基本屬性,例如
animation-name、animation-durationanimation-timing-function、animation-delayanimation-iteration-countanimation-direction 屬性。

了解更多 animation 相關(guān)的內(nèi)容。

現(xiàn)在制作一個(gè)左右抖動(dòng)的動(dòng)畫效果,效果如下:

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

1. 直接使用 CSS 動(dòng)畫

1.1 定義動(dòng)畫

@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)建動(dòng)畫

uniapp 提供 createAnimation 內(nèi)置函數(shù),用于創(chuàng)建一個(gè)動(dòng)畫實(shí)例 animation。

動(dòng)畫定義步驟:

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

兼容性列表:

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

注意??:

  • export方法每次調(diào)用后會(huì)清掉之前的動(dòng)畫操作。
  • nvue 暫不支持

2.1 定義動(dòng)畫

接下來通過編程實(shí)現(xiàn)上面抖動(dòng)功能。

2.1.1 創(chuàng)建動(dòng)畫實(shí)例

const animation = uni.createAnimation(); // 定義動(dòng)畫實(shí)例

2.1.2 調(diào)用實(shí)例方法來描述動(dòng)畫

在上面的 shakeX 動(dòng)畫定義中,通過 translate3d 來定義動(dòng)畫。 對(duì)應(yīng)的在 animation 實(shí)例中去查找與 translate3d 相關(guān)的實(shí)例方法。

translate 相關(guān)的實(shí)例方法,如下:

方法參數(shù)說明
translatetx,[ty]一個(gè)參數(shù)時(shí),表示在X軸偏移tx,單位px;兩個(gè)參數(shù)時(shí),表示在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

有了這些方法之后,我們可以描述動(dòng)畫啦~

@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,對(duì)應(yīng)到編程方式如下:

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

有上面方法后,可以把動(dòng)畫描述出來,如下:

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%

現(xiàn)在通過 export() 方法導(dǎo)出定義動(dòng)畫:

<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();
  }
}

代碼運(yùn)行之后,并沒有如期出現(xiàn)預(yù)期抖動(dòng)效果。為什么? 因?yàn)?nbsp;uniapp 中在定義的一組動(dòng)畫中是并行執(zhí)行的,所以并不會(huì)產(chǎn)生動(dòng)畫效果。

再回過來,看上面 CSS 中把一個(gè)動(dòng)畫周期劃分成不同的組(步驟),10% 時(shí)執(zhí)行 translate3d(-10px, 0, 0),20% 時(shí)執(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ā)現(xiàn)會(huì)動(dòng)了。

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

animation-duration: 屬性指定一個(gè)動(dòng)畫周期的時(shí)長。

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

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

這就是 “慢” 的原因。

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

現(xiàn)在指定 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í)行代碼,運(yùn)行效果如下:

發(fā)現(xiàn)效果基本與預(yù)期效果一樣了。

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

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

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

現(xiàn)在看個(gè)實(shí)際例子: 在登錄時(shí),通常需要 ?? 選用戶協(xié)議和隱私政策 之后才允許用戶登錄。現(xiàn)在產(chǎn)品希望當(dāng)用戶在未勾選時(shí)點(diǎn)擊登錄,希望通過抖動(dòng) 用戶協(xié)議和隱私政策來提醒用戶。

上面需求需要完成幾個(gè)功能點(diǎn):

  • 定義抖動(dòng)動(dòng)畫類
  • 未勾選時(shí)動(dòng)態(tài)添加動(dòng)畫類
  • 動(dòng)畫結(jié)束時(shí)移除動(dòng)畫類(用戶下一次點(diǎn)擊時(shí),需要繼續(xù)抖動(dòng))

通??梢赃@樣做:

<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; // 動(dòng)畫結(jié)束移除類
    });
      },
      methods: {
          onLogin(){
             // 動(dòng)態(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ā)現(xiàn)在 app、小程序 上運(yùn)行時(shí),發(fā)現(xiàn) this.$refs.agreement.$el 為空,這是為什么,這里就是跟 uniapp 底層設(shè)計(jì)有關(guān),如下圖所示:

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

如果不能獲取元素并注冊(cè)animationend事件,沒辦法很好知道動(dòng)畫結(jié)束,不知道何時(shí)應(yīng)該移除。當(dāng)然有的人想可以通過定時(shí)器完成,這樣不能精細(xì)話控制。

此時(shí)通過編程式就可以很好解決兼容的問題,現(xiàn)在稍微調(diào)整下:

<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();
          }
      },
 };

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

4. 總結(jié)

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

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

相關(guān)文章

最新評(píng)論