Compose 动画艺术探索之 Easing

news2024/11/15 21:22:12

本篇文章是此专栏的第六篇文章,前几篇文章大概将 Compose 中的动画都简单过了一遍,如果想阅读前几篇文章的话可以点击下方链接:

  • Compose 动画艺术探索之瞅下 Compose 的动画
  • Compose 动画艺术探索之可见性动画
  • Compose 动画艺术探索之属性动画
  • Compose 动画艺术探索之动画规格
  • Compose 动画艺术探索之灵动岛
  • Compose 动画艺术探索之 AnimationVector

什么是 Easing?

基于时长的 AnimationSpec 操作(如 tweenkeyframes)使用 Easing 来调整动画的小数值。这样可让动画值加速和减速,而不是以恒定的速率移动。小数是介于 0(起始值)和 1.0(结束值)之间的值,表示动画中的当前点。

Easing 实际上是一个函数,它取一个介于 0 和 1.0 之间的小数值并返回一个浮点数。返回的值可能位于边界之外,表示过冲或下冲。

上面这两段关于什么是 Easing 是官方文档中的描述,是不是看的云里雾里!哈哈哈,第一次看的时候都是,但在介绍 Easing 的最后加了一个注意,一起来看下:

注意:Easing 对象的运行方式与平台中 Interpolator 类的实例相同。不过,它采用的不是 getInterpolation() 方法,而是 transform() 方法。

奥,原来 Easing 就相当于咱们之前使用的插值器(Interpolator)啊!这么说就好理解一些了。

如何使用 Easing?

其实在之前文章 Compose 动画艺术探索之动画规格 中已经简单介绍过 Easing ,在里面大概介绍了常用的几种 Easing

  • FastOutSlowInEasing
  • LinearOutSlowInEasing
  • FastOutLinearEasing
  • LinearEasing
  • CubicBezierEasing

其中 CubicBezierEasing 是剩下四种的父类,这几种 Easing 的具体用法在 Compose 动画艺术探索之动画规格 中已经介绍过,这里将就不再赘述,如果想看这几种 Easing 的动画效果可以先移步去看下。

下面来看下 Easing 的使用方法:

val value1 by animateFloatAsState(
    targetValue = 1f,
    animationSpec = tween(
        durationMillis = 300,
        delayMillis = 50,
        easing = LinearOutSlowInEasing // 使用 Easing
    )
)

使用方法其实很简单,关键是要选对 Easing 才能实现动画交互想要实现的效果。

还有哪些 Easing?

其实 Compose 中为我们提供的 Easing 远远不止上面说的这几种,还有很多,先来张图感受下有多少吧!

image-20221124110458280.png

小小提示,并没有截完。。。下面还有,这里就不放那么多截图了。每一种 Easing 都对应着一种动画效果,大家可以去 看每一种 Easing 对应的动画效果样例。下面是官方文档地址:

https://developer.android.google.cn/reference/kotlin/androidx/compose/animation/core/package-summary#Ease()

如何自定义 Easing?

刚才的截图种可以看到,里面的 Easing 和最初说的那几种都继承的是 CubicBezierEasing ,那咱们就来看下 CubicBezierEasing

@Immutable
class CubicBezierEasing(
    private val a: Float,
    private val b: Float,
    private val c: Float,
    private val d: Float
) : Easing {
    ......
    private fun evaluateCubic(a: Float, b: Float, m: Float): Float {
        return 3 * a * (1 - m) * (1 - m) * m +
            3 * b * (1 - m) *  m * m +
            m * m * m
    }
​
    override fun transform(fraction: Float): Float {
        if (fraction > 0f && fraction < 1f) {
            var start = 0.0f
            var end = 1.0f
            while (true) {
                val midpoint = (start + end) / 2
                val estimate = evaluateCubic(a, c, midpoint)
                if ((fraction - estimate).absoluteValue < CubicErrorBound)
                    return evaluateCubic(b, d, midpoint)
                if (estimate < fraction)
                    start = midpoint
                else
                    end = midpoint
            }
        } else {
            return fraction
        }
    }
    ......
}

