假设我想为一个向右滚动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像素时调用我的回调方法。由于具有定时功能,可以在ti 0 = 2秒时达到前250个像素,仅达到ti 1 = 0.7秒后的总距离的一半(快速加速踢in),750px标记另一个ti 2 = 1.1秒后,需要剩余的ti 3 = 5.2秒才能达到100%(1000px)标记。
什么会很棒,但没有提供:
如果动画在描述的动画进度间隔中调用了委托方法,我就不需要问这个问题......; - )
想法如何解决问题:
我能想到的一个解决方案是计算贝塞尔曲线的值,将其映射到ti k 值(我们知道总动画持续时间),并且当动画启动时,我们依次执行我们的animationProgresssCallback:
选择器会手动延迟这些延迟。
显然,这是疯狂的(手动计算bezier曲线??),更重要的是,不可靠(我们不能依赖动画线程和主线程同步 - 或者我们可以吗?)。
任何想法?
期待您的想法!
答案 0 :(得分:1)
想法如何解决问题:
我能想到的一个解决方案是 计算贝塞尔曲线的值, 将其映射到tik值(我们知道 总动画持续时间),和 当动画开始时,我们 顺序执行我们的 animationProgresssCallback:选择器 手动延迟。
显然,这是疯了(计算 手动bezier曲线??)和更多 重要的是,不可靠(我们不能依赖 在动画线程和主要 线程要同步 - 或者我们可以吗?)。
实际上这是可靠的。 CoreAnimation是基于时间的,因此您可以在动画真正启动时使用委托进行通知。 关于计算bezier路径......好好看一下:如果你想在OpenGLES中实现一个表面,你可能需要计算一个Cubic Bezier!大声笑。你的情况只是一个维度,如果你知道数学就不那么难了。