Compose 动画艺术探索之 Easing
本文为稀土掘金技术社区首发签约文章,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:
FastOutSlowInEasingLinearOutSlowInEasingFastOutLinearEasingLinearEasingCubicBezierEasing其中CubicBezierEasing是剩下四种的父类,这几种Easing的具体用法在Compose 动画艺术探索之动画规格中已经介绍过,这里将就不再赘述,如果想看这几种Easing的动画效果可以先移步去看下。
下面来看下Easing的使用方法:
valvalue1byanimateFloatAsState(
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
classCubicBezierEasing(
privatevala:Float,
privatevalb:Float,
privatevalc:Float,
privatevald:Float
):Easing{
......
privatefunevaluateCubic(a:Float,b:Float,m:Float):Float{
return3*a*(1-m)*(1-m)*m+
3*b*(1-m)*m*m+
m*m*m
}
overridefuntransform(fraction:Float):Float{
if(fraction0ffraction1f){
varstart=0.0f
varend=1.0f
while(true){
valmidpoint=(start+end)/2
valestimate=evaluateCubic(a,c,midpoint)
if((fraction-estimate).absoluteValueCubicErrorBound)
returnevaluateCubic(b,d,midpoint)
if(estimatefraction)
start=midpoint
else
end=midpoint
}
}else{
returnfraction
}
}
......
}
嗯,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:
valLinearEasing:Easing=Easing{fraction-fraction}
由于默认就是线性的,所以直接返回未修改的分数就是线性的动画效果。
接下来咱们来自定义一个Easing!
valCustomLinearEasing:Easing=Easing{fraction-fraction/2}
代码很简单,直接实现Easing接口,然后将分数除以二并返回,再来写个 Demo !
varsmallbyremember{mutableStateOf(true)}
valsizebyanimateDpAsState(
targetValue=if(small)50.dpelse100.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的分数返回值修改为了之前的一半而导致的。
刚才的分数只是除以了二,这回咱们直接改为负数看看!
valCustomLinearEasing:Easing=Easing{fraction--fraction/2}
别的都没动,只是加了个负号,来运行看下效果!
easing2.gif可以看到动画效果正好和刚才是相反的方向!
接下来再玩一下,刚才是除以二,这回咱们来乘二看下效果!
valCustomLinearEasing:Easing=Easing{fraction-fraction*2}
运行看下效果!
easing3.gif可以看到,动画效果执行到目标值还在方法或缩小,最后返回到既定值。
总结如果想玩好Compose中的动画,Easing是必不可少的一环,其实官方给实现的Easing基本都能满足咱们的日程开发需求,如果实现需要自定义那就只能自定义搞一搞了,不过在自定义前可以思考下是直接实现Easing接口还是继承CubicBezierEasing。
本文至此结束,有用的地方大家可以参考,当然如果能帮助到大家,哪怕是一点也足够了。就这样。
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线