Android动效Compose贝塞尔曲线动画规格详解

目录
  • 正文
  • 贝塞尔曲线
  • 解析动画曲线
  • 曲线源码分析
  • 总结

正文

写Compose动画的时候使用animateXAsState的时候会注意到一个参数——animationSpec,如下:

val borderRadius by animateIntAsState(
    targetValue = if (isRound) 100 else 0,
    animationSpec = tween(
        durationMillis = 3000,
        easing = LinearEasing
    )
)

此处就不深入探讨不同的animationSpec类型有什么作用,主要看tween,它是几乎最简单的一个类型,即使用缓动曲线的起始点到终点的动画规格

那么其中的easing参数就是该动画规格的缓动曲线。什么是easing曲线,可以看下图:

x轴可以理解为时间进度,而y轴可以理解动画的进度,可以看出该图为线性曲线,即从头到尾保持一样的速度。关于各个不同的曲线产生不同的动画效果可以看下Android官网的Easing API,里面有比较多的动图来演示。

点进tween源码可以看到easing参数默认使用FastOutSlowInEasing曲线。

@Stable
fun <T> tween(
    durationMillis: Int = DefaultDurationMillis,
    delayMillis: Int = 0,
    easing: Easing = FastOutSlowInEasing
): TweenSpec<T> = TweenSpec(durationMillis, delayMillis, easing)

根据名字可以看出FastOutSlowInEasing为一开始加速,收尾时减速的曲线。

点进FastOutSlowInEasing源码可以看到官方内置了多个曲线,其中有三个贝塞尔曲线,一个线性曲线。

val FastOutSlowInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)
val LinearOutSlowInEasing: Easing = CubicBezierEasing(0.0f, 0.0f, 0.2f, 1.0f)
val FastOutLinearInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 1.0f, 1.0f)
val LinearEasing: Easing = Easing { fraction -> fraction }

到这里就可以看到CubicBezierEasing,即贝塞尔曲线。而这个就是本篇文章的主角。

贝塞尔曲线

贝塞尔曲线可以通过端点把手精确地画出想要的丝滑的曲线。

而上文中的三个内置的贝塞尔曲线在制图软件中就如下(可能有些偏差):

但是曲线图片和传进去的参数又有怎样的映射关系呢?

还记得刚刚贝塞尔曲线的描述吗?端点和把手来生成贝塞尔曲线。端点我们有了,即(0,0)和(1,1),那么我现在以FastOutSlowInEasing为例,把把手显示出来:

看到这里,其实答案很明确了!传进去的其实是把手的端点

  • 第一个参数为起始点把手的x坐标
  • 第二个参数为起始点把手的y坐标
  • 第三个参数为终点把手的x坐标
  • 第四个参数为终点把手的y坐标
CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)

知道这个原理之后就可以通过CubicBezierEasing画出各种想要的贝塞尔动画曲线了,而具体如何定义一根合理好看的动画的曲线就交给动画师吧!

解析动画曲线

我们打开After Effects,画一个小球,给小球的位置K两个关键帧,并将两个关键帧右键缓动。如下:

点开图标编辑器,之后就看到了两根动画曲线

绿色那根是不是很熟悉!就是刚刚讲的动画曲线(但是单位不一样,之前的单位为百分比单位,0即未开始,1为结束)从这里很清晰地看出x轴为时间,而Y轴则为动画的进度,都是实际的值。这里就不多说了,重点看白色那根动画曲线,可以猜猜是什么曲线。

恭喜你猜对了!是速度曲线。

在第一个格子的时候速度达到巅峰,因此可以看出绿色那根动画曲线在第一个格子的时候切线是最陡的,几乎接近垂直,在开始和结束的时候速度比较小,而此时的切线是平缓的。

将红箭头比作一个y = kx一元一次函数的话,而k的值就是白色曲线的y轴的值。

而该曲线则类似内置的FastOutSlowInEasing,先提高加速度,后减少加速度的曲线,导出动画效果如下。

曲线源码分析

点进Easing接口可以看到一个transform函数,传入一个Float类型的fraction,返回一个Float类型的值。而这个其实就是x轴和y轴的值,即时间和进度百分比,一般在0-1之间活动。

@Stable
fun interface Easing {
    fun transform(fraction: Float): Float
}

CubicBezierEasing则继承了Easing,并实现了transform方法

@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
        }
    }
    ...
}

但是公式我看不懂哈哈(= _=)。

进阶一点的话可以实现Easing来定义自己的曲线!

总结