嗯,CubicBezierEasing 实现了 Easing 接口,然后 Easing 中有一个方法 transformCubicBezierEasing 类实现了三阶贝塞尔曲线,这相当于原生的 PathInterpolator 。可以看到 CubicBezierEasing 构造方法中接受四个参数,类型都是 Float。

  • a:第一个控制点的x坐标。经过点(0,0)和第一个控制点的直线与点(0,0)处的缓动相切
  • b:第一个控制点的y坐标。经过点(0,0)和第一个控制点的直线与点(0,0)处的缓动相切
  • c:第二个控制点的x坐标。经过点(1,1)和第二个控制点的直线与点(1,1)处的缓动相切
  • d:第二个控制点的y坐标。经过点(1,1)和第二个控制点的直线与点(1,1)处的缓动相切。

CubicBezierEasing 是比较复杂的 Easing ,但也是一个通用的,所以有很多 Easing 都继承自它,咱们自定义的时候也可以继承 CubicBezierEasing ,通过传入不同的控制点坐标来实现想要的动画效果。

当然,也可以直接实现 Easing 接口来实现动画效果,比如 LinearEasing

val LinearEasing: Easing = Easing { fraction -> fraction }

由于默认就是线性的,所以直接返回未修改的分数就是线性的动画效果。

接下来咱们来自定义一个 Easing

val CustomLinearEasing: Easing = Easing { fraction -> fraction / 2 }

代码很简单,直接实现 Easing 接口,然后将分数除以二并返回,再来写个 Demo !

var small by remember { mutableStateOf(true) }
val size by animateDpAsState(
    targetValue = if (small) 50.dp else 100.dp,
    animationSpec = tween(
        durationMillis = 3000,
        delayMillis = 50,
        easing = CustomLinearEasing  // 使用上面自定义的 Easing
    )
)
​
Column {
    Button(onClick = { small = !small }) {
        Text("修改大小")
    }
    Box(
        modifier = Modifier.size(size)
    )
}

代码很简单,在之前的几篇文章中都使用过,这块也就不再赘述,唯一不同的就是这块使用了上面咱们自定义的 Easing ,接下来运行看下效果!

easing.gif

动画执行时间一共是三秒钟,但是三秒钟全部执行在了缩小的前半段,后半段在最后一瞬间完成。这是因为咱们将 Easing 的分数返回值修改为了之前的一半而导致的。

刚才的分数只是除以了二,这回咱们直接改为负数看看!

val CustomLinearEasing: Easing = Easing { fraction -> -fraction / 2 }

别的都没动,只是加了个负号,来运行看下效果!

easing2.gif

可以看到动画效果正好和刚才是相反的方向!

接下来再玩一下,刚才是除以二,这回咱们来乘二看下效果!

val CustomLinearEasing: Easing = Easing { fraction -> fraction * 2 }

运行看下效果!

easing3.gif

可以看到,动画效果执行到目标值还在方法或缩小,最后返回到既定值。

总结

如果想玩好 Compose 中的动画,Easing 是必不可少的一环,其实官方给实现的 Easing 基本都能满足咱们的日程开发需求,如果实现需要自定义那就只能自定义搞一搞了,不过在自定义前可以思考下是直接实现 Easing 接口还是继承 CubicBezierEasing

本文至此结束,有用的地方大家可以参考,当然如果能帮助到大家,哪怕是一点也足够了。就这样。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mobtech 秒验应用介绍

一、传统APP手机注册登录验证的弊端 1、 注册过程输入的信息过多&#xff0c;耗费时间长。用户体验感较差。 2、 传统手机绑定需要通过验证码验证手机真实性&#xff0c;容易被批量注册。 3、 如果手机APP多&#xff0c;每个APP都注册&#xff0c;使用的用户名密码多&#x…

高薪资的IT行业,我们该不该转行

