美文网首页@IT·互联网鸿蒙(HarmonyOS)开发知识
HarmonyOS 应用开发之@AnimatableExtend

HarmonyOS 应用开发之@AnimatableExtend

作者: 迪士尼在逃程序员 | 来源:发表于2024-07-25 21:22 被阅读0次

    @AnimatableExtend装饰器用于自定义可动画的属性方法,在这个属性方法中修改组件不可动画的属性。在动画执行过程时,通过逐帧回调函数修改不可动画属性值,让不可动画属性也能实现动画效果。

    • 可动画属性:如果一个属性方法在animation属性前调用,改变这个属性的值可以生效animation属性的动画效果,这个属性称为可动画属性。比如height、width、backgroundColor、translate属性,Text组件的fontSize属性等。

    • 不可动画属性:如果一个属性方法在animation属性前调用,改变这个属性的值不能生效animation属性的动画效果,这个属性称为不可动画属性。比如Polyline组件的points属性等。

    说明:

    该装饰器从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

    装饰器使用说明

    语法

    @AnimatableExtend(UIComponentName) function functionName(value: typeName) { 
      .propertyName(value)
    }
    
    • @AnimatableExtend仅支持定义在全局,不支持在组件内部定义。
    • @AnimatableExtend定义的函数参数类型必须为number类型或者实现 AnimtableArithmetic<T>接口的自定义类型。
    • @AnimatableExtend定义的函数体内只能调用@AnimatableExtend括号内组件的属性方法。

    AnimtableArithmetic<T>接口说明

    对复杂数据类型做动画,需要实现AnimtableArithmetic<T>接口中加法、减法、乘法和判断相等函数。

    名称 入参类型 返回值类型 说明
    plus AnimtableArithmetic<T> AnimtableArithmetic<T> 加法函数
    subtract AnimtableArithmetic<T> AnimtableArithmetic<T> 减法函数
    multiply number AnimtableArithmetic<T> 乘法函数
    equals AnimtableArithmetic<T> boolean 相等判断函数

    使用场景

    以下示例实现字体大小的动画效果。

    @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)
      }
    }
    

    以下示例实现折线的动画效果。

    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>)[i].plus((rhs as Array<Point>)[i]))
        }
        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>)[i].subtract((rhs as Array<Point>)[i]))
        }
        return result
      }
      multiply(scale: number): PointVector {
        let result = new PointVector([])
        for (let i = 0; i < this.length; i++) {
          result.push((this as Array<Point>)[i].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>)[i].equals((rhs as Array<Point>)[i])) {
            return false
          }
        }
        return true
      }
      get(): Array<Object[]> {
        let result: Array<Object[]> = []
        this.forEach(p => result.push([p.x, p.y]))
        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)
      }
    }
    

    写在最后

    • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
    • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
    • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
    • 想要获取更多完整鸿蒙最新学习知识点,请移步前往小编:https://gitee.com/MNxiaona/733GH/blob/master/jianshu

    相关文章

      网友评论

        本文标题:HarmonyOS 应用开发之@AnimatableExtend

        本文链接:https://www.haomeiwen.com/subject/ecsitjtx.html