【HarmonyOS开发】拖拽动画的实现

动画的原理是在一个时间段内,多次改变UI外观,由于人眼会产生视觉暂留,所以最终看到的就是一个“连续”的动画。UI的一次改变称为一个动画帧,对应一次屏幕刷新,而决定动画流畅度的一个重要指标就是帧率FPS(Frame Per Second),即每秒的动画帧数,帧率越高则动画就会越流畅。
ArkUI中,产生动画的方式是改变属性值且指定动画参数。动画参数包含了如动画时长、变化规律(即曲线)等参数。当属性值发生变化后,按照动画参数,从原来的状态过渡到新的状态,即形成一个动画。

1、动画分类

输入图片说明

2、常见动画的使用

通过改变元素的宽高、位置、布局等触发动画
官方文档-动画

// 显式动画 https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-explicit-animation-0000001281480722
animateTo(value: AnimateParam, event: () => void): void
// 属性动画 https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-animatorproperty-0000001333321185 
animation(value: AnimateParam)
// 转场动画-必须和animateTo配合使用 https://developer.harmonyos.com/cn/docs/documentation/doc-references/ts-page-transition-animation-0000001281201178
transition(value: TransitionOptions)
transition({ type: TransitionType.All, scale: { x: 0, y: 0 } }) // 全部使用一种动画
transition({ type: TransitionType.Insert, translate: { x: 200, y: -200 }, opacity: 0 }) // 进入/插入动画
transition({ type: TransitionType.Delete, rotate: { x: 0, y: 0, z: 1, angle: 360 } }) // 移出/删除动画

3、矩阵动画的使用

这一块我们重点关注几个常用的属性

3.1 translate(拖拽动画实现的主要属性)

translate({x?: number, y?: number, z?: number}): Object

当x,y坐标为0时,则意味着,每个元素按照各自的位置进行排列(例如:grid、list、Stack等)。
因此,我们可以根据元素的下标index,通过一些算法来改变坐标的位置,从而实现拖拽动画,具体见代码

DOM的实现

// isStartDrag 为是否开始拖拽,当开始拖拽时,我们动态改变矩阵中元素的坐标
Grid() {
    ForEach(this.selected, (item: dataListType) => {
        GridItem() {
            Text(item.text).blockTextStyle(this.blockWidth)
        }
        .translate({
            x: this.isStartDrag ? this.geyCoodXY(index).x : 0,
            y: this.isStartDrag? this.geyCoodXY(index).y : 0
        })
        .animation({
            duration: DURATION, // 动画时长
            curve: Curve.Linear, // 动画曲线
            iterations: 1, // 播放次数
            playMode: PlayMode.Normal // 动画模式
        })
    })
}
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(16)
.rowsGap(16)
.editMode(true)  //设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem
.supportAnimation(true) // 开启动画

坐标改变的算法

  geyCoodXY(index) {
    const gridCol = this.getGridCol()
    let x = 0
    let y = 0
    if(this.insterIndex != -1) {
      if(index >= this.insterIndex) {
        // 判断是否需要换行
        // 需要取余如果等于0,则需要换行,需要进行下移和左移
        if(parseInt(((index) % gridCol).toString()) === gridCol - 1) {
          // 判断是否为当前列的最后一个
          if(this.options.type === 'object') {
            x = x - this.blockWidth * (gridCol - 1) - 16 * (gridCol - 2) - 19
            y = y + this.blockHeight - 16.5
          } else {
            x = x - this.blockWidth * (gridCol - 1) - 16 * (gridCol - 2) - 13
            y = y + this.blockHeight + 18
          }
        } else {
          // 默认右移
          x = x + 16 + this.blockWidth + 1
        }
      }

      if(!this.isStartDrag) {
        x = 0
        y = 0
      }
    }
    return {
      x: x,
      y: y
    }
  }

  /**
   * 获取Grid高度计算是否需要+1
   *     场景1:当前数组(data)长度小于列(colNum)的长度
   *     场景2:当前数组的长度等于拖拽前的长度 && 对数组长度%列长度区域不为0
   * */
  getGridNum(data) {
    let len = data.length
    let num = 0
    if(len < this.colNum) {
      num = 1
    }
    if(parseInt((len % this.colNum).toString()) !== 0 && this.editGridDataLength === len) {
      num = 1
    }
    return num
  }

  /**
   * 获取当前布局列数
   * 默认:文本COL_TEXT:4
   * 默认:图文COL_IMAGE_TEXT:3
   * */
  getGridCol() {
    return this.options.type === 'object' ? COL_IMAGE_TEXT : COL_TEXT
  }

