鸿蒙动画开发06——打断动画

devtools/2024/11/16 14:59:05/

1、前 言

UI界面除了运行动画之外,还承载着与用户进行实时交互的功能。当用户行为根据意图变化发生改变时,UI界面应做到即时响应。

例如用户在应用启动过程中,上滑退出,那么启动动画应该立即过渡到退出动画,而不应该等启动动画完成后再退出,从而减少用户等待时间。打断动画演示如下:

另外,对于桌面翻页类从跟手到离手触发动画的场景,离手后动画的初始速度应承继手势速度,避免由于速度不接续导致停顿感的产生。

针对以上场景,系统已提供动画与动画、手势与动画之间的衔接能力(打断动画),保证各类场景下动画平稳光滑地过渡的同时,尽可能降低开发难度。

下面针对打断动画的主要场景做探讨。

2、基于属性变更的打断动画

基于属性变更的动画归属于“布局更新动画”,我们在之前的文章中有讨论布局更新动画的基本使用,详见👉🏻 鸿蒙动画开发01——布局更新动画。

假设对于某一可动画属性(width、height、position、scale等),存在正在运行的动画。当UI侧行为改变该属性终点值时,我们仅需在animateTo动画闭包中改变属性值或者改变animation接口作用的属性值,即可产生打断动画(立即终止正在运行动画的目标,同时基于当前状态立即动画转向新的值)。系统会自动衔接之前的动画和当前的动画,我们仅需要关注当前单次动画的实现。

一个打断动画效果如下(同时演示了不打断和打断的两个场景):

代码如下(核心代码在26、28和34行):

