河曲智叟 发表于 2023-10-11 03:51:21

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

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

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

语法

@AnimatableExtend(UIComponentName) function functionName(value: typeName) {
.propertyName(value)
}

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

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

以下示例实现字体大小的动画效果。
@AnimatableExtend(Text) function animatableFontSize(size: number) {
.fontSize(size)
}

@Entry
@Component
struct AnimatablePropertyExample {
@State fontSize: number = 20
build() {
    Column() {
      Text("AnimatableProperty")
      .animatableFontSize(this.fontSize)
      .animation({duration: 1000, curve: "ease"})
      Button("Play")
      .onClick(() => {
          this.fontSize = this.fontSize == 20 ? 36 : 20
      })
    }.width("100%")
    .padding(10)
}
}https://img2023.cnblogs.com/other/2824423/202309/2824423-20230930212924417-409553794.png
以下示例实现折线的动画效果。
class Point {
x: number
y: number

constructor(x: number, y: number) {
    this.x = x
    this.y = y
}
plus(rhs: Point): Point {
    return new Point(this.x + rhs.x, this.y + rhs.y)
}
subtract(rhs: Point): Point {
    return new Point(this.x - rhs.x, this.y - rhs.y)
}
multiply(scale: number): Point {
    return new Point(this.x * scale, this.y * scale)
}
equals(rhs: Point): boolean {
    return this.x === rhs.x && this.y === rhs.y
}
}

class PointVector extends Array<Point> implements AnimatableArithmetic<PointVector> {
constructor(value: Array<Point>) {
    super();
    value.forEach(p => this.push(p))
}
plus(rhs: PointVector): PointVector {
    let result = new PointVector([])
    const len = Math.min(this.length, rhs.length)
    for (let i = 0; i < len; i++) {
      result.push((this as Array<Point>).plus((rhs as Array<Point>)))
    }
    return result
}
subtract(rhs: PointVector): PointVector {
    let result = new PointVector([])
    const len = Math.min(this.length, rhs.length)
    for (let i = 0; i < len; i++) {
      result.push((this as Array<Point>).subtract((rhs as Array<Point>)))
    }
    return result
}
multiply(scale: number): PointVector {
    let result = new PointVector([])
    for (let i = 0; i < this.length; i++) {
      result.push((this as Array<Point>).multiply(scale))
    }
    return result
}
equals(rhs: PointVector): boolean {
    if (this.length != rhs.length) {
      return false
    }
    for (let i = 0; i < this.length; i++) {
      if (!(this as Array<Point>).equals((rhs as Array<Point>))) {
      return false
      }
    }
    return true
}
get(): Array<Object[]> {
    let result: Array<Object[]> = []
    this.forEach(p => result.push())
    return result
}
}

@AnimatableExtend(Polyline) function animatablePoints(points: PointVector) {
.points(points.get())
}

@Entry
@Component
struct AnimatablePropertyExample {
@State points: PointVector = new PointVector([
    new Point(50, Math.random() * 200),
    new Point(100, Math.random() * 200),
    new Point(150, Math.random() * 200),
    new Point(200, Math.random() * 200),
    new Point(250, Math.random() * 200),
])
build() {
    Column() {
      Polyline()
      .animatablePoints(this.points)
      .animation({duration: 1000, curve: "ease"})
      .size({height:220, width:300})
      .fill(Color.Green)
      .stroke(Color.Red)
      .backgroundColor('#eeaacc')
      Button("Play")
      .onClick(() => {
          this.points = new PointVector([
            new Point(50, Math.random() * 200),
            new Point(100, Math.random() * 200),
            new Point(150, Math.random() * 200),
            new Point(200, Math.random() * 200),
            new Point(250, Math.random() * 200),
          ])
      })
    }.width("100%")
    .padding(10)
}
}https://img2023.cnblogs.com/other/2824423/202309/2824423-20230930212924995-1087341410.png
本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器