写点什么

HarmonyOS Next 动画大全 02- 显式动画

作者:万少
  • 2024-12-15
    江苏
  • 本文字数:2506 字

    阅读完需:约 8 分钟

HarmonyOS Next 动画大全 02-显式动画

HarmonyOS Next 动画大全 02-显式动画

前言

上一篇文章我们介绍过属性动画animation的使用方法,那么本文就来学习和了解一下显示动画animateTo

animateTo

我们称之为显式动画,它本身是一个全局函数,通过调用函数的形式实现动画效果。显式动画animateTo和之前的属性动画


animation最大的区别在于 显式动画可以利用本身函数的特性实现多个显式动画连续调用,从而实现连贯性的动画。

基本语法

animateTo(value: AnimateParam, event: () => void): void



解释:


  1. AnimateParam 动画属性,在上一篇文章《HarmonyNext 动画大全 01-属性动画》内有详细介绍过


  2. 其中,onFinish 是我们实现连续动画的关键

  3. event 指定动效的闭包函数

基本示例


@Entry@Componentstruct Index {  @State  scaleXY: number = 1
build() { Column() { Button("点我就变大啦") .scale({ x: this.scaleXY, y: this.scaleXY }) .onClick(() => { // 显式动画 animateTo({ // 1 指定动画参数 duration: 1000 }, () => { // 2 指定动效的闭包函数 this.scaleXY = 2 }) }) } .width("100%") .height("100%") .padding(40) }}
复制代码


代码解释


  1. 可以看到 animateTo就是一个全局函数,可以直接调用

  2. duration: 1000 表示动画参数,动画的持续时间为 1s

  3. this.scaleXY = 2 放在 animateTo的第二个参数上,回调函数,也是在这里指定要具体执行的动画效果


至此,我们发现 显式动画 animateTo 和 之前的属性动画 animation 没有太大区别。 对的,因为他们两个最大的区别就在于 animateTo 可以比较方便实现连续多个动画效果

连续多个动画效果

如下图:



可以看到以上动画其实是有多个动画效果组合在一起的。如


  1. 左上角 -> 右上角

  2. 右上角 -> 右下角

  3. 右下角 -> 左下角

  4. 左下角 -> 左上角


我们思考:该如何实现呢?


答案是:onFinishonFinish 是动画参数中的一个属性,表示动画执行完毕。

onFinish

当动画执行完毕时,便会自动触发 onFinish里面的逻辑



@Entry@Componentstruct Index {  @State  x: number = 0  @State  y: number = 0
build() { Column() { Row() .width(100) .height(100) .backgroundColor("#499C54")// tips: translate 表示设置位移 .translate({ x: this.x, y: this.y }) .onClick(() => { animateTo({ // 动画执行完毕触发 onFinish: () => { AlertDialog.show({ message: "动画执行完毕" }) } }, () => { this.x = 100 this.y = 0 }) }) } .width("100%") .height("100%") .alignItems(HorizontalAlign.Start)
}}
复制代码


因此,当我们想要实现连续执行多个动画时,就不断往onFinish里面套娃即可



@Entry@Componentstruct Index {  @State  x: number = 0  @State  y: number = 0
build() { Column() { Row() .width(100) .height(100) .backgroundColor("#499C54") .translate({ x: this.x, y: this.y }) .onClick(() => { // 1 左上角 -> 右上角 animateTo({ onFinish: () => { // 2 右上角 -> 右下角 animateTo({ onFinish: () => { // 3 右下角 -> 左下角 animateTo({ onFinish: () => { // 4 左下角 -> 左上角 animateTo({}, () => { this.x = 0 this.y = 0 }) } }, () => { this.x = 0 this.y = 100 }) } }, () => { this.x = 100 this.y = 100 }) } }, () => { this.x = 100 this.y = 0 }) }) } .width("100%") .height("100%") .alignItems(HorizontalAlign.Start)
}}
复制代码


以上这个代码,就可以实现连续动画了。

回调函数地狱



但是,这个代码结构,妈妈看到了很难不夸你写得好



以上结构已经形成了一个回调函数地狱了,小伙伴们~😂

解决回调函数地狱

有开发经验的小伙们应该可以马上想到解决方法


  1. promise

  2. asyncawait


对的,回调函数地狱可以靠这两个老哥来解决。


先拿 animateToPromise 做一个封装


const animateToPromise = (option: AnimateParam, fn: Function) => {  const promise: Promise<undefined> = new Promise((resolve: Function) => {    option.onFinish = () => {      resolve();    };    animateTo(option, () => {      fn();    });  });  return promise;};
复制代码


最后再来看解决后的版本


  Row() {
} .width(100) .height(100) .backgroundColor("#499C54") .translate({ x: this.x, y: this.y }) .onClick(async () => { // 1 左上角 -> 右上角 await animateToPromise({}, () => { this.x = 100 this.y = 0 }) // 2 右上角 -> 右下角 await animateToPromise({}, () => { this.x = 100 this.y = 100 }) // 3 右下角 -> 左下角 await animateToPromise({}, () => { this.x = 0 this.y = 100 }) // 4 左下角 -> 左上角 await animateToPromise({}, () => { this.x = 0 this.y = 0 }) })
复制代码




可以看到,封装后的代码,要简洁不少


小结

  1. animateTo 适合用在连续多个动画效果上

  2. animateTo 可以搭配promiseasyncawait 解决回调地狱的问题

  3. 由于篇幅问题,这里没有直接介绍 promise 和 async。


发布于: 刚刚阅读数: 5
用户头像

万少

关注

还未添加个人签名 2021-12-02 加入

还未添加个人简介

评论

发布
暂无评论
HarmonyOS Next 动画大全 02-显式动画_鸿蒙_万少_InfoQ写作社区