鴻蒙HarmonyO實戰-ArkUI動畫(元件內轉場動畫)

蜀道山QAQ發表於2024-04-20

🚀前言

轉場動畫是一種在電影、影片和簡報中使用的動畫效果,用於平滑地切換不同的場景或幻燈片。轉場動畫可以增加視覺吸引力,改善觀眾的觀看體驗。

常見的轉場動畫包括淡入淡出、滑動、旋轉、放大縮小等效果。這些動畫效果可以在場景之間建立無縫的過渡,使觀眾感到自然流暢。

在電影中,轉場動畫通常用於切換不同的場景或時間段。例如,一個電影可能從一個場景中的角色身上開始,然後透過淡入淡出或滑動的效果過渡到另一個場景中的不同角色。

在影片編輯軟體和簡報軟體中,轉場動畫常用於建立幻燈片之間的過渡效果。這些過渡可以使幻燈片之間的切換更加流暢和有趣,從而吸引觀眾的注意力。

轉場動畫的選擇應根據媒體型別、主題和受眾型別來進行,以確保動畫效果與內容相匹配,並增強使用者體驗。

🚀一、元件內轉場動畫

轉場動畫的介面為:

transition(value: TransitionOptions)

transition函式的入參為元件內轉場的效果,可以定義平移、透明度、旋轉、縮放這幾種轉場樣式的單個或者組合的轉場效果,必須和animateTo一起使用才能產生元件轉場效果。

🔎1.transition常見用法

在HarmonyOS中,transition(過渡)是指在UI介面的元素之間進行平滑的動畫切換的一種功能。在過渡中,可以定義元素的插入、刪除、移動等動畫效果。TransitionType是用來指定過渡型別的列舉值,包括以下三種型別:

  1. TransitionType.All:表示在過渡中包含所有型別的動畫效果,包括插入、刪除和移動。當使用TransitionType.All時,所有相關元素的過渡動畫都會被應用。

  2. TransitionType.Insert:表示只在過渡中包含插入型別的動畫效果。當新的元素被插入到UI介面中時,使用TransitionType.Insert可以定義其出現的動畫效果。

  3. TransitionType.Delete:表示只在過渡中包含刪除型別的動畫效果。當元素被從UI介面中刪除時,使用TransitionType.Delete可以定義其消失的動畫效果。

透過使用這些過渡型別,開發者可以在HarmonyOS應用中實現更加流暢、吸引人的介面切換效果。

Button()
  .transition({ type: TransitionType.All, scale: { x: 0, y: 0 } })
Button()
  .transition({ type: TransitionType.Insert, translate: { x: 200, y: -200 }, opacity: 0 })
  .transition({ type: TransitionType.Delete, rotate: { x: 0, y: 0, z: 1, angle: 360 } })

🔎2.if/else產生元件內轉場動畫

🦋2.1 無任何動畫

@Entry
@Component
struct IfElseTransition {
  @State flag: boolean = true;
  @State show: string = 'show';

  build() {
    Column() {
      Button(this.show).width(80).height(30).margin(30)
        .onClick(() => {
          if (this.flag) {
            this.show = 'hide';
          } else {
            this.show = 'show';
          }
          // 點選Button控制Image的顯示和消失
          this.flag = !this.flag;
        })
      if (this.flag) {
          Image($r('app.media.mountain')).width(200).height(200)
      }
    }.height('100%').width('100%')
  }
}

image

🦋2.2 無任何動畫

@Entry
@Component
struct IfElseTransition {
  @State flag: boolean = true;
  @State show: string = 'show';

  build() {
    Column() {
      Button(this.show).width(80).height(30).margin(30)
        .onClick(() => {
          if (this.flag) {
            this.show = 'hide';
          } else {
            this.show = 'show';
          }

          animateTo({ duration: 1000 }, () => {
            // 動畫閉包內控制Image元件的出現和消失
            this.flag = !this.flag;
          })
        })
      if (this.flag) {
        // Image的出現和消失配置為不同的過渡效果
        Image($r('app.media.img_2')).width(200).height(200)
          .transition({ type: TransitionType.Insert, translate: { x: 200, y: -200 } })
          .transition({ type: TransitionType.Delete, opacity: 0, scale: { x: 0, y: 0 } })
      }
    }.height('100%').width('100%')
  }
}

image

🔎3.ForEach產生元件內轉場動畫

@Entry
@Component
struct ForEachTransition {
  @State numbers: string[] = ["1", "2", "3", "4", "5"]
  startNumber: number = 6;

  build() {
    Column({ space: 10 }) {
      Column() {
        ForEach(this.numbers, (item) => {
          // ForEach下的直接元件需配置transition效果
          Text(item)
            .width(240)
            .height(60)
            .fontSize(18)
            .borderWidth(1)
            .backgroundColor(Color.Orange)
            .textAlign(TextAlign.Center)
            .transition({ type: TransitionType.All, translate: { x: 200 }, scale: { x: 0, y: 0 } })
        }, item => item)
      }
      .margin(10)
      .justifyContent(FlexAlign.Start)
      .alignItems(HorizontalAlign.Center)
      .width("90%")
      .height("70%")

      Button('向頭部新增元素')
        .fontSize(16)
        .width(160)
        .onClick(() => {
          animateTo({ duration: 1000 }, () => {
            // 往陣列頭部插入一個元素,導致ForEach在頭部增加對應的元件
            this.numbers.unshift(this.startNumber.toString());
            this.startNumber++;
          })
        })
      Button('向尾部新增元素')
        .width(160)
        .fontSize(16)
        .onClick(() => {
          animateTo({ duration: 1000 }, () => {
            // 往陣列尾部插入一個元素,導致ForEach在尾部增加對應的元件
            this.numbers.push(this.startNumber.toString());
            this.startNumber++;
          })
        })
      Button('刪除頭部元素')
        .width(160)
        .fontSize(16)
        .onClick(() => {
          animateTo({ duration: 1000 }, () => {
            // 刪除陣列的頭部元素,導致ForEach刪除頭部的元件
            this.numbers.shift();
          })
        })
      Button('刪除尾部元素')
        .width(160)
        .fontSize(16)
        .onClick(() => {
          animateTo({ duration: 1000 }, () => {
            // 刪除陣列的尾部元素,導致ForEach刪除尾部的元件
            this.numbers.pop();
          })
        })
    }
    .width('100%')
    .height('100%')
  }
}

image

🚀寫在最後

  • 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
  • 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
  • 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
  • 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY

image

相關文章