百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

10个案例详解AnimatableExtend装饰器定义可动画属性

zhezhongyun 2025-07-09 00:19 1 浏览

Hello,大家好,我是 V 哥。HarmonyOS NEXT开发中,使用@AnimatableExtend装饰器来定义可动画属性是个很好玩的事情,废话不多说,马上进入主题,先来看一下基本语法,接着 V 哥提供10个好玩的案例供你参考。

@AnimatableExtend装饰器的使用说明

@AnimatableExtend装饰器用于自定义可动画的属性方法,允许开发者在动画执行过程中通过逐帧回调函数修改不可动画属性值,从而使不可动画属性也能实现动画效果。

语法

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

AnimtableArithmetic接口说明

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

名称

入参类型

返回值类型

说明

plus

AnimtableArithmetic

AnimtableArithmetic

加法函数

subtract

AnimtableArithmetic

AnimtableArithmetic

减法函数

multiply

number

AnimtableArithmetic

乘法函数

equals

AnimtableArithmetic

boolean

相等判断函数

业务场景代码案例

案例1:实现字体大小的动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@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)
  }
}

在这个例子中,我们定义了一个animatableFontSize函数来修改Text组件的fontSize属性,使其可以动画化。通过改变fontSize状态的值,我们可以实现字体大小的动画效果。

案例2:实现折线的动画效果

class Point {
  x: number;
  y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
  // 实现AnimtableArithmetic接口的方法
  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;
  }
}

// 自定义可动画属性接口
@AnimatableExtend(Polyline) function animatablePoints(points: Array<Point>) {
  .points(points)
}

