写点什么

【中秋国庆不断更】OpenHarmony 定义可动画属性:@AnimatableExtend 装饰器

  • 2023-09-30
    广东
  • 本文字数:2550 字

    阅读完需:约 8 分钟

【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器

@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<T>接口的自定义类型。

● @AnimatableExtend 定义的函数体内只能调用 @AnimatableExtend 括号内组件的属性方法。

AnimtableArithmetic<T>接口说明

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


使用场景

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


@AnimatableExtend(Text) function animatableFontSize(size: number) {  .fontSize(size)}
@Entry@Componentstruct 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@Componentstruct 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开发者官方账号 2021-12-15 加入

OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展

评论

发布
暂无评论
【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器_OpenHarmony开发者_InfoQ写作社区