彈簧曲線動(dòng)畫

2024-02-07 12:42 更新

ArkUI提供了預(yù)置動(dòng)畫曲線,指定了動(dòng)畫屬性從起始值到終止值的變化規(guī)律,如Linear、Ease、EaseIn等。同時(shí),ArkUI也提供了由彈簧振子物理模型產(chǎn)生的彈簧曲線。通過彈簧曲線,開發(fā)者可以設(shè)置超過設(shè)置的終止值,在終止值附近震蕩,直至最終停下來的效果。彈簧曲線的動(dòng)畫效果比其他曲線具有更強(qiáng)的互動(dòng)性、可玩性。

彈簧曲線的接口包括兩類,一類是springCurve,另一類是springMotionresponsiveSpringMotion,這兩種方式都可以產(chǎn)生彈簧曲線。

使用springCurve

springCurve的接口為:

  1. springCurve(velocity: number, mass: number, stiffness: number, damping: number)

構(gòu)造參數(shù)包括初速度,彈簧系統(tǒng)的質(zhì)量、剛度、阻尼。構(gòu)建springCurve時(shí),可指定質(zhì)量為1,根據(jù)springCurve中的參數(shù)說明,調(diào)節(jié)剛度、阻尼兩個(gè)參數(shù),達(dá)到想要的震蕩效果。

  1. import curves from '@ohos.curves';
  2. @Entry
  3. @Component
  4. struct SpringTest {
  5. @State translateX: number = 0;
  6. private jumpWithSpeed(speed: number) {
  7. this.translateX = -1;
  8. animateTo({ duration: 2000, curve: curves.springCurve(speed, 1, 1, 1.2) }, () => {
  9. // 以指定初速度進(jìn)行x方向的平移的彈簧動(dòng)畫
  10. this.translateX = 0;
  11. })
  12. }
  13. build() {
  14. Column() {
  15. Button("button")
  16. .fontSize(14)
  17. .width(100)
  18. .height(50)
  19. .margin(30)
  20. .translate({ x: this.translateX })
  21. Row({space:50}) {
  22. Button("jump 50").fontSize(14)
  23. .onClick(() => {
  24. // 以初速度50的彈簧曲線進(jìn)行平移
  25. this.jumpWithSpeed(50);
  26. })
  27. Button("jump 200").fontSize(14)
  28. .onClick(() => {
  29. // 以初速度200的彈簧曲線進(jìn)行平移
  30. this.jumpWithSpeed(200);
  31. })
  32. }.margin(30)
  33. }.height('100%').width('100%')
  34. }
  35. }

以上示例中,點(diǎn)擊不同的按鈕,給定springCurve的不同初速度,button會(huì)有“彈性”的到達(dá)指定位置,且button的振幅隨著速度的增大而變大。另外也可以修改springCurve的質(zhì)量、剛度、阻尼參數(shù),達(dá)到想要的彈性的程度。

說明

速度只是放大了振蕩的效果,但系統(tǒng)能否產(chǎn)生振蕩的效果,取決于彈簧振子本身的物理參數(shù),即質(zhì)量、剛度、阻尼三個(gè)參數(shù)。剛度越小、阻尼越大,springCurve的“彈性”越弱,振蕩效果越弱。隨著剛度減小或阻尼變大,達(dá)到過阻尼狀態(tài)后,無論速度為多大,都不會(huì)有在終點(diǎn)值附近振蕩的效果。

使用springMotion和responsiveSpringMotion

springMotion的接口為:

  1. springMotion(response?: number, dampingFraction?: number, overlapDuration?: number)

responsiveSpringMotion的接口為:

  1. responsiveSpringMotion(response?: number, dampingFraction?: number, overlapDuration?: number)

它們的構(gòu)造參數(shù)包括彈簧自然振動(dòng)周期、阻尼系數(shù)、彈性動(dòng)畫銜接時(shí)長(zhǎng)這三個(gè)可選參數(shù),參數(shù)的含義請(qǐng)參考其文檔。

使用springMotion和responsiveSpringMotion曲線時(shí),duration不生效,適合于跟手動(dòng)畫。

  1. import curves from '@ohos.curves';
  2. @Entry
  3. @Component
  4. struct SpringMotionTest {
  5. @State positionX: number = 100;
  6. @State positionY: number = 100;
  7. diameter: number = 50;
  8. build() {
  9. Column() {
  10. Row() {
  11. Circle({ width: this.diameter, height: this.diameter })
  12. .fill(Color.Blue)
  13. .position({ x: this.positionX, y: this.positionY })
  14. .onTouch((event: TouchEvent) => {
  15. if (event.type === TouchType.Move) {
  16. // 跟手過程,使用responsiveSpringMotion曲線
  17. animateTo({ curve: curves.responsiveSpringMotion() }, () => {
  18. // 減去半徑,以使球的中心運(yùn)動(dòng)到手指位置
  19. this.positionX = event.touches[0].screenX - this.diameter / 2;
  20. this.positionY = event.touches[0].screenY - this.diameter / 2;
  21. console.info(`move, animateTo x:${this.positionX}, y:${this.positionY}`);
  22. })
  23. } else if (event.type === TouchType.Up) {
  24. // 離手時(shí),使用springMotion曲線
  25. animateTo({ curve: curves.springMotion() }, () => {
  26. this.positionX = 100;
  27. this.positionY = 100;
  28. console.info(`touchUp, animateTo x:100, y:100`);
  29. })
  30. }
  31. })
  32. }
  33. .width("100%").height("80%")
  34. .clip(true) // 如果球超出父組件范圍,使球不可見
  35. .backgroundColor(Color.Orange)
  36. Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Center }) {
  37. Text("拖動(dòng)小球").fontSize(16)
  38. }
  39. .width("100%")
  40. Row() {
  41. Text('點(diǎn)擊位置: [x: ' + Math.round(this.positionX) + ', y:' + Math.round(this.positionY) + ']').fontSize(16)
  42. }
  43. .padding(10)
  44. .width("100%")
  45. }.height('100%').width('100%')
  46. }
  47. }

以上代碼是跟手動(dòng)畫的一個(gè)示例。通過在onTouch事件中,捕捉觸摸的位置,改變組件的translate或者position屬性,使其在跟手過程中運(yùn)動(dòng)到觸摸位置,松手后回到原位置。跟手動(dòng)畫的效果如下:

跟手過程推薦使用responsiveSpringMotion曲線,松手過程推薦使用springMotion曲線。跟手過程隨著手的位置變化會(huì)被多次觸發(fā),所以會(huì)接連啟動(dòng)多次responsiveSpringMotion動(dòng)畫,松手時(shí)啟動(dòng)一次springMotion動(dòng)畫。跟手、松手過程在對(duì)同一對(duì)象的同一屬性上執(zhí)行動(dòng)畫,且使用了springMotion或responsiveSpringMotion曲線,每次新啟動(dòng)的動(dòng)畫會(huì)繼承上次動(dòng)畫使用的速度,實(shí)現(xiàn)平滑過渡。

說明

1. springCurve可以設(shè)置初速度,單一屬性存在多個(gè)動(dòng)畫時(shí)不會(huì)互相影響,觀察到的是多個(gè)動(dòng)畫效果的疊加。

2. springMotion雖然內(nèi)部有速度機(jī)制,但不可由開發(fā)者設(shè)置。在單一屬性存在多個(gè)動(dòng)畫時(shí),后一動(dòng)畫會(huì)取代前一動(dòng)畫,并繼承前一動(dòng)畫的速度。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)