3.2 scale

缩放函数,配合transform进行使用

scale({x?: number, y?: number, z?: number, centerX?: number, centerY?: number}): Object

3.3 rotate

旋转函数

rotate({x?: number, y?: number, z?: number, angle?: number, centerX?: Length, centerY?: Length}): Object

3.4 transformPoint

坐标映射,可以将当前的变换效果作用到一个坐标点上。

源码地址:MeshObjectEdit

输入图片说明

4、 注意点

4.1 Grid布局中的Item使用属性动画时,只能使用自带的curve,无法自定义

4.2 底层渲染问题

 在开发拖拽动画时,发现png的图片在拖拽结束后,会出现图片闪动的不流畅问题,改为svg图片解决。因此通过大量的对比验证,确认为鸿蒙底层窜然问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue左侧菜单栏显示问题

关于 使用若依系统&#xff0c;路由中左侧菜单栏一级菜单中只有一个二级菜单&#xff0c;一级菜单不显示的问题&#xff01;&#xff01;&#xff01; 在一级组件中添加 alwaysShow: true,

c4--函数和指针

函数和指针 指针 函数 函数指针 1、以下选项中&#xff0c;合法的一组C语言数值常量是(A )。 A、12. 0Xa23 4.5e0 // B、028 5e-3 -0xf //NO C、.177 4e1.5 0abc D、0x8A 10,000 3.e5 // 不能有逗号 解答&#xff1a; B、028 这个有问题 C: 这个…

普冉PY32系列(十三) SPI驱动WS2812全彩LED

目录 普冉PY32系列(一) PY32F0系列32位Cortex M0 MCU简介普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单普冉PY32系列(四) PY32F002A/003/030的时钟设置普冉PY32系列(五) 使用JLink RTT代替串口输出日志普冉PY32…

【数据结构(十·树结构的实际应用)】赫夫曼树(2)

文章目录 1. 基本介绍2. 赫夫曼树的创建2.1. 思路分析2.2. 代码实现 1. 基本介绍 给定 n 个权值作为 n 个叶子结点&#xff0c;构造一棵二叉树&#xff0c;若该树的 带权路径长度(wpl) 达到最小&#xff0c;称这样的二叉树为最优二叉树&#xff0c;也称为哈夫曼树(Huffman Tre…

FL Studio21最新FL水果编曲软件中文版在哪下载?

FL Studio21水果编曲软件是一款专业的音乐制作软件&#xff0c;被广泛地应用于电子音乐、hip-hop、流行乐等多种音乐类型的制作。该软件提供了丰富的音频编曲工具和音乐效果器&#xff0c;让用户可以轻松地创作出高品质的音乐作品。同时&#xff0c;这也是一款非常易于上手的软…

登录rabbitMQ管理界面时浏览器显示要求进行身份验证,与此站点连接不安全解决办法

问题描述 最近在黑马学习rabbitMQ的过程中&#xff0c;在使用docker部署好rabbitMQ后&#xff0c;使用账号为&#xff1a;itcast&#xff0c;密码为&#xff1a;123321 登录的时候浏览器显示了这个问题&#xff0c;如图所示&#xff1a; 当时以为自己需要输入自己的浏览…

【Apipost】批量删除我的51CTO文章

文章目录 一、序二、API分析三、Apipost测试四、脚本五、Apipost中完成 一、序 去年开始再51CTO同步更新文章&#xff0c;一年多过去了&#xff0c;只涨了3个粉丝。看了下这个平台就是卖课、搞培训的&#xff0c;退出了。决定把文章也删除了&#xff08;有人私信我说专门注册了…

RCNN 学习

RCNN算法流程 RCNN算法流程可分为4个步骤 一张图像生成1K~2K个候选区域&#xff08;使用Selective Search方法&#xff09;对每个候选区域&#xff0c;使用深度网络图特征特征送入每一类的SVM分类器&#xff0c;判别是否属于该类使用回归期器细修正候选框位置 1.候选区域的生…

【论文极速读】视频检索中的模态均衡方法

