在Harmony上实现AnimateCSS动画

描述

   

显式动画

     Harmony参考文档:
https://gitee.com/openharmony/docs/blob/5654c2b940ab3e2f4f0baf435e630c4ef3536428/zh-cn/application-dev/reference/arkui-ts/ts-explicit-animation.md

 

来看一个简单的示例:
@Entry
@Component
struct AnimationPage {
  // 位移属性
  @State _translate: TranslateOptions = {
    x: 0,
    y: 0,
    z: 0
  }

  build() {
    Flex({
      alignItems: ItemAlign.Center,
      justifyContent: FlexAlign.Center,
      direction: FlexDirection.Column
    }) {
      Button('执行动画').margin({ bottom: 50 }).onClick(() => {
        //添加一个简单显式动画
        animateTo({
          duration: 1000// 动画时长
          tempo: 0.5// 播放速率
          curve: Curve.EaseInOut, // 动画曲线
          delay: 0// 动画延迟
          iterations: 1// 播放次数
          playMode: PlayMode.Normal, // 动画模式
        }, () => {
          //闭包内更改状态
          this._translate = {
            x: 0,
            y: 100,
            z: 0
          }
        })
      })

      Column() {
        Text('Animate.css')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .fontColor('#351c75')
          .translate(this._translate) // 位移变换
      }
    }
    .width('100%')
    .height('100%')
  }
}
 Harmony

如果我们希望向下位移完成后,再向右位移,就需要在第一个动画完成后再进行第二个动画,即在第一个动画的 onFinish 函数中执行第二个动画。

Harmony

这样组合起来可以构成一个更复杂的连续动画

// 单步动画执行函数
animationStep(value: AnimateParam, event() => void) {
    return () => {
      return new Promise((resolve) => {
        let onFinish = value.onFinish
        value.onFinish = () => {
          if(onFinish) onFinish()
          resolve(true)
        }
        animateTo(value, event)
      })
    }
}
 

创建 4 步动画:

aboutToAppear() {
    // 每步动画执行时长
    let time = 200
    this.step1 = this.animationStep({
      duration: time, // 动画时长
      tempo: 0.5// 播放速率
      curve: Curve.EaseInOut, // 动画曲线
      delay: 0// 动画延迟
      iterations: 1// 播放次数
      playMode: PlayMode.Normal, // 动画模式
      onFinish: () => {
        // 动画执行完成
        console.info('play end')
      }
    }, () => {
      //闭包内更改状态
      this._translate = {
        x0,
        y100,
        z0
      }
    })


    this.step2 = this.animationStep({
      duration: time, // 动画时长
      tempo: 0.5// 播放速率
      curve: Curve.EaseInOut, // 动画曲线
      delay: 0// 动画延迟
      iterations: 1// 播放次数
      playMode: PlayMode.Normal, // 动画模式
      onFinish: () => {
        // 动画执行完成
        console.info('play end')
      }
    }, () => {
      //闭包内更改状态
      this._translate = {
        x100,
        y100,
        z0
      }
    })

    this.step3 = this.animationStep({
      duration: time, // 动画时长
      tempo: 0.5// 播放速率
      curve: Curve.EaseInOut, // 动画曲线
      delay: 0// 动画延迟
      iterations: 1// 播放次数
      playMode: PlayMode.Normal, // 动画模式
      onFinish: () => {
        // 动画执行完成
        console.info('play end')
      }
    }, () => {
      //闭包内更改状态
      this._translate = {
        x100,
        y0,
        z0
      }
    })

    this.step4 = this.animationStep({
      duration: time, // 动画时长
      tempo: 0.5// 播放速率
      curve: Curve.EaseInOut, // 动画曲线
      delay: 0// 动画延迟
      iterations: 1// 播放次数
      playMode: PlayMode.Normal, // 动画模式
      onFinish: () => {
        // 动画执行完成
        console.info('play end')
      }
    }, () => {
      //闭包内更改状态
      this._translate = {
        x0,
        y0,
        z0
      }
    })
}

 

顺序执行 4 步动画:

Button('执行动画').margin({ bottom: 50 }).onClick(async () => {
    await this.step1()
    await this.step2()
    await this.step3()
    await this.step4()
})

 

 

实现 AnimateCSS 动画

   

 

AnimateCSS:

https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.css

https://animate.style/
 pulse 动画:Harmony

看下 pulse 动画样式代码:

.animate__pulse {
  -webkit-animation-name: pulse;
  animation-name: pulse;
  -webkit-animation-timing-function: ease-in-out;
  animation-timing-function: ease-in-out;
}

@keyframes pulse {
  from {
    -webkit-transformscale3d(1, 1, 1);
    transformscale3d(1, 1, 1);
  }

  50% {
    -webkit-transformscale3d(1.05, 1.05, 1.05);
    transformscale3d(1.05, 1.05, 1.05);
  }

  to {
    -webkit-transformscale3d(1, 1, 1);
    transformscale3d(1, 1, 1);
  }
}

 

ETS 实现:

@State _scale: ScaleOptions = {
    x: 1,
    y: 1,
    z: 1
}

...

Column() {
    Text('Animate.css')
      .fontSize(50)
      .fontWeight(FontWeight.Bold)
      .fontColor('#351c75')
      .translate(this._translate) // 位移变换
      .scale(this._scale) //比例变化
}

 

动画方法:
  • 传递一个动画总时长 time

  • 第一步动画执行段为 0%-50%,所以动画执行时长为总时长time * 50%

  • 第二步动画执行段为 50%-100%,所以动画执行时长为总时长time * 50%

	
async pulse(time{
    // 0% - 50%
    let step1 = this.animationStep({
      duration: time * 0.5// 动画时长
      tempo: 0.5// 播放速率
      curve: Curve.EaseInOut, // 动画曲线
      delay: 0// 动画延迟
      iterations: 1// 播放次数
      playMode: PlayMode.Normal, // 动画模式
    }, () => {
      this._scale = {
        x: 1.05,
        y: 1.05,
        z: 1.05
      }
    })

    // 50% - 100%
    let step2 = this.animationStep({
      duration: time * 0.5// 动画时长
      tempo: 0.5// 播放速率
      curve: Curve.EaseInOut, // 动画曲线
      delay: 0// 动画延迟
      iterations: 1// 播放次数
      playMode: PlayMode.Normal, // 动画模式
    }, () => {
      this._scale = {
        x: 1,
        y: 1,
        z: 1
      }
    })

    await step1()
    await step2()
}

 

执行动画:

Button('执行PULSE动画').margin({ bottom: 50 }).onClick(async () => {
    this.pulse(500)
})

 

Harmony

审核编辑 :李倩


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分