OpenHarmony定义可动画属性:@AnimatableExtend装饰器

608 篇文章 11 订阅
392 篇文章 0 订阅

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

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

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

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值