「Mac畅玩鸿蒙与硬件19」鸿蒙UI组件篇9 - 自定义动画实现

自定义动画让开发者可以设计更加个性化和复杂的动画效果,适合表现独特的界面元素。鸿蒙提供了丰富的工具,支持通过自定义路径和时间控制来创建复杂的动画运动。本篇将带你学习如何通过自定义动画实现更多样化的效果。

在这里插入图片描述


关键词
  • 自定义动画
  • 动画路径
  • 贝塞尔曲线
  • 动画控制

一、Animation 组件的自定义路径

自定义路径动画使组件能够按照特定轨迹移动。贝塞尔曲线是创建复杂动画路径的常用方法。

1.1 贝塞尔曲线

贝塞尔曲线动画适合需要平滑、自然的路径效果,可以通过调整控制点来改变曲线路径。以下代码演示了组件沿自定义贝塞尔曲线运动。

@Entry
@Component
export struct BezierPathAnimation {@State private x: number = 0; // x 轴初始位置@State private y: number = 0; // y 轴初始位置build() {Column() {Image($r('app.media.cat')).width(305).height(360).translate({ x: this.x, y: this.y }) // 应用自定义路径的移动.transition({ opacity: 0.8 }) // 设置透明度过渡效果.margin(50)Button('启动贝塞尔曲线动画') // 按钮触发贝塞尔路径动画.onClick(() => this.startBezierAnimation())}.width('100%').height('100%').alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center);}// 实现贝塞尔曲线动画startBezierAnimation() {let t = 0;const interval = setInterval(() => {t += 0.02; // 递增参数t,用于控制贝塞尔曲线进度// 贝塞尔曲线公式this.x = (1 - t) * (1 - t) * 0 + 2 * (1 - t) * t * 150 + t * t * 300;this.y = (1 - t) * (1 - t) * 0 + 2 * (1 - t) * t * 200 + t * t * 0;if (t >= 1) clearInterval(interval); // 动画结束时停止}, 50); // 每50ms更新一次位置}
}

效果示例:点击“启动贝塞尔曲线动画”按钮后,图片会按照贝塞尔曲线轨迹移动,形成柔和的弧形路径。

在这里插入图片描述


二、基于时间的动画控制

时间控制可用来设置动画播放的速度或暂停点。通过 setTimeoutclearInterval 等控制函数,可以实现精确的动画定时。

2.1 自动启动和暂停动画

以下示例展示了如何通过按钮启动或暂停自动位移动画。

@Entry
@Component
export struct TimedControlAnimation {@State private x: number = 0; // x 轴位置@State private isAnimating: boolean = false; // 控制动画状态private intervalId: number | null = null; // 存储动画的定时器 IDbuild() {Column() {Image($r('app.media.cat')).width(305).height(360).translate({ x: this.x }) // 应用自动位移动画.transition({ opacity: 0.7 }) // 设置透明度过渡效果.margin(50)Button(this.isAnimating ? '暂停' : '启动') // 切换启动和暂停按钮.onClick(() => this.toggleAnimation())}.width('100%').height('100%').alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center);}// 启动或暂停动画toggleAnimation() {if (this.isAnimating) {clearInterval(this.intervalId); // 暂停动画this.intervalId = null;} else {this.intervalId = setInterval(() => {this.x = this.x === 0 ? 200 : 0; // 在 0 和 200 之间切换位置}, 1000); // 每1秒切换位置,实现自动平移}this.isAnimating = !this.isAnimating; // 更新动画状态}
}

效果示例:点击“启动”按钮后,图片将左右自动移动;点击“暂停”按钮,动画将停止。

在这里插入图片描述


三、复杂组合动画

将多个动画效果组合可以实现丰富的视觉效果。以下代码展示旋转、缩放与路径运动的组合动画。

3.1 旋转、缩放与路径运动
@Entry
@Component
export struct ComplexCombinationAnimation {@State private x: number = 0; // x 轴位置@State private y: number = 0; // y 轴位置@State private rotation: number = 0; // 旋转角度@State private scale1: number = 1; // 缩放比例build() {Column() {Image($r('app.media.cat')).width(305).height(360).translate({ x: this.x, y: this.y }) // 应用位移动画.rotate({ angle: this.rotation }) // 应用旋转动画.scale({ x: this.scale1, y: this.scale1 }) // 应用缩放动画.transition({ opacity: 0.7 }) // 设置透明度过渡效果.margin(50)Button('启动组合动画') // 按钮触发组合动画.onClick(() => this.startComplexAnimation())}.width('100%').height('100%').alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center);}// 实现旋转、缩放和路径运动的组合动画startComplexAnimation() {let t = 0;const interval = setInterval(() => {t += 0.02;// 贝塞尔曲线路径this.x = (1 - t) * (1 - t) * 0 + 2 * (1 - t) * t * 150 + t * t * 300;this.y = (1 - t) * (1 - t) * 0 + 2 * (1 - t) * t * 200 + t * t * 0;// 旋转和缩放this.rotation += 5; // 累加旋转角度this.scale1 = this.scale1 === 1 ? 1.3 : 1; // 在 1 和 1.3 之间缩放// 动画结束条件if (t >= 1) clearInterval(interval);}, 100); // 每100ms更新一次}
}

效果示例:点击“启动组合动画”按钮后,图片会沿贝塞尔曲线移动,并自动旋转和缩放。

在这里插入图片描述


四、自定义缓动函数

缓动函数让动画更具表现力。下面是自定义的弹性缓动函数示例,使图片在缩放时带有弹跳效果。

4.1 弹性缩放动画
@Entry
@Component
export struct CustomEaseAnimation {@State private scale1: number = 1; // 缩放比例build() {Column() {Image($r('app.media.cat')).width(305).height(360).scale({ x: this.scale1, y: this.scale1 }) // 应用弹性缩放.transition({ opacity: 0.7 }) // 设置透明度过渡效果.margin(50)Button('启动弹性缩放') // 按钮触发弹性缩放动画.onClick(() => this.startElasticScaleAnimation())}.width('100%').height('100%').alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Center);}// 实现弹性缩放动画的函数startElasticScaleAnimation() {let t = 0;const interval = setInterval(() => {t += 0.05;this.scale1 = 1 + Math.sin(t * Math.PI * 4) * Math.exp(-t * 4); // 弹性缓动公式// 当 t 超过某值时停止动画if (t >= 1) {clearInterval(interval);this.scale1 = 1; // 恢复缩放比例}}, 50); // 每 50ms 更新一次缩放比例}
}

效果示例:点击“启动弹性缩放”按钮后,图片将缩放并带有弹性效果。
在这里插入图片描述


小结

本篇介绍了鸿蒙中如何实现自定义动画,包括贝塞尔曲线路径、时间控制、多重组合和自定义缓动函数。通过这些技巧,开发者可以设计出更具个性化和表现力的动画效果,提升应用的用户体验。


下一篇预告

在下一篇中,将介绍如何使用 Canvas 组件实现自定义绘图,为鸿蒙应用增添图形效果。


上一篇:「Mac畅玩鸿蒙与硬件18」鸿蒙UI组件篇8 - 高级动画效果与缓动控制
下一篇:「Mac畅玩鸿蒙与硬件20」鸿蒙UI组件篇10 - Canvas 组件自定义绘图

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

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

相关文章

GPIO子系统中Controller驱动源码分析

往期内容 本专栏往期内容: Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析:imx_pinctrl_soc_info结构体Pinctrl子系统中c…

【Linux系统编程】第四十二弹---多线程编程全攻略:涵盖线程创建、异常处理、用途、进程对比及线程控制

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、线程创建 2、线程异常 3、线程用途 4、进程 VS 线程 5、线程控制 5.1、创建和等待线程 1、线程创建 线程能看到进程的大…

Qt入门基础分享

文章目录 学习 Qt 语言之前的基本知识1. 编程基础语法:面向对象编程(OOP):基本数据结构:了解数组、链表、栈、队列、树(如二叉树、平衡树)、图(如邻接矩阵、邻接表)等。算法:熟悉常见的排序算法(如快速排序、归并排序、冒泡排序)和查找算法(如线性查找、二分查找)…

超萌!HTMLCSS:超萌卡通熊猫头

效果演示 创建了一个卡通风格的熊猫头 HTML <div class"box"><div class"head"><div class"head-copy"></div><div class"ears-left"></div><div class"ears-right"></di…

使用 AMD GPU 的 ChatGLM-6B 双语语言模型

Using the ChatGLM-6B bilingual language model with AMD GPUs — ROCm Blogs 2024 年 4 月 4 日&#xff0c;作者&#xff1a; Phillip Dang. ChatGLM-6B 是一个开源的中英双语语言模型&#xff0c;拥有 62 亿参数。它基于通用语言模型 (GLM) 架构&#xff0c;针对中文对话进…

计算并联电阻的阻值

计算并联电阻的阻值 C语言代码C代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 对于阻值为r1和r2的电阻&#xff0c;其并联电阻阻值公式计算如下&#xff1a; R1/(1/r11/r2) 输入 两个电阻阻抗大小&#xff0c;浮…

创建线程时传递参数给线程

在C中&#xff0c;可以使用 std::thread 来创建和管理线程&#xff0c;同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…

AAA 数据库事务隔离级别及死锁

目录 一、事务的四大特性&#xff08;ACID&#xff09; 1. 原子性(atomicity)&#xff1a; 2. 一致性(consistency)&#xff1a; 3. 隔离性(isolation)&#xff1a; 4. 持久性(durability)&#xff1a; 二、死锁的产生及解决方法 三、事务的四种隔离级别 0 .封锁协议 …

数字后端零基础入门系列 | Innovus零基础LAB学习Day9

Module 16 Wire Editing 这个章节的学习目标是学习如何在innovus中手工画线&#xff0c;切断一根线&#xff0c;换孔&#xff0c;更改一条net shape的layer和width等等。这个技能是每个数字IC后端工程师必须具备的。因为项目后期都需要这些技能来修复DRC和做一些手工custom走线…

前后端交互通用排序策略

目录 排序场景 排序实现思路 1. 静态代码排序实现 2.数据库驱动排序实现 3. 基于Java反射的动态排序实现 通用排序工具 SortListUtil 结语 排序场景 在面向前端数据展示的应用场景中&#xff0c;我们旨在实现一个更加灵活的排序机制&#xff0c;该机制能够支持对从后端传递…

前端入门一之CSS知识详解

前言 CSS是前端三件套之一&#xff0c;在MarkDown中也完美兼容这些语法&#xff1b;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 Emmet语法&#xff1a;CSS基本语法&#xff1a;css语法结构只有3种&#xff1a…

leetcode | 88. 合并两个有序数组

题目描述 88. 合并两个有序数组 分析 题目不允许更改nums1的长度&#xff0c;要求原地更改。 题目其实不难&#xff0c;如果记住可以从后往前合并的解法&#xff0c;但是正向遍历的问题是什么呢&#xff1f; ——元素覆盖。那为什么负向遍历就不会有这个问题呢&#xff1f;…

跳蚤市场之商品发布功能

一 商品类别和小类的联动 以下是一个示例代码&#xff0c;展示了如何实现商品类别中大类和小类的联动。 商品大类选择框、小类选择框 的设计 html部分 <form id"category-form"><label for"major-category">大类&#xff1a;</label&g…

OpenAI 发布了新的事实性基准——SimpleQA

SimpleQA 简介 名为 SimpleQA 的事实性基准&#xff0c;用于衡量语言模型回答简短的事实性问题的能力。 人工智能领域的一个悬而未决的问题是如何训练模型&#xff0c;使其产生符合事实的回答。 目前的语言模型有时会产生错误的输出或没有证据证明的答案&#xff0c;这个问题…

Android camera2

一、序言 为了对阶段性的知识积累、方便以后调查问题&#xff0c;特做此文档&#xff01; 将以camera app 使用camera2 api进行分析。 (1)、打开相机 openCamera (2)、创建会话 createCaptureSession (3)、开始预览 setRepeatingRequest (4)、停止预览 stopRepeating (5)、关闭…

Javascript属性遮蔽问题

先了解一下Object.defineProperty()方法 Object.defineProperty() 静态方法会直接在一个对象上定义一个新属性&#xff0c;或修改其现有属性&#xff0c;并返回此对象。 //obj&#xff1a;要定义的对象 //prop&#xff1a;一个字符串或 Symbol&#xff0c;指定了要定义或修改…

vue3项目history模式部署404处理,使用 historyApiFallback 中间件支持单页面应用路由

vue3项目history模式部署404处理&#xff0c;使用 historyApiFallback 中间件支持单页面应用路由 在现代的 web 开发中&#xff0c;单页面应用&#xff08;SPA&#xff09;变得越来越流行。这类应用通常依赖于客户端路由来提供流畅的用户体验&#xff0c;但在服务器端&#xf…

【vim文本编辑器gcc编译器gdb调试器】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、vimvim安装vim常用快捷键vim使用vimtutor zh文档 二、gcc编译器安装gcc工具编译源代码 三、gdb调试器gdb安装gdb常用指令gdb简单上手使用gdb的单步调试功能 总结…

企业数字化转型的架构治理策略:核心问题、深度分析与优化路径

在当今的商业环境中&#xff0c;企业数字化转型已成为实现可持续发展、增强竞争力的战略选择。企业架构治理&#xff08;Enterprise Architecture Governance Capability, EAGC&#xff09;在数字化转型中扮演着保障架构一致性、提升变革效能的关键角色。本指南深入解析了如何通…