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秒後に到達します。 100%(1000px)マークに到達するには、残りのti 3 =5.2秒が必要です。

何が素晴らしいでしょうが、提供されていません:

説明されているように、アニメーションがアニメーションの進行間隔でデリゲートメソッドを呼び出した場合、この質問をする必要はありません…;-)

問題を解決する方法のアイデア:

私が考えることができる1つの解決策は、ベジェ曲線の値を計算し、それをti k値(アニメーションの合計期間がわかっている)にマッピングし、アニメーションが開始されたときに、animationProgresssCallback:手動でそれらの遅延を使用してセレクターを順次実行することです。

明らかに、これは非常識であり(ベジェ曲線を手動で計算しますか??)、さらに重要なことに、信頼性がありません(アニメーションスレッドとメインスレッドが同期しているとは言えません-またはできますか?)。

何か案は??

あなたのアイデアを楽しみにしています!

4

1 に答える 1

1

問題を解決する方法のアイデア:

私が考えることができる 1 つの解決策は、ベジエ曲線の値を計算し、それを tik 値にマップし (アニメーションの合計時間を知っています)、アニメーションが開始されたら、animationProgresssCallback: セレクターをそれらの遅延で手動で順番に実行することです。

明らかに、これは常軌を逸しています (手動でベジエ曲線を計算しますか??)。さらに重要なことに、信頼性がありません (アニメーション スレッドとメイン スレッドが同期しているとは言えません。または同期できますか?)。

実際、これは信頼できます。CoreAnimation は時間ベースであるため、デリゲートを使用して、アニメーションが実際に開始されたときに通知を受けることができます。ベジエ パスの計算については、次のように考えてください。OpenGLES でサーフェスを実装する場合は、Cubic Bezier を計算する必要があります。笑。あなたのケースは一次元にすぎません。数学を知っていればそれほど難しくありません。

于 2010-07-15T18:58:29.157 に答える