【论文极速读】视频检索中的模态均衡方法 FesianXu 20231206 at Baidu Search Team 前言 传统的视频搜索系统相关性部分主要以文本匹配为基础手段&#xff0c;在其中引入多模态向量容易收到『模态不均衡』的问题&#xff0c;论文[1]尝试对其进行解决&#xff0c;本文进行笔记。…

二维码智慧门牌管理系统升级解决方案:数字化房产管理

文章目录 前言一、全面信息记录&#xff1a;提升管理效率二、多种优势功能&#xff1a;系统化管理与无缝对接三、安全隐私保护&#xff1a;数据安全的重要性四、总结&#xff1a;提升管理效率与居住体验 前言 科技驱动房产管理 随着科技的飞速发展&#xff0c;房产管理领域也面…

udp多播组播

import socket ,struct,time# 组播地址和端口号 MCAST_GRP 239.0.0.1 MCAST_PORT 8888 # 创建UDP socket对象 sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # 绑定socket对象到本地端口号 # sock.bind((MCAST_GRP, MCAST_PORT)) …

D28|买卖股票的最佳时机+跳跃游戏

122.买卖股票的最佳时机 II 初始思路&#xff1a; 这道题解题的时候比较像在找规律&#xff0c;发现只要计算这个过程中的两数之差然后相加即可。 题解复盘&#xff1a; 可以更加清晰的发现如何从题意中获得贪心的思路。 如何贪心&#xff1a;局部最优&#xff1a;收集每天的…

Unity中Batching优化的GPU实例化(3)

文章目录 前言一、UNITY_SETUP_INSTANCE_ID(v);二、在UnityInstancing.cginc文件中&#xff0c;看一下Unity这句话做了什么1、使用了该 .cginc 后&#xff0c;会自动预定义该函数2、需要满足GPU实例化条件&#xff0c;才会执行对应语句3、满足GPU实例化后&#xff0c;主要执行的…

【Web】SCU新生赛个人wp及完赛感想

目录 一些碎碎念&#xff1a; Web Guideline 2048 ezupload hardupload ezphp ezweb ezsql webbuilder tarit tarit_revenge VipDinner simplespi 一些碎碎念&#xff1a; scu新生赛是我全心全力打的第二场比赛&#xff0c;历时七天&#xff0c;期间不免煎熬&…

[GPT]Andrej Karpathy微软Build大会GPT演讲(下)--该如何使用GPT助手

该如何使用GPT助手--将GPT助手模型应用于问题 现在我要换个方向,让我们看看如何最好地将 GPT 助手模型应用于您的问题。 现在我想在一个具体示例的场景里展示。让我们在这里使用一个具体示例。 假设你正在写一篇文章或一篇博客文章,你打算在最后写这句话。 加州的人口是阿拉…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-2稳定性分析Stability

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-2稳定性分析Stability 0. 序言1. 稳定的分类2. 稳定的对象3. 稳定的系统4. 系统稳定性的讨论5. 补充内容——Transfer Function(传递函数) - nonzero Initial Condition(非零初始…

C现代方法(第27章)笔记——C99对数学计算的新增支持

文章目录 第27章 C99对数学计算的新增支持27.1 <stdint.h>: 整数类型(C99)27.1.1 <stdint.h>类型27.1.2 对指定宽度整数类型的限制27.1.3 对其他整数类型的限制27.1.4 用于整型常量的宏 27.2 <inttype.h>: 整数类型的格式转换(C99)27.2.1 用于格式指定符的宏…

【设计模式--创建型--建造者模式】

建造者模式 建造者模式概述结构结果优缺点使用场景 将上述案例改为链式调用结果 建造者模式 概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构建&#xff08;由Builder来负责&#xff09;和装配&#xff08;由Direct…

接触刚性环境任务下的机器人力控(阻抗)性能测试

内涵 接触刚性环境任务下的机器人力控&#xff08;阻抗&#xff09;性能测试旨在评估机器人在与刚性物体交互时的性能表现。这种测试通过调整机器人的控制参数&#xff0c;如期望刚度和期望阻尼等&#xff0c;并分析记录的数据&#xff0c;旨在确保机器人能够在执行任务时保持…

类数组对象转为数组的方法

在开发的过程经常会遇到一些类数组对象&#xff0c;例如arguments&#xff0c;类数组对象具有length属性&#xff0c;也可以通过下标访问到对应值&#xff0c;但是不能使用数组的方法&#xff0c;如果将类数组对象转为数组&#xff0c;数组方法可以帮助我们更快实现逻辑&#x…