【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器 ...

打印 上一主题 下一主题

主题 910|帖子 910|积分 2730

【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器

@AnimatableExtend装饰器用于自定义可动画的属性方法,在这个属性方法中修改组件不可动画的属性。在动画执行过程时,通过逐帧回调函数修改不可动画属性值,让不可动画属性也能实现动画效果。
​                ● 可动画属性:如果一个属性方法在animation属性前调用,改变这个属性的值可以生效animation属性的动画效果,这个属性称为可动画属性。比如height、width、backgroundColor、translate等。
​                ● 不可动画属性:如果一个属性方法在animation属性前调用,改变这个属性的值不能生效animation属性的动画效果,这个属性称为不可动画属性。比如Text组件的fontSize属性、Ployline组件的points属性等。
说明:
该装饰器从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
装饰器使用说明

语法
  1. @AnimatableExtend(UIComponentName) function functionName(value: typeName) {
  2.   .propertyName(value)
  3. }
复制代码


​                ● @AnimatableExtend仅支持定义在全局,不支持在组件内部定义。
​                ● @AnimatableExtend定义的函数参数类型必须为number类型或者实现 AnimtableArithmetic接口的自定义类型。
​                ● @AnimatableExtend定义的函数体内只能调用@AnimatableExtend括号内组件的属性方法。
AnimtableArithmetic接口说明

对复杂数据类型做动画,需要实现AnimtableArithmetic接口中加法、减法、乘法和判断相等函数。
名称入参类型返回值类型说明plusAnimtableArithmeticAnimtableArithmetic加法函数subtractAnimtableArithmeticAnimtableArithmetic减法函数multiplynumberAnimtableArithmetic乘法函数equalsAnimtableArithmeticboolean相等判断函数使用场景

以下示例实现字体大小的动画效果。
  1. @AnimatableExtend(Text) function animatableFontSize(size: number) {
  2.   .fontSize(size)
  3. }
  4. @Entry
  5. @Component
  6. struct AnimatablePropertyExample {
  7.   @State fontSize: number = 20
  8.   build() {
  9.     Column() {
  10.       Text("AnimatableProperty")
  11.         .animatableFontSize(this.fontSize)
  12.         .animation({duration: 1000, curve: "ease"})
  13.       Button("Play")
  14.         .onClick(() => {
  15.           this.fontSize = this.fontSize == 20 ? 36 : 20
  16.         })
  17.     }.width("100%")
  18.     .padding(10)
  19.   }
  20. }
复制代码

以下示例实现折线的动画效果。
  1. class Point {
  2.   x: number
  3.   y: number
  4.   constructor(x: number, y: number) {
  5.     this.x = x
  6.     this.y = y
  7.   }
  8.   plus(rhs: Point): Point {
  9.     return new Point(this.x + rhs.x, this.y + rhs.y)
  10.   }
  11.   subtract(rhs: Point): Point {
  12.     return new Point(this.x - rhs.x, this.y - rhs.y)
  13.   }
  14.   multiply(scale: number): Point {
  15.     return new Point(this.x * scale, this.y * scale)
  16.   }
  17.   equals(rhs: Point): boolean {
  18.     return this.x === rhs.x && this.y === rhs.y
  19.   }
  20. }
  21. class PointVector extends Array<Point> implements AnimatableArithmetic<PointVector> {
  22.   constructor(value: Array<Point>) {
  23.     super();
  24.     value.forEach(p => this.push(p))
  25.   }
  26.   plus(rhs: PointVector): PointVector {
  27.     let result = new PointVector([])
  28.     const len = Math.min(this.length, rhs.length)
  29.     for (let i = 0; i < len; i++) {
  30.       result.push((this as Array<Point>)[i].plus((rhs as Array<Point>)[i]))
  31.     }
  32.     return result
  33.   }
  34.   subtract(rhs: PointVector): PointVector {
  35.     let result = new PointVector([])
  36.     const len = Math.min(this.length, rhs.length)
  37.     for (let i = 0; i < len; i++) {
  38.       result.push((this as Array<Point>)[i].subtract((rhs as Array<Point>)[i]))
  39.     }
  40.     return result
  41.   }
  42.   multiply(scale: number): PointVector {
  43.     let result = new PointVector([])
  44.     for (let i = 0; i < this.length; i++) {
  45.       result.push((this as Array<Point>)[i].multiply(scale))
  46.     }
  47.     return result
  48.   }
  49.   equals(rhs: PointVector): boolean {
  50.     if (this.length != rhs.length) {
  51.       return false
  52.     }
  53.     for (let i = 0; i < this.length; i++) {
  54.       if (!(this as Array<Point>)[i].equals((rhs as Array<Point>)[i])) {
  55.         return false
  56.       }
  57.     }
  58.     return true
  59.   }
  60.   get(): Array<Object[]> {
  61.     let result: Array<Object[]> = []
  62.     this.forEach(p => result.push([p.x, p.y]))
  63.     return result
  64.   }
  65. }
  66. @AnimatableExtend(Polyline) function animatablePoints(points: PointVector) {
  67.   .points(points.get())
  68. }
  69. @Entry
  70. @Component
  71. struct AnimatablePropertyExample {
  72.   @State points: PointVector = new PointVector([
  73.     new Point(50, Math.random() * 200),
  74.     new Point(100, Math.random() * 200),
  75.     new Point(150, Math.random() * 200),
  76.     new Point(200, Math.random() * 200),
  77.     new Point(250, Math.random() * 200),
  78.   ])
  79.   build() {
  80.     Column() {
  81.       Polyline()
  82.         .animatablePoints(this.points)
  83.         .animation({duration: 1000, curve: "ease"})
  84.         .size({height:220, width:300})
  85.         .fill(Color.Green)
  86.         .stroke(Color.Red)
  87.         .backgroundColor('#eeaacc')
  88.       Button("Play")
  89.         .onClick(() => {
  90.           this.points = new PointVector([
  91.             new Point(50, Math.random() * 200),
  92.             new Point(100, Math.random() * 200),
  93.             new Point(150, Math.random() * 200),
  94.             new Point(200, Math.random() * 200),
  95.             new Point(250, Math.random() * 200),
  96.           ])
  97.         })
  98.     }.width("100%")
  99.     .padding(10)
  100.   }
  101. }
复制代码

本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表