import { curves } from '@kit.ArkUI';class SetSlt{  isAnimation:boolean = true  set():void{    this.isAnimation = !this.isAnimation;  }}@Entry@Componentstruct AnimationToAnimationDemo {// 第一步:声明相关状态变量  @State SetAnimation: SetSlt = new SetSlt();  build() {    Column() {      Text('Harmony自习室')        .fontWeight(FontWeight.Bold)        .fontSize(12)        .fontColor(Color.White)        .textAlign(TextAlign.Center)        .borderRadius(10)        .backgroundColor(0xf56c6c)        .width(100)        .height(100)        // 第二步:将状态变量设置到相关可动画属性接口        .scale({ x: this.SetAnimation.isAnimation ? 2 : 1, y: this.SetAnimation.isAnimation ? 2 : 1 })        // 第四步:通过隐式动画接口开启隐式动画,动画终点值改变时,系统自动添加衔接动画        .animation({ curve: curves.springMotion(0.4, 0.8) })      Button('Click')        .margin({ top: 200 })        // 第三步:通过点击事件改变状态变量值,影响可动画属性值        .onClick(() => {          this.SetAnimation.set()        })    }    .width('100%')    .height('100%')    .justifyContent(FlexAlign.Center)  }}

3、手势跟随打断动画

使用滑动、捏合、旋转等手势的场景中,跟手过程中一般会触发属性的改变。离手后,这部分属性往往会继续发生变化,直到到达属性终点值。

离手阶段的属性变化初始速度应与离手前一刻的属性改变速度保持一致。如果离手后属性变化速度从0开始,就好像正在运行的汽车紧急刹车,造成观感上的骤变是用户和开发者都不希望看到的。

针对在TapGesture和动画之间进行衔接的场景(如列表滑动),可以在跟手阶段每一次更改组件属性时,都做成使用跟手弹簧曲线的属性动画。离手时再用离手弹簧曲线产生离手阶段的属性动画。

对于采用springMotion曲线的动画,离手阶段动画将自动继承跟手阶段动画的速度,并以跟手动画当前位置为起点,运动到指定的属性终点。在跟手过程中使用responsiveSpringMotion动画,在释放后状态打断后的运动使用springMotion动画。之前的文章中我们有讨论responsiveSpringMotion和springMotion动画,详见👉🏻 鸿蒙UI开发——使用动画曲线

我们实现一个小球,这个小球可以跟随我们的指尖,在我们指尖离开屏幕后,小球按照运动惯性自动回到起点(整个过程动画衔接非常顺畅)。

示例效果如下:

代码如下(关注22~37行代码):​​​​​​​

import { curves } from '@kit.ArkUI';@Entry@Componentstruct SpringMotionDemo {  // 第一步:声明相关状态变量  @State positionX: number = 100;  @State positionY: number = 100;  diameter: number = 50;  build() {    Column() {      Row() {        Circle({ width: this.diameter, height: this.diameter })          .fill(Color.Blue)          // 第二步:将状态变量设置到相关可动画属性接口          .position({ x: this.positionX, y: this.positionY })          // 第三步:在跟手过程改变状态变量值,并且采用responsiveSpringMotion动画运动到新的值          .onTouch((event?: TouchEvent) => {            if(event){              if (event.type === TouchType.Move) {                // 跟手过程,使用responsiveSpringMotion曲线                this.getUIContext()?.animateTo({ curve: curves.responsiveSpringMotion() }, () => {                  // 减去半径,以使球的中心运动到手指位置                  this.positionX = event.touches[0].windowX - this.diameter / 2;                  this.positionY = event.touches[0].windowY - this.diameter / 2;                  console.info(`move, animateTo x:${this.positionX}, y:${this.positionY}`);                })              } else if (event.type === TouchType.Up) {                // 第四步:在离手过程设定状态变量终点值,并且用springMotion动画运动到新的值,springMotion动画将继承跟手阶段的动画速度                this.getUIContext()?.animateTo({ curve: curves.springMotion() }, () => {                  this.positionX = 100;                  this.positionY = 100;                  console.info(`touchUp, animateTo x:100, y:100`);                })              }            }          })      }      .width("100%").height("80%")      .clip(true) // 如果球超出父组件范围,使球不可见      .backgroundColor(Color.Orange)      Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Center }) {        Text("拖动小球").fontSize(16)      }      .width("100%")      Row() {        Text('点击位置: [x: ' + Math.round(this.positionX) + ', y:' + Math.round(this.positionY) + ']').fontSize(16)      }      .padding(10)      .width("100%")    }.height('100%').width('100%')  }}

http://www.ppmy.cn/devtools/134460.html

相关文章

视频流媒体播放器EasyPlayer.js RTSP播放器视频颜色变灰色/渲染发绿的原因分析

EasyPlayer.js RTSP播放器属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,无须安装任何插件,起播快、延迟低、兼容性强,使用非常便捷。 EasyPlayer.js播放器不仅支持H.264与H.265视频编码格式&#xff0…

芯原科技嵌入式面试题及参考答案

Linux 相关驱动怎么写? 在 Linux 中编写驱动主要有以下步骤。 首先,需要了解设备的硬件特性。这包括设备的工作原理、寄存器地址和功能、中断号等信息。例如,对于一个简单的 GPIO 设备,要知道其数据寄存器、方向寄存器的位置以及读写操作的规则。 然后是模块的初始化部分。…

【全面系统性介绍】虚拟机VM中CentOS 7 安装和网络配置指南

一、CentOS 7下载源 华为源:https://mirrors.huaweicloud.com/centos/7/isos/x86_64/ 阿里云源:centos-vault-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云 百度网盘源:https://pan.baidu.com/s/1MjFPWS2P2pIRMLA2ioDlVg?pwdfudi &…

Kotlin约束泛型参数必须继承自某个父类

Kotlin约束泛型参数必须继承自某个父类 open class SuperData { }class DataA : SuperData {constructor() {println("DataA constructor")} }class DataB : SuperData {constructor() {println("DataB constructor")} }fun <T : SuperData> myfun(p…

利用服务工作线程serviceWorker缓存静态文件css,html,js,图片等的方法,以及更新和删除及版本控制

Service Worker 是一种运行在浏览器背后的独立线程&#xff0c;可以用来处理推送通知、后台同步、缓存等任务。以下是使用 Service Worker 来缓存图片的一个基本示例&#xff1a; 1、注册 Service Worker: 首先&#xff0c;你需要在你的 JavaScript 文件中注册 Service Worker。…

Mac 使用mac 原生工具将mp4视频文件提取其中的 mp3 音频文件

简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过国家奖学金,有幸在竞赛中拿过一些国奖、省奖…已保研 学习经验:扎实基础 + 多做笔…

基于微信小程序的农场管理系统的设计与实现,LW+源码+讲解

1.2 课题意义 现如今&#xff0c;信息种类变得越来越多&#xff0c;信息的容量也变得越来越大&#xff0c;这就是信息时代的标志。近些年&#xff0c;计算机科学发展得也越来越快&#xff0c;而且软件开发技术也越来越成熟&#xff0c;因此&#xff0c;在生活中的各个领域&…

深入解析 OpenHarmony 构建系统-3-GN 构建系统管理脚本

引言 OpenHarmony作为一款面向全场景的分布式操作系统,其构建系统在开发过程中扮演着至关重要的角色。本文将详细介绍OpenHarmony构建系统下的一个gn封装脚本,该脚本用于管理和执行 gn 命令,更高效地管理构建过程。 位置:/build/hb/services/gn.py 脚本概述 该脚本定义了…