如何使用弹簧动画曲线 原创 精华

野生菌君
发布于 2023-5-31 15:13
浏览
2收藏

如何使用弹簧动画曲线

场景说明

在动画开发场景中,经常用到弹性效果,尤其在拖拽某个对象时经常伴随弹性动效。OpenHarmony提供了三种弹簧动画曲线用来实现弹性效果,本例将为大家介绍这三种曲线的用法。

效果呈现

本例最终效果如下:

如何使用弹簧动画曲线-鸿蒙开发者社区

运行环境

本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:

  • IDE: DevEco Studio 3.1 Beta2
  • SDK: Ohos_sdk_public 3.2.11.9(API Version 9 Release)

实现思路

本例主要用到以下三种弹簧动画曲线:

  • curves.springCurve:通过设置弹簧的初始速度、质量、刚度和阻尼来控制弹簧动画的效果。对应本例中springCurve按钮触发的动画。
  • curves.springMotion:通过设置弹簧震动时间和阻尼来控制弹簧动画的效果。对应本例中springMotion按钮触发的动画。
  • curves.responsiveSpringMotion:构造弹性跟手动画曲线对象,是springMotion的一种特例,仅默认参数不同,可与springMotion混合使用。用来实现拖拽动画。

开发步骤

  1. 搭建UI框架。
    样例中有两个按钮,一个图片。内容整体纵向分布,两个按钮横向分布。纵向布局可以采用Column组件,横向布局可以采用Row组件。代码如下:

    @Entry
    @Component
    struct ImageComponent {
      build() {
        Column() {
          Row() {
            Button('springCurve')
              .margin({right:10})
              .fontSize(20)
              .backgroundColor('#18183C')
            Button('springMotion')
              .fontSize(20)
              .backgroundColor('#18183C')
          }
          .margin({top:30})
    
          Image($r("app.media.contact2"))
            .width(100)
            .height(100)
        }.width("100%").height("100%").backgroundColor('#A4AE77')
      }
    }
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.
    • 17.
    • 18.
    • 19.
    • 20.
    • 21.
    • 22.
  2. 为springCurve按钮添加curves.springCurve的曲线动画。

    ...
    // 定义状态变量translateY,用来控制笑脸图像的位移
    @State translateY: number = 0
    	...
        Button('springCurve')
          .margin({right:10})
          .fontSize(20)
          .backgroundColor('#18183C')
          // 绑定点击事件
          .onClick(() => {
            // 在点击事件中添加显示动画
            animateTo({
              duration: 2000,
              // 设定curves.springCurve为动画曲线
              curve: curves.springCurve(100, 10, 80, 10)
            },
            () => {
              // 改变translateY的值,使笑脸图像发生位移
              this.translateY = -20
            })
            this.translateY = 0
          })
    	...
        Image($r("app.media.contact2"))
          .width(100)
          .height(100)
          // 为笑脸图像添加位移属性,以translateY为参数
          .translate({ y: this.translateY })
    	...
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.
    • 17.
    • 18.
    • 19.
    • 20.
    • 21.
    • 22.
    • 23.
    • 24.
    • 25.
    • 26.
    • 27.
    • 28.
    • 29.

    效果如下:

    如何使用弹簧动画曲线-鸿蒙开发者社区

  3. 为springMotion按钮添加curves.springMotion曲线动画。
    这里通过position属性控制springMotion按钮的移动,当然开发者也可以继续选择使用translate属性。

    ...
      // 定义状态变量translateY,用来控制笑脸图像的位置变化
      @State imgPos: {
        x: number,
        y: number
      } = { x: 125, y: 400 }
            ...
            Button('springMotion')
              .fontSize(20)
              .backgroundColor('#18183C')
              // 绑定点击事件
              .onClick(() => {
              // 在点击事件中添加显示动画
              animateTo({
                duration: 15,
                //设定curves.springMotion为动画曲线
                curve: curves.springMotion(0.5, 0.5),
                onFinish: () => {
                  animateTo({ duration: 500,
                    curve: curves.springMotion(0.5, 0.5), }, () => {
                    // 动画结束时笑脸图像位置还原
                    this.imgPos = { x: 125, y: 400 }
                  })
                }
              }, () => {
                // 改变笑脸图像位置,y轴位置由400,变为150
                this.imgPos = { x: 125, y: 150 }
              })
            })
          ...
          Image($r("app.media.contact2"))
            .width(100)
            .height(100)
            .translate({ y: this.translateY })
            // 为笑脸图像添加位置属性,以imgPos为参数
            .position(this.imgPos)
         ...
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.
    • 17.
    • 18.
    • 19.
    • 20.
    • 21.
    • 22.
    • 23.
    • 24.
    • 25.
    • 26.
    • 27.
    • 28.
    • 29.
    • 30.
    • 31.
    • 32.
    • 33.
    • 34.
    • 35.
    • 36.
    • 37.

    效果如下:

    如何使用弹簧动画曲线-鸿蒙开发者社区

  4. 使用curves.responsiveSpringMotion为笑脸图像添加拖拽动画。

    ...
          Image($r("app.media.contact2"))
            .width(100)
            .height(100)
            .translate({ y: this.translateY })
            .position(this.imgPos)
            // 绑定触摸事件
            .onTouch((event: TouchEvent) => {
              // 当触摸放开时,笑脸图像位置还原
              if (event.type == TouchType.Up) {
                animateTo({
                  duration: 50,
                  delay: 0,
                  curve: curves.springMotion(),
                  onFinish: () => {
                  }
                }, () => {
                  this.imgPos = { x: 125, y: 400 }
                })
              } else {
                // 触摸过程中触发跟手动画
                animateTo({
                  duration: 50,
                  delay: 0,
                  //设定跟手动画曲线
                  curve: curves.responsiveSpringMotion(),
                  onFinish: () => {
                  }
                }, () => {
                  // 根据触点位置改变笑脸图像位置,从而实现跟手动画
                  this.imgPos = {
                    x: event.touches[0].screenX - 100 / 2,
                    y: event.touches[0].screenY - 100 / 2
                  }
                })
              }
            })
    ...
    
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
    • 11.
    • 12.
    • 13.
    • 14.
    • 15.
    • 16.
    • 17.
    • 18.
    • 19.
    • 20.
    • 21.
    • 22.
    • 23.
    • 24.
    • 25.
    • 26.
    • 27.
    • 28.
    • 29.
    • 30.
    • 31.
    • 32.
    • 33.
    • 34.
    • 35.
    • 36.
    • 37.
    • 38.

    效果如下:

    如何使用弹簧动画曲线-鸿蒙开发者社区

