HarmonyOS:@AnimatableExtend 装饰器自学指南

在最近的项目开发中,我遇到了需要实现复杂动画效果的需求。在探索解决方案的过程中,我发现了 @AnimatableExtend 装饰器,它为实现动画效果提供了一种非常灵活且强大的方式。然而,在学习这个装饰器的过程中,我发现相关的资料并不是特别丰富,而且很多资料都缺乏系统性的讲解。因此,我决定写这篇博客,将自己的学习经验和理解分享出来,希望能帮助更多的开发者快速掌握 @AnimatableExtend 装饰器的使用。

1. @AnimatableExtend 装饰器概述

@AnimatableExtend 装饰器从 API Version 10 开始支持,为动画效果的实现提供了一种便捷的方式。从 API version 11 开始,它支持在元服务中使用。这个装饰器允许我们自定义动画属性,使得我们可以对不同类型的数据进行动画处理。

1.1 装饰器使用规则

  • 定义位置@AnimatableExtend 仅支持定义在全局,不支持在组件内部定义。
  • 参数类型@AnimatableExtend 定义的函数参数类型必须为 number 类型或者实现 AnimatableArithmetic<T> 接口的自定义类型。
  • 函数体限制@AnimatableExtend 定义的函数体内只能调用 @AnimatableExtend 括号内组件的属性方法。

1.2 AnimatableArithmetic<T> 接口说明

AnimatableArithmetic<T> 接口定义了非 number 数据类型的动画运算规则。对于非 number 类型的数据(如数组、结构体、颜色等)做动画,需要实现该接口中的加法、减法、乘法和判断相等函数,使得该数据能参与动画的插值运算和识别该数据是否发生改变。

名称入参类型返回值类型说明
plusAnimatableArithmetic<T>AnimatableArithmetic<T>定义该数据类型的加法运算规则
subtractAnimatableArithmetic<T>AnimatableArithmetic<T>定义该数据类型的减法运算规则
multiplynumberAnimatableArithmetic<T>定义该数据类型的乘法运算规则
equalsAnimatableArithmetic<T>boolean定义该数据类型的相等判断规则

2. 使用场景示例

2.1 改变 Text 组件宽度实现逐帧布局效果

下面的示例通过改变 Text 组件的宽度实现逐帧布局的效果。

@AnimatableExtend(Text)
function animatableWidth(width: number) {.width(width)
}@Entry
@Component
struct AnimatablePropertyExample {@State textWidth: number = 100;build() {Column() {Text("AnimatableProperty").animatableWidth(this.textWidth).animation({ duration: 3000, curve: Curve.EaseInOut })Button("Play").onClick(() => {this.textWidth = this.textWidth == 100 ? 200 : 100;})}.width("100%").padding(20)}
}

在这个示例中,我们定义了一个 animatableWidth 函数,通过 @AnimatableExtend 装饰器将其应用到 Text 组件上。点击按钮时,textWidth 的值会在 100 和 200 之间切换,从而触发动画效果。

2.2 实现折线的动画效果

为了实现折线的动画效果,我们需要定义一个自定义类型 Point 和 PointVector,并让 PointVector 实现 AnimatableArithmetic<T> 接口。

