• 【中秋国庆不断更】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接口中加法、减法、乘法和判断相等函数。

    名称

    入参类型

    返回值类型

    说明

    plus

    AnimtableArithmetic

    AnimtableArithmetic

    加法函数

    subtract

    AnimtableArithmetic

    AnimtableArithmetic

    减法函数

    multiply

    number

    AnimtableArithmetic

    乘法函数

    equals

    AnimtableArithmetic

    boolean

    相等判断函数

    使用场景

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

    1. @AnimatableExtend(Text) function animatableFontSize(sizenumber) {
    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 ? 3620
    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. }

  • 相关阅读:
    模拟实现string类
    SQL之索引
    静态共享代理和静态独享有哪些区别?怎么选择?
    [附源码]java毕业设计成都团结石材城商家协作系统
    Python课程设计-图书管理系统
    C++学习——引用详解
    通过Demo学WPF—数据绑定(一)✨
    运算符【Java基础】
    web大作业:简单的学生网页作业源码 基于html css javascript jquery实现智能分控网站
    0/1分数规划专题
  • 原文地址:https://blog.csdn.net/OpenHarmony_dev/article/details/133309841