本文为稀土技术社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!
本篇文章是此专栏的第六篇文章,前几篇文章大约将 Compose
中的动画都简略过了一遍,假如想阅览前几篇文章的话能够点击下方链接:
- Compose 动画艺术探究之瞅下 Compose 的动画
- Compose 动画艺术探究之可见性动画
- Compose 动画艺术探究之属性动画
- Compose 动画艺术探究之动画标准
- Compose 动画艺术探究之灵动岛
- Compose 动画艺术探究之 AnimationVector
什么是 Easing?
根据时长的
AnimationSpec
操作(如tween
或keyframes
)运用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
远远不止上面说的这几种,还有许多,先来张图感受下有多少吧!
小小提示,并没有截完。。。下面还有,这儿就不放那么多截图了。每一种 Easing
都对应着一种动画作用,我们能够去 看每一种 Easing
对应的动画作用样例。下面是官方文档地址:
developer.android.google.cn/reference/k…
怎么自界说 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
中有一个办法 transform
,CubicBezierEasing
类完成了三阶贝塞尔曲线,这相当于原生的 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
的分数回来值修正为了之前的一半而导致的。
方才的分数仅仅除以了二,这回我们直接改为负数看看!
val CustomLinearEasing: Easing = Easing { fraction -> -fraction / 2 }
别的都没动,仅仅加了个负号,来运转看下作用!
能够看到动画作用正好和方才是相反的方向!
接下来再玩一下,方才是除以二,这回我们来乘二看下作用!
val CustomLinearEasing: Easing = Easing { fraction -> fraction * 2 }
运转看下作用!
能够看到,动画作用履行到目标值还在办法或缩小,最终回来到既定值。
总结
假如想玩好 Compose
中的动画,Easing
是必不可少的一环,其实官方给完成的 Easing
根本都能满足我们的日程开发需求,假如完成需要自界说那就只能自界说搞一搞了,不过在自界说前能够思考下是直接完成 Easing
接口还是承继 CubicBezierEasing
。
本文至此完毕,有用的当地我们能够参考,当然假如能帮助到我们,哪怕是一点也足够了。就这样。