3

假设我想为一个向右滚动 1000 像素的球制作动画,并在此过程中指定一个计时函数——如下所示:

UIView *ball = [[UIView alloc] initWithFrame:CGRectMake(0,0,30,30)];
CABasicAnimation* anim =
        [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
anim.toValue = [NSNumber numberWithFloat:ball.frame.origin.x + 1000.0];
                                            // move 1000 pixels to the right
anim.duration = 10.0;
anim.timingFunction = [CAMediaTimingFunction functionWithControlPoints:
                      0.1 :0.0 :0.3 :1.0]; // accelerate fast, decelerate slowly
[ball.layer addAnimation:anim forKey:@"myMoveRightAnim"];

我最终想要的是有一个方法,比如说-(void)animationProgressCallback:(float)progress,在动画期间被调用,在动画进度的规则间隔中,就开始值和结束值之间的绝对“距离”而言,即忽略计时函数。

我将尝试用上面的例子来解释,球向右滚动 1000px(按 y 轴绘制,在我们的例子中是 100%=1000px):

替代文字

我希望每当球前进 250 像素时调用我的回调方法。由于计时功能,前 250 个像素可能在 ti 0 =2 秒后到达,总距离的一半在 ti 1 = 0.7 秒后(快速加速开始),750px 标记另一个 ti 2 = 1.1 秒后,并且需要剩余的 ti 3 = 5.2 秒才能达到 100% (1000px) 标记。

什么会很棒,但没有提供:

如果动画按照描述在动画进度间隔中调用委托方法,我就不需要问这个问题...... ;-)

如何解决问题的想法:

我能想到的一种解决方案是计算贝塞尔曲线的值,将其映射到 ti k值(我们知道动画的总持续时间),当动画开始时,我们animationProgresssCallback:手动执行带有这些延迟的选择器。

显然,这很疯狂(手动计算贝塞尔曲线??),更重要的是,不可靠(我们不能依赖动画线程和主线程同步——或者我们可以吗?)。

有任何想法吗??

期待你的想法!

4

1 回答 1

1

如何解决问题的想法:

我能想到的一种解决方案是计算贝塞尔曲线的值,将其映射到 tik 值(我们知道动画的总持续时间),当动画开始时,我们手动执行带有这些延迟的 animationProgresssCallback: 选择器。

显然,这很疯狂(手动计算贝塞尔曲线??),更重要的是,不可靠(我们不能依赖动画线程和主线程同步——或者我们可以吗?)。

其实这个是靠谱的。CoreAnimation 是基于时间的,因此您可以使用代理在动画真正开始时收到通知。关于计算贝塞尔路径......好吧,这样看:如果你想在OpenGLES中实现一个表面,你必须计算一个三次贝塞尔曲线!哈哈。您的案例只是一个维度,如果您知道数学,那并不难。

于 2010-07-15T18:58:29.157 回答