我想要一个等同于UIViewAnimationCurveEaseInOut的缓动函数,但是没有看到Apple将它作为一个函数公开。
我试过the easeInOutQuad function posted here但没有成功。我的Objective-C版本的功能是:
-(float) getEaseInOutValueWithElapsedMillis: (float) t startValue: (float) b endValue: (float) c andTotalMillis: (float) d {
float value =0.0f;
if ((t/=d/2.0f) <1.0f)
value =c/2.0f*t*t + b;
else
value =-c/2.0f * ((--t)*(t-2.0f) - 1.0f) + b;
debug(@"t=%f b=%f c=%f d=%f value=%f", t, b, c, d, value);
return value;
}
记录的结果是:
当起始值小于结束值时:
t=0.066467 b=110.000000 c=225.000000 d=500.000000 value=110.497017
t=0.133133 b=110.000000 c=225.000000 d=500.000000 value=111.993996
t=0.199799 b=110.000000 c=225.000000 d=500.000000 value=114.490944
...
t=0.999786 b=110.000000 c=225.000000 d=500.000000 value=222.451935
t=0.066452 b=110.000000 c=225.000000 d=500.000000 value=236.954926
t=0.133118 b=110.000000 c=225.000000 d=500.000000 value=250.457932
... (note that value shot right past c)
t=0.866440 b=110.000000 c=225.000000 d=500.000000 value=332.993195
t=0.933105 b=110.000000 c=225.000000 d=500.000000 value=334.496582
t=0.999771 b=110.000000 c=225.000000 d=500.000000 value=335.000000
100%的值最终为b + c,而不是c。
当起始值大于结束值时:
t=0.047389 b=225.000000 c=110.000000 d=700.000000 value=225.123520
t=0.095008 b=225.000000 c=110.000000 d=700.000000 value=225.496460
...
t=0.904504 b=225.000000 c=110.000000 d=700.000000 value=334.498413
t=0.952122 b=225.000000 c=110.000000 d=700.000000 value=334.873932
t=0.999740 b=225.000000 c=110.000000 d=700.000000 value=335.000000
同样,100%的值最终为b + c,而不是c。
也许我已经破坏了代码。我怎样才能实现适当的轻松自拔?
答案 0 :(得分:1)
有点晚了,但现在很快。
在Playgrounds中运行它:
import UIKit
var sValue: CGFloat = 0
var eValue: CGFloat = 100
var tDuration: CGFloat = 100
var eTime: CGFloat = 0
var currentValue: CGFloat = 0
func easeInOutQuad (percentComplete: CGFloat, elapsedTimeMs: CGFloat, startValue: CGFloat, endValue: CGFloat, totalDuration: CGFloat) -> CGFloat {
var newElapsedTimeMs = elapsedTimeMs
newElapsedTimeMs /= totalDuration/2
if newElapsedTimeMs < 1 {
return endValue/2*newElapsedTimeMs*newElapsedTimeMs + startValue
}
newElapsedTimeMs = newElapsedTimeMs - 1
return -endValue/2 * ((newElapsedTimeMs)*(newElapsedTimeMs-2) - 1) + startValue
}
for i in eTime...tDuration {
currentValue = easeInOutQuad(0, CGFloat(i), sValue, eValue, tDuration)
}
答案 1 :(得分:1)
我想要一个相当于的缓和功能 UIViewAnimationCurveEaseInOut,但没有看到Apple公开了这一点 作为一种功能。
Apple通过CAMediaTimingFunction
通过[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]
公开getControlPointAtIndex:values:
,您可以通过f(n)
来获取控制点。您将了解到它是一个具有控制点(0,0),(0.42,0),(0.58,1),(1,1)的三次贝塞尔曲线。
这为你提供了一个贝塞尔函数value
,它沿着x绘制为time
的二维图表,沿着y,与n
对齐。因此,要获得正确的值,只需求解x = time
f.x(n) = (1-n)^3 * 0 + 3(1-n)^2 * n * 0.42 + 3(1-n) * n^2 * 0.58 + n^3 * 1
= 3(1-n)^2 * n * 0.42 + 3(1-n) * n^2 * 0.58 + n^3
= 1.26(1 - 2n + n^2) * n + 1.74 (1 - n) * n^2 + n^3
= 1.26n - 2.52n^2 + 1.26n^3 + 1.74n^2 - 1.74n^3 + n^3
= 1.26n - 0.78n^2 + 0.52n^3
,然后读取值。
具体来说,在这个功能中:
0.5 = 1.26n - 0.78n^2 + 0.52n^3
(免责声明:临时写出;请检查)
要获得0.5时的值,请求n:
f.y(n)
然后将其插入等效的{{1}}。 There's a formula to solve a cubic但稍微涉及到这一点(i)阅读维基百科文章并使用公式;或者(ii)写一个数字解算器,例如通过二进制搜索。这种特殊的立方体表现非常好,每次只有一种解决方案。