完整代码

本例完整代码如下:

import curves from '@ohos.curves';

@Entry
@Component
struct ImageComponent {
  // 定义状态变量translateY,用来控制笑脸图像的位移
  @State translateY: number = 0
  // 定义状态变量translateY,用来控制笑脸图像的位置变化
  @State imgPos: {
    x: number,
    y: number
  } = { x: 125, y: 400 }

  build() {
    Column() {
      Row() {
        Button('springCurve')
          .margin({right:10})
          .fontSize(20)
          .backgroundColor('#18183C')
          // 绑定点击事件
          .onClick(() => {
            // 在点击事件中添加显示动画
            animateTo({
              duration: 2000,
              // 设定curves.springCurve为动画曲线
              curve: curves.springCurve(100, 10, 80, 10)
            },
            () => {
              // 改变translateY的值,使笑脸图像发生位移
              this.translateY = -20
            })
            this.translateY = 0
          })
        Button('springMotion')
          .fontSize(20)
          .backgroundColor('#18183C')
          // 绑定点击事件
          .onClick(() => {
            // 在点击事件中添加显示动画
            animateTo({
              duration: 15,
              //设定curves.springMotion为动画曲线
              curve: curves.springMotion(0.5, 0.5),
              onFinish: () => {
                animateTo({ duration: 500,
                  curve: curves.springMotion(0.5, 0.5), }, () => {
                  // 动画结束时笑脸图像位置还原
                  this.imgPos = { x: 125, y: 400 }
                })
              }
            }, () => {
              // 改变笑脸图像位置,y轴位置由400,变为150
              this.imgPos = { x: 125, y: 150 }
            })
        })
      }
      .margin({top:30})

      Image($r("app.media.contact2"))
        .width(100)
        .height(100)
        // 为笑脸图像添加位移属性,以translateY为参数
        .translate({ y: this.translateY })
        // 为笑脸图像添加位置属性,以imgPos为参数
        .position(this.imgPos)
        // 绑定触摸事件
        .onTouch((event: TouchEvent) => {
          // 当触摸放开时,笑脸图像位置还原
          if (event.type == TouchType.Up) {
            animateTo({
              duration: 50,
              delay: 0,
              curve: curves.springMotion(),
              onFinish: () => {
              }
            }, () => {
              this.imgPos = { x: 125, y: 400 }
            })
          } else {
            // 触摸过程中触发跟手动画,同样通过animateTo实现动画效果
            animateTo({
              duration: 50,
              delay: 0,
              //设定跟手动画曲线
              curve: curves.responsiveSpringMotion(),
              onFinish: () => {
              }
            }, () => {
              // 根据触点位置改变笑脸图像位置,从而实现跟手动画
              this.imgPos = {
                x: event.touches[0].screenX - 100 / 2,
                y: event.touches[0].screenY - 100 / 2
              }
            })
          }
        })
    }.width("100%").height("100%").backgroundColor('#A4AE77')
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.

参考

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
6
收藏 2
回复
举报
6
4
2
4条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

看上去弹簧的动画效果还是做的不错

回复
2023-5-31 16:14:03
殇时云起
殇时云起

感觉可以做成割绳子小游戏

回复
2023-6-1 20:11:08
物联风景
物联风景

不错不错,厉害了!

回复
2023-6-2 09:14:14
野生菌君
野生菌君 回复了 红叶亦知秋
看上去弹簧的动画效果还是做的不错

对的,你有什么想要实现的场景也可以回复呢,我来看能不能实现,大家一起学习进步~

回复
2023-6-2 09:15:36


回复
    相关推荐