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) 现在我们把这…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...