今年互联网各大厂秋招基本结束&#xff0c;校招薪资已经出炉了。可以从上图中看到&#xff0c;今年薪资仍然存在倒挂&#xff08;新员工工资高过老员工&#xff09;现象。各大厂人均 30w 的薪资在其它专业是难以想象的。大家无需置疑上述薪资的可靠性。作为今年的校招生&#x…

视频剪辑教程,批量将视频裁切为1:1比例的尺寸

视频太多&#xff0c;如何批量剪辑&#xff0c;比如将视频裁切为1:1的比例呢&#xff1f;那么今天小编给大家带来一个超简单的方法&#xff0c;可以同时将多段16:9的视频裁切为1:1的视频。 所需工具 多段16:9&#xff08;即1280*720&#xff09;的视频素材 操作步骤 第一步&…

C++那些事之高效率开发

1.神器 目前开发C/C用的比较多的当属Vim、VS code、CLion。 Vim配上插件编写C/C效率高的不少。 VSCode配上自定义配置及快捷键、vim插件效率跟vim旗鼓相当。 CLion因其独特的CMakeLists.txt管理方式及强大的代码补全等功能&#xff0c;编写本地代码绝对好于前两者。 但是对…

获B轮融资 官栈如何打破薛定谔式“中式滋补”

日前&#xff0c;滋补头部品牌官栈宣布完成B轮融资&#xff0c;这是其继去年9月完成Pre-B轮融资后&#xff0c;再度获得资本青睐。 近年来&#xff0c;乘国潮东风&#xff0c;中式滋补在沉寂多年后火热翻红&#xff0c;以官栈为代表的新品牌快速崛起&#xff0c;而老字号也紧跟…

非零基础自学Golang 第15章 Go命令行工具 15.5 代码测试(test) 15.5.2 基准测试 15.5.3 覆盖率测试

非零基础自学Golang 文章目录非零基础自学Golang第15章 Go命令行工具15.5 代码测试(test)15.5.2 基准测试15.5.3 覆盖率测试第15章 Go命令行工具 15.5 代码测试(test) 15.5.2 基准测试 基准测试提供可自定义的计时器和一套基准测试算法&#xff0c;能方便快速地分析一段代码…

P5 PyTorch 常用数学运算

前言&#xff1a; 这里主要介绍一下PyTorch 的常用数学运算 目录&#xff1a; 1&#xff1a; add|sub 加减法 2: mul/div 乘/除运算 3: 矩阵乘法 4 2D矩阵转置 5 其它常用数学运算 6 clamp 梯度剪裁 一 加减法 1.1 加法 可以直接通过符号 或者 torch.add # -*- co…

并发编程学习(五):设计模式~同步模式之保护性暂停

1、保护性暂停 模式的定义 保护性暂停 即Guarded Suspension&#xff0c;用于在一个线程等待另一个线程的执行结果。 要点&#xff1a; 有一个结果需要从一个线程传递到另一个线程&#xff0c;让它们关联同一个对象GuardedObject。如果有结果不断从一个线程到另一个线程&…

Redis架构演变之主从、Sentinel哨兵、Cluster(通信、分片、路由等机制)

一. 主从复制 1. 含义 在分布式系统中&#xff0c;为了解决单点问题&#xff0c;通常会把数据复制多个副本到其它机器&#xff0c;满足故障恢复和负载均衡等要求&#xff0c;Redis也是如此&#xff0c;提供了主从复制功能。&#xff08;redis第一代架构&#xff09; 实质&…

程序员35岁就失业了吗?就没有其他路可以选了吗?

前言 回到老家最近感到很迷茫&#xff0c;不知道该做什么&#xff0c;也不知道学习了更多的技术又能干什么。 有句话确实是很符合我现在的处境&#xff1a;时势造英雄&#xff01;虽然我不是英雄&#xff0c;但是我确实需要一个鞥一展所长的环境。 记得当初决定回到哈尔滨&a…

【大话设计模式】工厂+策略+装饰模式 hw01

