官网地址:自定义属性动画
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需要重写以下方法,系统根据方法的返回值,计算动画插值,从而实现动画的效果。
| 名称 | 入参类型 | 返回值类型 | 说明 |
|---|---|---|---|
| plus | AnimatableArithmetic | AnimatableArithmetic | 加法函数 |
| subtract | AnimatableArithmetic | AnimatableArithmetic | 减法函数 |
| multiply | number | AnimatableArithmetic | 乘法函数 |
| equals | AnimatableArithmetic | boolean | 相等判断函数 |
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, 作为动画属性的参数。
效果如下: