HarmonyOS4-ArkUI组件动画
一、ArkUI组件属性动画和显示动画
显示动画:
案例:上下左右箭头控制小鱼的游动 具体代码如下:
import router from '@ohos.router'@Entry @Component struct AnimationPage {// 小鱼坐标@State fishX: number = 200@State fishY: number = 180// 小鱼角度@State angle: number = 0// 小鱼图片@State src: Resource = $r('app.media.fish')// 是否开始游戏@State isBegin: boolean = falsebuild() {Row() {Stack() {// 返回按钮Button('返回').position({ x: 0, y: 0 }).backgroundColor('#20101010').onClick(() => {// 返回上一页router.back()})if (!this.isBegin) {// 开始游戏Button('开始游戏').onClick(() => {// 点击后显示小鱼this.isBegin = true})} else {// 小鱼图片Image(this.src).position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标.rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }).width(40).height(40)//.animation({duration: 500})// 操作按钮Row() {Button('⬅').backgroundColor('#20101010').onClick(() => {// this.fishX -= 20// this.src = $r('app.media.fish_rev')// 显示动画animateTo({duration: 500},() => {this.fishX -= 20this.src = $r('app.media.fish_rev')})})Column({ space: 40 }) {Button('⬆').backgroundColor('#20101010').onClick(() => {this.fishY -= 20})Button('⬇').backgroundColor('#20101010').onClick(() => {this.fishY += 20})}Button('➡').backgroundColor('#20101010').onClick(() => {this.fishX += 20this.src = $r('app.media.fish')})}.width(240).height(240)}}.width('100%').height('100%')}.height('100%')} }
二、ArkUI组件转场动画
代码如下:
import router from '@ohos.router'@Entry @Component struct AnimationPage {// 小鱼坐标@State fishX: number = 200@State fishY: number = 180// 小鱼角度@State angle: number = 0// 小鱼图片@State src: Resource = $r('app.media.fish')// 是否开始游戏@State isBegin: boolean = falsebuild() {Row() {Stack() {// 返回按钮Button('返回').position({ x: 0, y: 0 }).backgroundColor('#20101010').onClick(() => {// 返回上一页router.back()})if (!this.isBegin) {// 开始游戏Button('开始游戏').onClick(() => {// 点击后显示小鱼// this.isBegin = true// 转场动画需结合animateTo才能生效animateTo({duration: 1000},() => {// 点击后显示小鱼this.isBegin = true})})} else {// 小鱼图片Image(this.src).position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标.rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }).width(40).height(40)//.animation({duration: 500})// 添加转场动画.transition({// 开始游戏,入场动画type: TransitionType.Insert,opacity: 0, //一开始是透明的translate: { x: -250 }})}// 操作按钮Row() {Button('⬅').backgroundColor('#20101010').onClick(() => {// this.fishX -= 20// this.src = $r('app.media.fish_rev')// 显示动画animateTo({duration: 500},() => {this.fishX -= 20this.src = $r('app.media.fish_rev')})})Column({ space: 40 }) {Button('⬆').backgroundColor('#20101010').onClick(() => {this.fishY -= 20})Button('⬇').backgroundColor('#20101010').onClick(() => {this.fishY += 20})}Button('➡').backgroundColor('#20101010').onClick(() => {this.fishX += 20this.src = $r('app.media.fish')})}.width(240).height(240).justifyContent(FlexAlign.Center).position({x: 0, y: 120})}.width('100%').height('100%')}.height('100%')} }
三、ArkUI组件实现摇杆功能
此功能自行开发
此块涉及到的主要是算法 ,比如三角函数
角度正弦和余弦
import router from '@ohos.router' import { TouchEvent } from '@ohos.multimodalInput.touchEvent' import curves from '@ohos.curves'@Entry @Component struct AnimationPage {// 小鱼坐标@State fishX: number = 200@State fishY: number = 180// 小鱼角度@State angle: number = 0// 小鱼图片@State src: Resource = $r('app.media.fish')@State srcBg: Resource = $r('app.media.bg')// 是否开始游戏@State isBegin: boolean = false// 摇杆中心区域坐标private centerX: number = 120private centerY: number = 120// 大、小圆半径private maxRadius: number = 100private radius: number = 20// 摇杆小圆球初始位置@State positionX: number = this.centerX;@State positionY: number = this.centerY;// 角度正弦和余弦sin: number = 0cos: number = 0// 小鱼移动速度speed: number = 0// 任务idtaskId: number = -1build() {Row() {Stack() {// 返回按钮Button('返回').position({ x: 0, y: 0 }).backgroundColor('#20101010').onClick(() => {// 返回上一页router.back()})if (!this.isBegin) {// 开始游戏Button('开始游戏').onClick(() => {// 点击后显示小鱼// this.isBegin = true// 转场动画需结合animateTo才能生效animateTo({duration: 1000},() => {// 点击后显示小鱼this.isBegin = true})})} else {// 小鱼图片Image(this.src).position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标.rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }).width(40).height(40)//.animation({duration: 500})// 添加转场动画.transition({// 开始游戏,入场动画type: TransitionType.Insert,opacity: 0, //一开始是透明的translate: { x: -250 }})}// 操作按钮Row() {Circle( {width: this.maxRadius * 2, height: this.maxRadius * 2}).fill('#20101010').position({x: this.centerX - this.maxRadius, y: this.centerY - this.maxRadius})Circle( {width: this.radius * 2, height: this.radius * 2}).fill('#403A3A3A').position({x: this.positionX - this.radius, y: this.positionY - this.radius})}.width(240).height(240).justifyContent(FlexAlign.Center).position({x: 0, y: 120}).onTouch(this.handleTouchEvent.bind(this))}.width('100%').height('100%')}.height('100%').width('100%').backgroundImage(this.srcBg)}// 处理手指移动的函数handleTouchEvent(event: TouchEvent) {// 1、先获取手指位置坐标// .x .y 我获取不到? 为啥let x = event.touches[0].screenX// @ts-ignorelet y = event.touches[0].screenY// 2、计算手指与中心点的坐标差值let vx = x - this.centerXlet vy = y - this.centerY// 3、计算手指与中心点连线和x轴正半轴的夹角,单位是弧度let angle = Math.atan2(vy, vx);// 4、计算手指与中心点的距离(角度正弦和余弦)let distance = this.getDistance(vx, vy)// 5、计算摇杆小球的坐标(x轴和y轴)this.sin = Math.sin(angle)this.cos = Math.cos(angle)animateTo({curve: curves.responsiveSpringMotion()},() => {this.positionX = this.centerX + (distance * this.sin)this.positionY = this.centerY + (distance * this.cos)})}getDistance(x: number, y: number) {let d = Math.sqrt(x * x + y * y)return Math.min(d, this.maxRadius)} }
最终版:
import router from '@ohos.router' import curves from '@ohos.curves'@Entry @Component struct AnimationPage {// 小鱼坐标@State fishX: number = 200@State fishY: number = 180// 小鱼角度@State angle: number = 0// 小鱼图片@State src: Resource = $r('app.media.fish')@State srcBg: Resource = $r('app.media.bg')// 是否开始游戏@State isBegin: boolean = false// 摇杆中心区域坐标private centerX: number = 120private centerY: number = 120// 大、小圆半径private maxRadius: number = 100private radius: number = 20// 摇杆小圆球初始位置@State positionX: number = this.centerX;@State positionY: number = this.centerY;// 角度正弦和余弦sin: number = 0cos: number = 0// 小鱼移动速度speed: number = 0// 任务idtaskId: number = -1build() {Row() {Stack() {// 返回按钮Button('返回').position({ x: 0, y: 0 }).backgroundColor('#20101010').onClick(() => {// 返回上一页router.back()})if (!this.isBegin) {// 开始游戏Button('开始游戏').onClick(() => {// 点击后显示小鱼// this.isBegin = true// 转场动画需结合animateTo才能生效animateTo({duration: 1000},() => {// 点击后显示小鱼this.isBegin = true})})} else {// 小鱼图片Image(this.src).position({ x: this.fishX - 20, y: this.fishY - 20 }) // 中心点坐标.rotate({ angle: this.angle, centerX: '50%', centerY: '50%' }).width(40).height(40)//.animation({duration: 500})// 添加转场动画.transition({// 开始游戏,入场动画type: TransitionType.Insert,opacity: 0, //一开始是透明的translate: { x: -250 }})}// 操作按钮Row() {Circle( {width: this.maxRadius * 2, height: this.maxRadius * 2}).fill('#20101010').position({x: this.centerX - this.maxRadius, y: this.centerY - this.maxRadius})Circle( {width: this.radius * 2, height: this.radius * 2}).fill('#403A3A3A').position({x: this.positionX - this.radius, y: this.positionY - this.radius})}.width(240).height(240).justifyContent(FlexAlign.Center).position({x: 0, y: 120}).onTouch(this.handleTouchEvent.bind(this))}.width('100%').height('100%')}.height('100%').width('100%').backgroundImage(this.srcBg)}// 处理手指移动的函数handleTouchEvent(event: TouchEvent) {switch (event.type) {case TouchType.Up:// 还原小鱼的速度this.speed = 0// 取消定时任务clearInterval(this.taskId)// 还原摇杆小球的坐标 springMotion:还原动画animateTo({curve: curves.springMotion()},() => {this.positionX = this.centerXthis.positionY = this.centerYthis.angle = 0})breakcase TouchType.Down:// 开始定时任务this.taskId = setInterval(() => {this.fishX += this.speed * this.costhis.fishY += this.speed * this.sin}, 40);breakcase TouchType.Move:// 1、先获取手指位置坐标let x = event.touches[0].xlet y = event.touches[0].y// 2、计算手指与中心点的坐标差值let vx = x - this.centerXlet vy = y - this.centerY// 3、计算手指与中心点连线和x轴正半轴的夹角,单位是弧度let angle = Math.atan2(vy, vx);// 4、计算手指与中心点的距离(角度正弦和余弦)let distance = this.getDistance(vx, vy)this.sin = Math.sin(angle)this.cos = Math.cos(angle)// responsiveSpringMotion:跟手动画animateTo({curve: curves.responsiveSpringMotion()},() => {// 5、计算摇杆小球的坐标(x轴和y轴) 使用显示动画改变坐标this.positionX = this.centerX + (distance * this.sin)this.positionY = this.centerY + (distance * this.cos)// 6、修改小鱼的角度 [弧度转角度]if (Math.abs(angle * 2) < Math.PI) {// 判断弧度是否小于90度 正负90度 朝右游this.src = $r('app.media.fish')} else {this.src = $r('app.media.fish_rev')angle = angle < 0 ? angle + Math.PI : angle - Math.PI}this.angle = angle * 180 / Math.PIthis.speed = 5})break}}getDistance(x: number, y: number) {let d = Math.sqrt(x * x + y * y)return Math.min(d, this.maxRadius)} }
相关文章:

HarmonyOS4-ArkUI组件动画
一、ArkUI组件属性动画和显示动画 显示动画: 案例:上下左右箭头控制小鱼的游动 具体代码如下: import router from ohos.routerEntry Component struct AnimationPage {// 小鱼坐标State fishX: number 200State fishY: number 180// 小鱼…...

模块化——如何导入模块?(内置模块与自定义模块)
在Node.js中,要导入另一个模块,我们可以使用require函数。这个函数接受一个文件路径参数,并返回导入的模块。 注意:require导入包场景:内置模块、自定义模块、npm包的导入... 下面介绍内置模块与自定义模块。npm包的…...

element-ui的按需引入报错解决:MoudleBuildFailed,完整引入和按需引入
官网: Element - The worlds most popular Vue UI framework 1.完整引入 (1)下载: npm i element-ui -S (2)引入: 在 main.js 中写入以下内容: import Vue from vue; impor…...

面向低碳经济运行目标的多微网能量互联优化调度matlab程序
微❤关注“电气仔推送”获得资料(专享优惠) 运用平台 matlabgurobi 程序简介 该程序为多微网协同优化调度模型,系统在保障综合效益的基础上,调度时优先协调微网与微网之间的能量流动,将与大电网的互联交互作为备用…...

FORM的引入与使用
FORM的引入与使用 【0】引入 表单(Form)是网页中用于收集用户输入数据的一种交互元素。通过表单,用户可以输入文本、选择选项、上传文件等操作。表单通常由一个或多个输入字段(Input Field)组成,每个字…...

酷开会员丨古偶悬疑剧《花间令》在酷开系统热播中!
酷开系统一直致力于为用户提供卓越的大屏娱乐体验。随着三月新剧《花间令》的上线,酷开系统再次展现了其在内容更新上的迅速响应能力和对高质量视听体验的不懈追求。 《花间令》的故事背景设定在一个充满神秘色彩的古代王朝,鞠婧祎饰演的女主角与刘学义饰…...

html骨架以及常见标签
推荐一个网站mdn。 html语法 双标签:<标签 属性"属性值">内容</标签> 属性:给标签提供附加信息。大多数属性以键值对的形式存在。如果属性名和属性值一样,可以致谢属性值。 单标签:<标签 属性"属…...

Vue3学习01 Vue3核心语法
Vue3学习 1. Vue3新的特性 2. 创建Vue3工程2.1 基于 vue-cli 创建项目文件说明 2.2 基于 vite 创建具体操作项目文件说明 2.3 简单案例(vite) 3. Vue3核心语法3.1 OptionsAPI 与 CompositionAPIOptions API 弊端Composition API 优势 ⭐3.2 setup小案例setup返回值setup 与 Opt…...
Spring Boot实现跨域的5种方式
Spring Boot实现跨域的5种方式 为什么会出现跨域问题什么是跨域非同源限制java后端实现CORS跨域请求的方式返回新的CorsFilter(全局跨域)重写WebMvcConfigurer(全局跨域)使用注解(局部跨域)手动设置响应头(局部跨域)使用自定义filter实现跨域 为什么会出现跨域问题 出于浏览器…...

Elasticsearch:从 ES|QL 到 PHP 对象
作者:来自 Elastic Enrico Zimuel 从 elasticsearch-php v8.13.0 开始,你可以执行 ES|QL 查询并将结果映射到 stdClass 或自定义类的 PHP 对象。 ES|QL ES|QL 是 Elasticsearch 8.11.0 中引入的一种新的 Elasticsearch 查询语言。 目前,它在…...

Stm32 HAL库 访问内部flash空间
Stm32 HAL库 访问内部flash空间 代码的部分串口配置申明文件main函数 在一些时候,需要存储一些数据,但是又不想接外部的flash,那我们可以知道,其实还有内部的flash可以使用, 需要注意的是内部flash,读写次数…...

线程池详解
线程池 什么是线程池:线程池就是管理一系列线程的资源池。 当有任务要处理时,直接从线程池中获取线程来处理,处理完之后线程并不会立即被销毁,而是等待下一个任务。 为什么要用线程池 / 线程池的好处: **降低资源消…...

mybatis(5)参数处理+语句查询
参数处理+语句查询 1、简单单个参数2、Map参数3、实体类参数4、多参数5、Param注解6、语句查询6.1 返回一个实体类对象6.2 返回多个实体类对象 List<>6.3 返回一个Map对象6.4 返回多个Map对象 List<Map>6.5 返回一个大Map6.6 结果映射6.6.1 使用resultM…...

数据应用OneID:ID-Mapping Spark GraphX实现
前言 说明 以用户实体为例,ID 类型包含 user_id 和 device_id。当然还有其他类型id。不同id可以获取到的阶段、生命周期均不相同。 device_id 生命周期通常指的是一个设备从首次被识别到不再活跃的整个时间段。 user_id是用户登录之后系统分配的唯一标识ÿ…...

第6章 6.2.3 : readlines和writelines函数 (MATLAB入门课程)
讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。 MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 在MATLAB的文本数据处理任务中,导入和导出文件是常…...

Matlab应用层生成简述
基础软件层 目前接触到的几款控制器,其厂商并没有提供simulink的基础软件库一般为底层文件被封装为lib,留有供调用API接口虽然能根据API接口开发基础软件库,但耗费时间过长得不偿失 应用层 所以可以将应用层封装为一个子系统,其…...

每日一题(leetcode1702):修改后的最大二进制字符串--思维
找到第一个0之后,对于后面的子串(包括那个0),所有的0都能调上来,然后一一转化为10,因此从找到的第一个0的位置开始,接下来是(后半部分子串0的个数-1)个1,然后…...

PHP自助建站系统,小白也能自己搭建网站
无需懂代码,用 自助建站 做企业官网就像做PPT一样简单,您可以亲自操刀做想要的效果! 自助建站是一款简单、快捷、高效的工具,可以帮助您制作响应式网站。我们的自助建站系统,将传统的编码工作转化为直观的拖拽操作和文…...

计算机视觉 | 基于 ORB 特征检测器和描述符的全景图像拼接算法
Hi,大家好,我是半亩花海。本项目实现了基于 ORB 特征检测器和描述符的全景图像拼接算法,能够将两张部分重叠的图像拼接成一张无缝连接的全景图像。 文章目录 一、随机抽样一致算法二、功能实现三、代码解析四、效果展示五、完整代码 一、随机…...
Scala - 函数柯里化(Currying)
柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。 实例 首先我们定义一个函数: def add(x:Int,y:Int)xy 那么我们应用的时候,应该是这样用:add(1,2) 现在我们把这…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...