@Entry
@Component
struct PolylineAnimationExample {
  @State points: Array<Point> = [new Point(0, 0), new Point(100, 100)];
  build() {
    Column() {
      Polyline()
        .animatablePoints(this.points) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 1000, curve: "ease" }) // 为自定义可动画属性接口绑定动画
      Button("Play")
        .onClick(() => {
          // 改变自定义可动画属性的参数,产生动画
          this.points = this.points.map(point => point.multiply(1.1));
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个Point类来表示折线上的点,并实现了AnimtableArithmetic接口。然后我们定义了一个animatablePoints函数来修改Polyline组件的points属性,使其可以动画化。通过改变points状态的值,我们可以实现折线的动画效果。

案例3:实现颜色渐变动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(View) function animatableBackgroundColor(color: number) {
  .backgroundColor(color)
}

@Entry
@Component
struct ColorAnimationExample {
  @State color: number = 0xff0000; // 初始颜色为红色
  build() {
    Column() {
      View()
        .width(200)
        .height(200)
        .animatableBackgroundColor(this.color) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 2000, curve: "ease" }) // 为自定义可动画属性接口绑定动画
      Button("Play")
        .onClick(() => {
          this.color = this.color === 0xff0000 ? 0x00ff00 : 0xff0000; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableBackgroundColor函数来修改View组件的backgroundColor属性,使其可以动画化。通过改变color状态的值,我们可以实现背景颜色的渐变动画效果。

案例4:实现旋转动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(Image) function animatableRotate(angle: number) {
  .rotate(angle)
}

@Entry
@Component
struct RotateAnimationExample {
  @State angle: number = 0;
  build() {
    Column() {
      Image("https://example.com/image.png")
        .width(100)
        .height(100)
        .animatableRotate(this.angle) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 2000, curve: "linear" }) // 为自定义可动画属性接口绑定动画
      Button("Play")
        .onClick(() => {
          this.angle = this.angle === 0 ? 360 : 0; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableRotate函数来修改Image组件的rotate属性,使其可以动画化。通过改变angle状态的值,我们可以实现图片的旋转动画效果。

案例5:实现透明度渐变动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(Text) function animatableOpacity(opacity: number) {
  .opacity(opacity)
}

@Entry
@Component
struct OpacityAnimationExample {
  @State opacity: number = 0; // 初始透明度为0
  build() {
    Column() {
      Text("Opacity Animation")
        .fontSize(20)
        .animatableOpacity(this.opacity) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 2000, curve: "ease-in-out" }) // 为自定义可动画属性接口绑定动画
      Button("Play")
        .onClick(() => {
          this.opacity = this.opacity === 0 ? 1 : 0; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableOpacity函数来修改Text组件的opacity属性,使其可以动画化。通过改变opacity状态的值,我们可以实现文本的透明度渐变动画效果。

案例6:实现按钮的弹性动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(Button) function animatableScale(scale: number) {
  .scale(scale)
}

@Entry
@Component
struct ElasticButtonExample {
  @State scaleValue: number = 1; // 初始缩放比例为1
  build() {
    Column() {
      Button("Click Me")
        .width(100)
        .height(50)
        .backgroundColor(0x3399ff)
        .textColor(0xffffff)
        .animatableScale(this.scaleValue) // 将自定义可动画属性接口设置到组件上
        .onClick(() => {
          this.scaleValue = this.scaleValue === 1 ? 0.8 : 1; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableScale函数来修改Button组件的scale属性,使其可以动画化。点击按钮时,按钮会有一个弹性缩放的效果。

案例7:实现滑动进入的动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(View) function animatableTranslationX(translationX: number) {
  .translationX(translationX)
}

@Entry
@Component
struct SlideInAnimationExample {
  @State translation: number = -200; // 初始横向位移为-200
  build() {
    Column() {
      View()
        .width(200)
        .height(200)
        .backgroundColor(0x33cc33)
        .animatableTranslationX(this.translation) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 1000, curve: "ease-out" }) // 为自定义可动画属性接口绑定动画
      Button("Slide In")
        .onClick(() => {
          this.translation = 0; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableTranslationX函数来修改View组件的translationX属性,使其可以动画化。点击按钮时,视图会从左侧滑动进入。

案例8:实现视图的淡入淡出动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(View) function animatableAlpha(alpha: number) {
  .alpha(alpha)
}

@Entry
@Component
struct FadeAnimationExample {
  @State alphaValue: number = 0; // 初始透明度为0
  build() {
    Column() {
      View()
        .width(200)
        .height(200)
        .backgroundColor(0x6633ff)
        .animatableAlpha(this.alphaValue) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 1000, curve: "ease-in-out" }) // 为自定义可动画属性接口绑定动画
      Button("Fade In")
        .onClick(() => {
          this.alphaValue = this.alphaValue === 0 ? 1 : 0; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableAlpha函数来修改View组件的alpha属性,使其可以动画化。点击按钮时,视图会有一个淡入淡出的效果。

案例9:实现文本的上下移动动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(Text) function animatableTranslationY(translationY: number) {
  .translationY(translationY)
}

@Entry
@Component
struct TextMoveAnimationExample {
  @State translationY: number = -100; // 初始纵向位移为-100
  build() {
    Column() {
      Text("Move Me")
        .fontSize(20)
        .animatableTranslationY(this.translationY) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 1000, curve: "ease-in-out" }) // 为自定义可动画属性接口绑定动画
      Button("Move Up & Down")
        .onClick(() => {
          this.translationY = this.translationY === -100 ? 0 : -100; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableTranslationY函数来修改Text组件的translationY属性,使其可以动画化。点击按钮时,文本会有一个上下移动的效果。

案例10:实现进度条的增长动画效果

// 使用@AnimatableExtend装饰器,自定义可动画属性接口
@AnimatableExtend(ProgressBar) function animatableProgress(progress: number) {
  .progress(progress)
}

@Entry
@Component
struct ProgressBarAnimationExample {
  @State progressValue: number = 0; // 初始进度为0
  build() {
    Column() {
      ProgressBar()
        .width(300)
        .animatableProgress(this.progressValue) // 将自定义可动画属性接口设置到组件上
        .animation({ duration: 2000, curve: "ease-in-out" }) // 为自定义可动画属性接口绑定动画
      Button("Increase")
        .onClick(() => {
          this.progressValue = this.progressValue === 0 ? 1 : 0; // 改变自定义可动画属性的参数,产生动画
        })
    }.width("100%")
    .padding(10)
  }
}

在这个例子中,我们定义了一个animatableProgress函数来修改ProgressBar组件的progress属性,使其可以动画化。点击按钮时,进度条会有一个增长的效果。

关注威哥爱编程,一起鸿蒙起来。鸿蒙你我他,生态靠大家。

相关推荐

一篇文章带你了解SVG 渐变知识(svg动画效果)

渐变是一种从一种颜色到另一种颜色的平滑过渡。另外,可以把多个颜色的过渡应用到同一个元素上。SVG渐变主要有两种类型:(Linear,Radial)。一、SVG线性渐变<linearGradie...

Vue3 实战指南:15 个高效组件开发技巧解析

Vue.js作为一款流行的JavaScript框架,在前端开发领域占据着重要地位。Vue3的发布,更是带来了诸多令人兴奋的新特性和改进,让开发者能够更高效地构建应用程序。今天,我们就来深入探讨...

CSS渲染性能优化(低阻抗喷油器阻值一般为多少欧)

在当今快节奏的互联网环境中,网页加载速度直接影响用户体验和业务转化率。页面加载时间每增加100毫秒,就会导致显著的流量和收入损失。作为前端开发的重要组成部分,CSS的渲染性能优化不容忽视。为什么CSS...

前端面试题-Vue 项目中,你做过哪些性能优化?

在Vue项目中,以下是我在生产环境中实践过且用户反馈较好的性能优化方案,整理为分类要点:一、代码层面优化1.代码分割与懒加载路由懒加载:使用`()=>import()`动态导入组件,结...

如何通过JavaScript判断Web页面按钮是否置灰?

在JavaScript语言中判断Web页面按钮是否置灰(禁用状态),可以通过以下几种方式实现,其具体情形取决于按钮的禁用方式(原生disabled属性或CSS样式控制):一、检查原生dis...

「图片显示移植-1」 尝试用opengl/GLFW显示图片

GLFW【https://www.glfw.org】调用了opengl来做图形的显示。我最近需要用opengl来显示图像,不能使用opencv等库。看了一个glfw的官网,里面有github:http...

大模型实战:Flask+H5三件套实现大模型基础聊天界面

本文使用Flask和H5三件套(HTML+JS+CSS)实现大模型聊天应用的基本方式话不多说,先贴上实现效果:流式输出:思考输出:聊天界面模型设置:模型设置会话切换:前言大模型的聊天应用从功能...

ae基础知识(二)(ae必学知识)

hi,大家好,我今天要给大家继续分享的还是ae的基础知识,今天主要分享的就是关于ae的路径文字制作步骤(时间关系没有截图)、动态文字的制作知识、以及ae特效的扭曲的一些基本操作。最后再次复习一下ae的...

YSLOW性能测试前端调优23大规则(二十一)---避免过滤器

AlphalmageLoader过滤器是IE浏览器专有的一个关于图片的属性,主要是为了解决半透明真彩色的PNG显示问题。AlphalmageLoader的语法如下:filter:progid:DX...

Chrome浏览器的渲染流程详解(chrome预览)

我们来详细介绍一下浏览器的**渲染流程**。渲染流程是浏览器将从网络获取到的HTML、CSS和JavaScript文件,最终转化为用户屏幕上可见的、可交互的像素画面的过程。它是一个复杂但高度优...

在 WordPress 中如何设置背景色透明度?

最近开始写一些WordPress专业的知识,阅读数奇低,然后我发一些微信昵称技巧,又说我天天发这些小学生爱玩的玩意,写点文章真不容易。那我两天发点专业的东西,两天发点小学生的东西,剩下三天我看着办...

manim 数学动画之旅--图形样式(数学图形绘制)

manim绘制图形时,除了上一节提到的那些必需的参数,还有一些可选的参数,这些参数可以控制图形显示的样式。绘制各类基本图形(点,线,圆,多边形等)时,每个图形都有自己的默认的样式,比如上一节的图形,...

Web页面如此耗电!到了某种程度,会是大损失

现在用户上网大多使用移动设备或者笔记本电脑。对这两者来说,电池寿命都很重要。在这篇文章里,我们将讨论影响电池寿命的因素,以及作为一个web开发者,我们如何让网页耗电更少,以便用户有更多时间来关注我们的...

11.mxGraph的mxCell和Styles样式(graph style)

3.1.3mxCell[翻译]mxCell是顶点和边的单元对象。mxCell复制了模型中可用的许多功能。使用上的关键区别是,使用模型方法会创建适当的事件通知和撤销,而使用单元进行更改时没有更改记...

按钮重复点击:这“简单”问题,为何难住大半面试者与开发者?

在前端开发中,按钮重复点击是一个看似不起眼,实则非常普遍且容易引发线上事故的问题。想象一下:提交表单时,因为网络卡顿或手抖,重复点击导致后端创建了多条冗余数据…这些场景不仅影响用户体验,更可能造成实...