class Point {x: numbery: numberconstructor(x: number, y: number) {this.x = xthis.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}
}// PointVector实现了AnimatableArithmetic<T>接口
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
@Component
struct AnimatablePropertyExample {@State points: PointVector = new PointVector([new Point(30, Math.random() * 250),new Point(80, Math.random() * 250),new Point(130, Math.random() * 250),new Point(180, Math.random() * 250),new Point(230, Math.random() * 250),])build() {Column() {Polyline().animatablePoints(this.points).animation({ duration: 1500, curve: Curve.EaseOut })// 设置动画参数.size({ height: 250, width: 350 }).fill(Color.Blue).stroke(Color.Yellow).backgroundColor('#aaccff')Button("Play").onClick(() => {// points是实现了可动画协议的数据类型,points在动画过程中可按照定义的运算规则、动画参数从之前的PointVector变为新的PointVector数据,产生每一帧的PointVector数据,进而产生动画this.points = new PointVector([new Point(30, Math.random() * 250),new Point(80, Math.random() * 250),new Point(130, Math.random() * 250),new Point(180, Math.random() * 250),new Point(230, Math.random() * 250),])})}.width("100%").padding(20)}
}

在这个示例中,我们定义了 Point 类表示二维平面上的点,PointVector 类表示点的数组。通过实现 AnimatableArithmetic<T> 接口,我们为 PointVector 定义了加法、减法、乘法和相等判断规则。然后,我们使用 @AnimatableExtend 装饰器将 animatablePoints 函数应用到 Polyline 组件上,点击按钮时,折线的顶点位置会随机变化,从而实现动画效果。

3. 总结

@AnimatableExtend 装饰器为实现复杂动画效果提供了一种强大而灵活的方式。通过自定义动画属性和实现 AnimatableArithmetic<T> 接口,我们可以对不同类型的数据进行动画处理。在实际开发中,我们可以根据具体需求灵活运用这个装饰器,实现各种炫酷的动画效果。希望这篇博客能帮助你快速掌握 @AnimatableExtend 装饰器的使用,让你的应用更加生动有趣。

通过以上的学习和实践,你可以逐步掌握 @AnimatableExtend 装饰器的使用方法,并且在实际项目中灵活运用,为用户带来更加丰富的动画体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38666.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows server 2022域控制服务器的配置

Windows server 2022介绍 一、核心特性与改进 安全核心服务器&#xff08;Secured-Core Server&#xff09; 硬件级安全&#xff1a;支持基于硬件的安全功能&#xff08;如TPM 2.0、Secure Boot、基于虚拟化的安全防护VBS&#xff09;&#xff0c;防止固件攻击。受信任的启动链…

C++语法之模板函数和模板类

模板函数是什么&#xff1f;就是不指定类型的函数&#xff0c;不指定类型如何写代码?所以得用到模板&#xff0c;可以先用模板代替&#xff0c;就好像方程式&#xff0c;先用x,y代替一样。 它的写法是这样&#xff0c;定义函数时&#xff0c;开头加一句:(其中的T就相当于x,y之…

时序分析笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、周期约束 二、建立时间和保持时间 三、时序路径 四、时序模型 前言 约束文件笔记&#xff0c;傅里叶的猫的视频。 一、周期约束 时序约束就是告诉软件输…

六十天前端强化训练之第二十八天之Composition 函数完全指南

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、核心概念解析 1.1 什么是 Composition 函数 1.2 为什么需要封装 1.3 设计原则 二、实战案例&#xff1a;鼠标跟踪器 2.1 未封装版本 2.2 封装后的 Composition 函数…

MySQL 锁机制详解

MySQL 锁机制详解 5.1 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、 RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有 效性是所有数…

常见中间件漏洞攻略-Apache篇

漏洞名称&#xff1a;Apache HTTP Server 路径穿越漏洞-CVE-2021-41773 第一步&#xff1a;拉取环境、启动环境 #拉取环境 docker pull blueteamsteve/cve-2021-41773:no-cgidhttp://121.40.229.129:8080#启动环境 docker run -dit -p 8080:80 blueteamsteve/cve-2021-41773:n…

站群服务器是什么意思呢?

站群服务器是一种专门为托管和管理多个网站而设计的服务器&#xff0c;其核心特点是为每个网站分配独立的IP地址。这种服务器通常用于SEO优化、提高网站权重和排名&#xff0c;以及集中管理多个网站的需求。以下是站群服务器的详细解释&#xff1a; 一、站群服务器的定义 站群…

Excel 小黑第22套

对应大猫22 新建一行&#xff0c;输入第一个人名字&#xff0c; 填充 -快速填充 修改员工编号&#xff08;1—001&#xff09;&#xff1a;选中所有员工编号&#xff0c;开始 -数据组 -自定义数字格式 000 在所有空表格单元格中输入数字0&#xff1a;选中修改的表格范围&#…

多传感器融合 SLAM LVI-SAM

目录 LVI-SAM 简介 A. 系统概述 B. 视觉惯导系统 C.雷达惯导系统 LVI-SAM 安装编译 编译 LVI-SAM 常见问题 LVI-SAM 工程化建议 LVI-SAM 简介 源码地址:https://github.com/TixiaoShan/LVI-SAM 如无法下载,换用 gitee 版本:https://gitee.com/inf_lee/LVI-SAM 改进…

Linux shell脚本3-if语句、case语句、for语句、while语句、until语句、break语句、continue语句,格式说明及程序验证

目录 1.if 控制语句 1.1 if 语句格式 1.2 程序验证 2.case语句 2.1case语句格式 2.2程序验证 2.2.1 终端先执行程序&#xff0c;在输入一个数 2.2.2 终端执行程序时同时输入一个预设变量 2.2.3 case带有按位或运算和通配符匹配 3.for语句 3.1for语句格式 3.2程序验…

图解模糊推理过程(超详细步骤)

我们前面已经讨论了三角形、梯形、高斯型、S型、Z型、Π型6种隶属函数&#xff0c;下一步进入模糊推理阶段。 有关六种隶属函数的特点在“Pi型隶属函数&#xff08;Π-shaped Membership Function&#xff09;的详细介绍及python示例”都有详细讲解&#xff1a;https://lzm07.b…

001-JMeter的安装与配置

1.前期准备 下载好JMeter : https://jmeter.apache.org/download_jmeter.cgi 下载好JDK : :Java Downloads | Oracle 中国 下载图中圈蓝的JMeter和JDK就行&#xff0c;让它边下载&#xff0c;我们边往下看 2.为什么要下载并安装JDK ? JMeter 是基于 Java 开发的工具&#…

英伟达有哪些支持AI绘画的 工程

英伟达在AI绘画领域布局广泛&#xff0c;其自研工具与第三方合作项目共同构建了完整的技术生态。以下是其核心支持AI绘画的工程及合作项目的详细介绍&#xff1a; 一、英伟达自研AI绘画工具 1. GauGAN系列 技术特点&#xff1a;基于生成对抗网络&#xff08;GAN&#xff09;&…

Netty源码—4.客户端接入流程二

大纲 1.关于Netty客户端连接接入问题整理 2.Reactor线程模型和服务端启动流程 3.Netty新连接接入的整体处理逻辑 4.新连接接入之检测新连接 5.新连接接入之创建NioSocketChannel 6.新连接接入之绑定NioEventLoop线程 7.新连接接入之注册Selector和注册读事件 8.注册Rea…

2025.3.17-2025.3.23学习周报

目录 摘要Abstract1 文献阅读1.1 动态图邻接矩阵1.2 总体框架1.2.1 GCAM1.2.2 输出块 1.3 实验分析 总结 摘要 在本周阅读的文献中&#xff0c;作者提出了一种名为TFM-GCAM的模型。TFM-GCAM模型的创新主要分为两部分&#xff0c;一部分是交通流量矩阵的设计&#xff0c;TFM-GC…

生活电子类常识——搭建openMauns工作流+搭建易犯错解析

前言 小白一句话生成一个网站&#xff1f;小白一句话生成一个游戏&#xff1f;小白一句话生成一个ppt?小白一句话生成一个视频&#xff1f; 可以 原理 总体的执行流程是 1&#xff0c;用户下达指令 2&#xff0c;大模型根据用户指令&#xff0c;分解指令任务为多个细分步骤…

深入解析 Uniswap:自动做市商模型的数学推导与智能合约架构

目录 1. 自动做市商&#xff08;AMM&#xff09;模型的数学推导1.1 恒定乘积公式推导1.2 价格影响与滑点 2. Uniswap 智能合约架构解析2.1 核心合约&#xff08;Core&#xff09;2.1.1 工厂合约&#xff08;Factory&#xff09;2.1.2 交易对合约&#xff08;Pair&#xff09; 2…

高频面试题(含笔试高频算法整理)基本总结回顾20

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

生成模型速通(Diffusion,VAE,GAN)

基本概念 参考视频https://www.bilibili.com/video/BV1re4y1m7gb/?spm_id_from333.337.search-card.all.click&vd_sourcef04f16dd6fd058b8328c67a3e064abd5 生成模型其实是主要是依赖概率分布&#xff0c;对输入特征的概率密度函数建模 隐空间&#xff08;latent space)…

Android在kts中简单使用AIDL

Android在kts中简单使用AIDL AIDL相信做Android都有所了解&#xff0c;跨进程通信会经常使用&#xff0c;这里就不展开讲解原理跨进程通信的方式了&#xff0c;最近项目换成kts的方式&#xff0c;于是把aidl也换成了统一的方式&#xff0c;其中遇到了很多问题&#xff0c;这里…