背景 小李已经是一个工作一年的初级工程师了&#xff0c;他所在的公司是一家大型购物商场。随着各种网络购物软件兴起&#xff0c;老板也想做一个商场的购物 APP。分给小李的是一个一个订单结算模块&#xff0c;需要支持各种不同的结算策略。 需求 请帮小李写一个订单结算模…

vm2 <3.9.10 存在任意代码执行漏洞

漏洞描述 vm2 是一个基于 Node.js 的沙箱环境&#xff0c;可以使用列入白名单的 Node 内置模块运行不受信任的代码。 vm2 3.9.10之前版本中由于 WeakMap.prototype.set 方法使用原型查找从而存在任意代码执行漏洞&#xff0c;攻击者可利用此漏洞在沙箱内执行任意恶意代码&…

盲盒抽奖流程

盲盒模块的流程大致如下&#xff1a; 进入盲盒抽奖页面&#xff0c;需要初始化直接获取一些盲盒的信息&#xff0c;例如&#xff1a;盲盒活动id&#xff0c;开奖buff等。首先需要获取盲盒活动id&#xff0c;后面的所有请求都是基于盲盒活动id进行的。 初始化获取: 盲盒活动id…

Thymeleaf 下拉列表传值示例

参考资料 Spring Boot で Thymeleaf 使い方メモ 目录一. 前期准备二. 实体类.内部类设置下拉列表值2.1 form实体类2.2 Controller层2.3 Thymeleaf页面三. request.setAttribute()设置下拉列表值3.1 定义下拉列表存放类3.2 Controller层3.3 Thymeleaf页面一. 前期准备 枚举类 …

FT2232作为JTAG烧录器的使用步骤详解

FT2232作为JTAG烧录器的使用步骤详解FT2232作为JTAG烧录器的使用步骤详解配置OpenOCD环境(已经配置好的可以跳过)【步骤 1】安装 FT2232HL 芯片的驱动&#xff0c;安装文件为 CDM21228_Setup.exe。【步骤 2】 安装 FT_Prog_v3.6.88.402 Installer.exe【步骤 3】 使用 FT Prog 软…

模型实战一之YOLOv7实例分割、模型寻来自己数据集

模型实战一之YOLOv7实例分割、模型训练自己数据集 1.环境准备 下载yolov7实例分割模型&#xff1a; git clone https://github.com/WongKinYiu/yolov7.git -b mask yolov7-maskcd yolov7-mask安装环境 #查看已安装环境 conda info --envs #查看安装了哪些包 conda list#创建…

神奇的线性表(链表)

目录 神马是链表 链表的分类 单向链表 链表的常用操作 查找操作 插入操作 删除操作 链表与数组 数组的插入 数组的删除 链表的应用 尾声 神马是链表 记得很久很久以前…我们学习过数组&#xff0c; 数组是在内存中一段连续的存储空间&#xff0c; 可以在常数时间内访…

逻辑分析仪解析SPI数据

工具为梦源逻辑分析仪&#xff0c;本次测试的是ST7789v屏幕驱动 接线方面一共需要三根线&#xff08;MOSI&#xff0c;SCL&#xff0c;GND&#xff09; SCL PA5 MOSI PA7 DSView上位机配置 通道按照接线选择&#xff0c;这个一定要对应上 COPL CPOH按照SPI实际配置来&#x…

生成模型(四):扩散模型(Diffusion Models)

本文大纲如下&#xff1a; 生成模型种类 到目前为止&#xff0c;我已经写了三种类型的生成模型&#xff0c;[[生成模型-GAN]]、[[生成模型-VAE]]和[[生成模型-Flow based model]]。 它们在生成高质量样本方面显示出巨大的成功&#xff0c;但每一种都有其自身的一些局限性。下…

基于Python的GUI图形用户界面编程

【无限嚣张&#xff08;菜菜&#xff09;】&#xff1a;hello您好&#xff0c;我是菜菜&#xff0c;很高兴您能来访我的博客&#xff0c;我是一名爱好编程学习研究的菜菜&#xff0c;每天分享自己的学习&#xff0c;想法&#xff0c;博客来源与自己的学习项目以及编程中遇到问题…