其实我们很多APP对于动画的使用其实是非常局限的,包括曲线!我们大多数动画都在使用生硬的线性动画,其中一个原因就是程序员和设计师的交流隔了一个专业,实际沟通比较困难。

以上就是Android动效Compose贝塞尔曲线动画规格详解的详细内容,更多关于Android Compose贝塞尔曲线的资料请关注我们其它相关文章!

(0)

相关推荐

  • Compose状态保存rememberSaveable原理解析

    目录 前言 从一个报错说起 rememberSaveable 源码分析 恢复 key 的数据 注册 ValueProvider 注销 registry DisposableSavableStateRegistry 源码分析 saveableStateRegistry 与 SavedStateRegistry DisposableSaveableStateRegistry 与 SaveableStateRegistryImpl canBeSavedToBundle SaveableStateReg

  • docker资源限制和compose部署详解

    目录 一.私有仓库建立 二.Cgroup 资源配置方法 三.CPU使用率控制 使用 stress 工具测试 CPU 和内存 四. CPU 周期限制 五. CPU Core 控制 六. CPU 配额控制参数的混合使用 七. 内存限额 八.Block IO 的限制 九. bps 和 iops 的限制 十. 构建镜像(docker build)时指定资源限制 十一. compose部署 十二. consul部署 总结 一.私有仓库建立 docker pull registry 在docker 引擎终端

  • Jetpack Compose状态专篇精讲

    目录 1.remember 2.rememberSaveable 3.状态提升 4.状态管理 将Composable作为可信来源 将状态容器作为可信来源 将 ViewModel 作为可信来源 应用中的状态是指可以随时间变化的任何值.这是一个非常宽泛的定义,从 Room 数据库到类的变量,全部涵盖在内. 由于Compose是声明式UI,会根据状态变化来更新UI,因此状态的处理至关重要.这里的状态你可以简单理解为页面上展示的数据,那么状态管理就是处理数据的读写. 1.remember remembe

  • Jetpack Compose Canvas绘制超详细介绍

    目录 1. Canvas 2. 绘制方法 1. drawLine 2. drawRect 3. drawRoundRect 4. drawImage 5. drawCircle 6. drawArc 7. drawPath 8. drawPoints 3. DrawScope拓展方法 1. inset 2. translate 3. rotate与rotateRad 4. scale 5. clipRect 6. drawIntoCanvas 7. withTransform 4.参考 1. C

  • Jetpack Compose自定义动画与Animatable详解

    目录 AnimationSpec 1.spring 2.tween 3.keyframes 4.repeatable 5.snap Animatable 本篇主要是自定义动画与Animatable. AnimationSpec 上一篇中,出现了多次animationSpec属性,它是用来自定义动画规范的.例如: fun Modifier.animateContentSize( animationSpec: FiniteAnimationSpec<IntSize> = spring(), fin

  • Jetpack Compose常用组件详细介绍

    目录 1. Text 2. Image 3. LazyColumn 1. Text 日常最常用的应该就是显示文字,所以有必要说一下Text控件.首先源码如下: @Composable fun Text( text: String, modifier: Modifier = Modifier, color: Color = Color.Unspecified, fontSize: TextUnit = TextUnit.Unspecified, fontStyle: FontStyle? = nu

  • Android动效Compose贝塞尔曲线动画规格详解

    目录 正文 贝塞尔曲线 解析动画曲线 曲线源码分析 总结 正文 写Compose动画的时候使用animateXAsState的时候会注意到一个参数——animationSpec,如下: val borderRadius by animateIntAsState( targetValue = if (isRound) 100 else 0, animationSpec = tween( durationMillis = 3000, easing = LinearEasing ) ) 此处就不深入探

  • Jetpack Compose惯性衰减动画AnimateDecay详解

    目录 什么是惯性衰减动画 惯性衰减动画 使用要点 block 监听 什么是惯性衰减动画 比如说我们玩微信的时候 手指一拉,微信的列表就会惯性滑动 ,这个滑动的速率当然是越来越慢的,最终停止, 这个其实就是惯性衰减动画的典型例子 那这个例子和animateTo 有啥区别呢? 一个速率变慢的动画 ,听起来似乎 我们用animateTo 设置一些参数也可以实现 其实这里最大的区别就是 animateTo 你是需要设置目标值的,也就是动画结束的那一刻 某个view属性的值 你必须明确指定 而所谓的惯性衰

  • Android仿百度地图小度语音助手的贝塞尔曲线动画

    本文为大家分享了Android仿小度语音助手的贝塞尔曲线动画,供大家参考,具体内容如下 废话不多说,看下面的动图,和百度的还是有点点差别,我也不修改了,很简单,我实在是没有多余的时间,还要学习其他的东西. package com.example.helang.volumewave; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; impo

  • Android通过交互实现贝塞尔曲线的绘制

    目录 前言 获取触控位置 交互绘制实现 绘制代码 运行效果 总结 前言 之前几篇我们介绍了贝塞尔曲线的原理.绘制曲线和动效实现,这些都是代码预设好的,如果我们要根据需要自行绘制曲线,就需要使用交互来实现了.本篇我们先来介绍简单的交互式绘图,通过获取触控位置来设定贝塞尔曲线的控制点,从而实现交互式绘制曲线. 获取触控位置 第一个要解决的问题是如何获取手指在屏幕的触控位置.在 Flutter 中,提供了一个 Listener 组件,可以监听各类触控事件.Listener 的组件构造方法定义如下: c

  • Android自定义View绘制贝塞尔曲线中小红点的方法

    目录 前言 需求 效果图 代码 主要问题 简单画法 使用贝塞尔曲线 前言 上一篇文章用扇形图练习了一下安卓的多点触控,实现了单指旋转.二指放大.三指移动,四指以上同时按下进行复位的功能.今天这篇文章用很多应用常见的小红点,来练习一下贝塞尔曲线的使用. 需求 这里想法来自QQ的拖动小红点取消显示聊天条数功能,不过好像是记忆里的了,现在看了下好像效果变了.总而言之,就是一个小圆点,拖动的时候变成水滴状,超过一定范围后触发消失回调,核心思想如下: 1.一个正方形view,中间是小红点,小红点距离边框有

  • iOS实现贝塞尔曲线动画

    本文实例为大家分享了iOS实现贝塞尔曲线动画的具体代码,供大家参考,具体内容如下 效果如图: 仿美人相机,手势滑动隐藏顶部view.为了方便讲解,将屏幕分为几个区域,如图: 在拖动过程中: 1.拖动距离小于minMoveDistance,贝赛尔曲线发生形变 2.拖动大于minMoveDistance,整个view开始下移 在松开手时: 1.拖动距离小于minMoveDistance,未发生位移,贝塞尔曲线恢复形变 2.拖动大于minMoveDistance,小于minDisappearDista

  • Android自定义View绘制贝塞尔曲线的方法

    本文实例为大家分享了Android自定义View绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下 在平面内任选 3 个不共线的点,依次用线段连接. 在第一条线段上任选一个点 D.计算该点到线段起点的距离 AD,与该线段总长 AB 的比例. 根据上一步得到的比例,从第二条线段上找出对应的点 E,使得 AD:AB = BE:BC. 连接这两点 DE. 从新的线段 DE 上再次找出相同比例的点 F,使得 DF:DE = AD:AB = BE:BC. 到这里,我们就确定了贝塞尔曲线上的一个点 F.接下

  • Android自定义View绘制贝塞尔曲线实现流程

    目录 前言 二阶贝塞尔曲线 三阶贝塞尔曲线 前言 对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的API供你调用.由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主要讲解二阶和三阶. 二阶贝塞尔曲线 在Android中,使用quadTo来实现二阶贝塞尔 path.reset() path.moveTo(startX, startY) path.quadTo(currentX, currentY, endX, endY) canvas.drawPath(path, cur

  • Android Flutter实现五种酷炫文字动画效果详解

    目录 前言 波浪涌动效果 波浪线跳动文字组 彩虹动效 滚动广告牌效果 打字效果 其他效果 自定义效果 总结 前言 偶然逛国外博客,看到了一个介绍文字动画的库,进入 pub 一看,立马就爱上这个动画库了,几乎你能想到的文字动画效果它都有!现在正式给大家安利一下这个库:animated_text_kit.本篇我们介绍几个酷炫的效果,其他的效果大家可以自行查看官网文档使用. 波浪涌动效果 波浪涌动 上面的动画效果只需要下面几行代码,其中loadUntil用于控制波浪最终停留的高度,取值是0-1.0,如

  • Jetpack Compose实现列表和动画效果详解

    目录 创建一个列表消息卡片 可交互的动画效果 创建一个列表消息卡片 到目前为止,我们只有一个消息的卡片,看上去有点单调,所以让我们来改善它,让它拥有多条信息.我们需要创建一个能够显示多条消息的函数.对于这种情况,我们可以使用 Compose 的 LazyColumn 和 LazyRow.这些 Composable 只渲染屏幕上可见的元素,所以它们的设计对于长列表来说很有效果.同时,它们避免了 RecyclerView 与 XML 布局的复杂性. import androidx.compose.f

随机推荐