自定义属性动画

146 阅读2分钟

官网地址:自定义属性动画

1. 概述

在系统提供的属性,有一些属性是不支持动画的,比如:zIndex, colorFilter等。但是在实际开发中,我们可能会需要让这些属性也能够跟随动画进行变化。鸿蒙系统提供了自定义属性动画的能力。

2. 自定义属性动画

2.1. @AnimatableExtend装饰器

使用@AnimatableExtend装饰器,可以跟某个组件的某个属性设置动画效果。为此属性绑定状态变量后,当属性动画执行时,会引起属性执行动画效果。

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

2.2. AnimatableArithmetic

如上所述,@AnimatableExnted只支持number和AnimatableArithmetic类型的参数,对于非number类型的参数,必须实现AnimatableArithmetic才能使用@AnimatableExnted定义属性的动画。

实现AnimatableArithmetic需要重写以下方法,系统根据方法的返回值,计算动画插值,从而实现动画的效果。

名称入参类型返回值类型说明
plusAnimatableArithmeticAnimatableArithmetic加法函数
subtractAnimatableArithmeticAnimatableArithmetic减法函数
multiplynumberAnimatableArithmetic乘法函数
equalsAnimatableArithmeticboolean相等判断函数

2.3. colorFilter属性动画

colorFilter是Image的属性,可以对Image进行染色处理。colorFilter属性不支持动画,为了能够让Image在染色的过程中,实现颜色过渡的效果,需要给colorFilter增加动画,代码如下:

import { common2D, drawing } from '@kit.ArkGraphics2D'

@AnimatableExtend(Image)
function animatableColorFilter(value: MyColorFilter) {
  .colorFilter(drawing.ColorFilter.createBlendModeColorFilter(value.color, drawing.BlendMode.MODULATE));
}

@Component
export struct AnimationCustomPropertyView {
  @State private color: common2D.Color = {
    alpha: 255,
    red: 255,
    green: 255,
    blue: 0
  };

  build() {
    Column({space: 20}) {
      Stack(){
        Image($rawfile('2.png'))
          .width(230)
          .height(400)
          .fitOriginalSize(false)
          .autoResize(false)
          .animatableColorFilter(new MyColorFilter(this.color))
          .animation({ duration: 8000, curve: Curve.Linear })
          .border({width: 2, color: Color.Red})
      }



      Button("anim start")
        .onClick(() => {
          this.color = {
            alpha: 255,
            red: 0,
            green: 255,
            blue: 0
          }
        })

    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.Gray)
  }
}


class MyColorFilter implements AnimatableArithmetic<MyColorFilter> {
  public color: common2D.Color;

  constructor(color: common2D.Color) {
    this.color = color;
  }

  plus(rhs: MyColorFilter): MyColorFilter {
    const color: common2D.Color = {
      alpha: this.color.alpha + rhs.color.alpha,
      red: this.color.red + rhs.color.red,
      green: this.color.green + rhs.color.green,
      blue: this.color.blue + this.color.blue
    }

    return new MyColorFilter(color);
  }

  subtract(rhs: MyColorFilter): MyColorFilter {
    const color: common2D.Color = {
      alpha: this.color.alpha - rhs.color.alpha,
      red: this.color.red - rhs.color.red,
      green: this.color.green - rhs.color.green,
      blue: this.color.blue - this.color.blue
    }

    return new MyColorFilter(color);
  }

  multiply(scale: number): MyColorFilter {
    const color: common2D.Color = {
      alpha: this.color.alpha * scale,
      red: this.color.red * scale,
      green: this.color.green * scale,
      blue: this.color.blue * scale
    }

    return new MyColorFilter(color);
  }

  equals(rhs: MyColorFilter): boolean {
    return this.color.alpha === rhs.color.alpha && (this.color.red === rhs.color.red) &&
      (this.color.green === rhs.color.green) && (this.color.blue == rhs.color.blue)
  }
}

MyColorFilter实现了AnimatableArithmetic接口,内部包含了common2D.Color, 作为动画属性的参数。

效果如下: