鴻蒙HarmonyOS實戰-ArkUI動畫(佈局更新動畫)

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

🚀前言

動畫是一種透過連續展示一系列靜止的影像(稱為幀)來創造出運動效果的藝術形式。它可以以手繪、計算機生成或其他各種形式呈現。在動畫中,每一幀都具有微小的變化,當這些幀被快速播放時,人眼會產生視覺上的錯覺,認為物體在運動。動畫可以用來表達故事、觀念、想法、情感或其他形式的藝術創作。它在電影、電視節目、廣告、遊戲和網頁設計等領域中得到廣泛應用。

按照頁面分類的動畫:

image

按照基礎能力分類的動畫

image

🚀一、佈局更新動畫

顯式動畫(animateTo)和屬性動畫(animation)是ArkUI提供的最基礎和常用的動畫功能。這些動畫功能可以在佈局屬性(例如尺寸屬性、位置屬性)發生變化時使用。透過屬性動畫或顯式動畫,可以按照指定的動畫引數過渡到新的佈局引數狀態。這些動畫功能的使用可以使UI變得更加生動和有趣。

🔎1.使用顯式動畫產生布局更新動畫

顯式動畫是指透過在程式碼中顯式地定義動畫效果,來實現檢視的動態變化。在HarmonyOS中,透過使用animateTo方法可以建立顯式動畫。這個方法可以傳入目標屬性值、動畫時長和動畫插值器等引數,以實現在一段時間內使檢視屬性平滑過渡到指定的目標值。顯式動畫可以用於控制檢視的尺寸、位置、透明度等屬性,在使用者互動或特定事件觸發時產生動態效果,增強使用者體驗。

顯式動畫的介面為:

animateTo(value: AnimateParam, event: () => void): void
  • 第一個引數指定動畫引數

  • 第二個引數為動畫的閉包函式

🦋1.1 平移動畫

平移動畫是一種移位動畫效果,透過改變元素在螢幕上的位置來實現物體的平移效果。在平移動畫中,元素可以沿著水平、垂直或對角線方向移動,或者沿著自定義的路徑移動。平移動畫可以為使用者介面新增動感和互動性,提高使用者體驗。

@Entry
@Component
struct LayoutChange {
  // 用於控制Column的alignItems屬性
  @State itemAlign: HorizontalAlign = HorizontalAlign.Start;
  allAlign: HorizontalAlign[] = [HorizontalAlign.Start, HorizontalAlign.Center, HorizontalAlign.End];
  alignIndex: number = 0;

  build() {
    Column() {
      Column({ space: 10 }) {
        Button("1").width(100).height(50)
        Button("2").width(100).height(50)
        Button("3").width(100).height(50)
      }
      .margin(20)
      .alignItems(this.itemAlign)
      .borderWidth(2)
      .width("90%")
      .height(200)

      Button("click").onClick(() => {
        // 動畫時長為1000ms,曲線為EaseInOut
        animateTo({ duration: 1000, curve: Curve.EaseInOut }, () => {
          this.alignIndex = (this.alignIndex + 1) % this.allAlign.length;
          // 在閉包函式中修改this.itemAlign引數,使Column容器內部孩子的佈局方式變化,使用動畫過渡到新位置
          this.itemAlign = this.allAlign[this.alignIndex];
        });
      })
    }
    .width("100%")
    .height("100%")
  }
}

初始化

image

移動到中間

image

移動到末尾

image

最後還原初始化

🦋1.2 縮放動畫

縮放動畫是一種在動畫中改變物件的尺寸大小的效果。它可以透過逐漸增大或減小物件的尺寸,或者透過突然改變物件的尺寸來實現。縮放動畫可以應用於各種型別的物件,包括文字、圖片、圖示等。

@Entry
@Component
struct LayoutChange2 {
  @State myWidth: number = 100;
  @State myHeight: number = 50;
  // 標誌位,true和false分別對應一組myWidth、myHeight值
  @State flag: boolean = false;

  build() {
    Column({ space: 10 }) {
      Button("text")
        .type(ButtonType.Normal)
        .width(this.myWidth)
        .height(this.myHeight)
        .margin(20)
      Button("area: click me")
        .fontSize(12)
        .margin(20)
        .onClick(() => {
          animateTo({ duration: 1000, curve: Curve.Ease }, () => {
            // 動畫閉包中根據標誌位改變控制第一個Button寬高的狀態變數,使第一個Button做寬高動畫
            if (this.flag) {
              this.myWidth = 100;
              this.myHeight = 50;
            } else {
              this.myWidth = 200;
              this.myHeight = 100;
            }
            this.flag = !this.flag;
          });
        })
    }
    .width("100%")
    .height("100%")
  }
}

image

image

如果不希望其他元件也變化位置,可以把變化元件放在足夠大容器內,或者進行佈局約束,如下:

Column() {
  // Button放在足夠大的容器內,使其不影響更外層的元件位置
  Button("text")
    .type(ButtonType.Normal)
    .width(this.myWidth)
    .height(this.myHeight)
}
.margin(20)
.width(200)
.height(100)
Button("area: click me")
    .fontSize(12)
    // 配置position屬性固定,使自己的佈局位置不被第一個Button的寬高影響
    .position({ x: "30%", y: 200 })
    .onClick(() => {
      animateTo({ duration: 1000, curve: Curve.Ease }, () => {
        // 動畫閉包中根據標誌位改變控制第一個Button寬高的狀態變數,使第一個Button做寬高動畫
        if (this.flag) {
          this.myWidth = 100;
          this.myHeight = 50;
        } else {
          this.myWidth = 200;
          this.myHeight = 100;
        }
        this.flag = !this.flag;
      });
    })

🔎2.使用屬性動畫產生布局更新動畫

屬性動畫是一種在HarmonyOS平臺上用於實現動畫效果的機制。屬性動畫可以對任意物件的屬性進行動畫操作,包括檢視的位置、大小、透明度、顏色等屬性。屬性動畫可以實現更靈活、更復雜的動畫效果。

屬性動畫的介面為:

animation(value: AnimateParam)

案例

@Entry
@Component
struct LayoutChange2 {
  @State myWidth: number = 100;
  @State myHeight: number = 50;
  @State flag: boolean = false;
  @State myColor: Color = Color.Blue;

  build() {
    Column({ space: 10 }) {
      Button("text")
        .type(ButtonType.Normal)
        .width(this.myWidth)
        .height(this.myHeight)
        // animation只對其上面的type、width、height屬性生效,時長為1000ms,曲線為Ease
        .animation({ duration: 1000, curve: Curve.Ease })
        // animation對下面的backgroundColor、margin屬性不生效
        .backgroundColor(this.myColor)
        .margin(20)
      Button("area: click me")
        .fontSize(12)
        .onClick(() => {
          // 改變屬性值,配置了屬性動畫的屬性會進行動畫過渡
          if (this.flag) {
            this.myWidth = 100;
            this.myHeight = 50;
            this.myColor = Color.Blue;
          } else {
            this.myWidth = 200;
            this.myHeight = 100;
            this.myColor = Color.Pink;
          }
          this.flag = !this.flag;
        })
    }
  }
}

image

🚀寫在最後

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

image

相關文章