2009-11-19 9 views
15

私はコアアニメーションに近づき、経験的に描画します。 シンプルな図形をアニメーション化しようとしています。問題の形状は、3本の線とベジェ曲線によって形成される。カーブコントロールポイントを表示するために、赤い線も描画されます。CoreAnimationでシェイプをアニメーション化する

alt text http://img.skitch.com/20091119-1ufar435jdq7nwh8pid5cb6kmm.jpg

私のメインコントローラは、単純にこのサブビューを追加し、いつでもtouchesEndadjustWaveメソッドを呼び出します。 私の図形描画クラスのコードは次のとおりです。ご覧のように、クラスには1つのプロパティcp1x(ベジェコントロールポイント1のx)があります。これはアニメーション化したい値です。マインド、これはダムの試みです...

- (void)drawRect:(CGRect)rect { 
    float cp1y = 230.0f; 
    float cp2x = 100.0f; 
    float cp2y = 120.0f; 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    CGContextClearRect(ctx, rect); 

    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPathMoveToPoint(path, NULL, 10.0f, 200.0f); 
    CGPathAddCurveToPoint (path, NULL, cp1x, cp1y, cp2x, cp2y, 300.0f, 200.0f); 
    CGPathAddLineToPoint(path, NULL, 300.0f, 300.0f); 
    CGPathAddLineToPoint(path, NULL, 10.0f, 300.0f); 
    CGPathCloseSubpath(path); 
    CGContextSetFillColorWithColor(ctx, [UIColor blueColor].CGColor); 
    CGContextAddPath(ctx, path); 
    CGContextFillPath(ctx); 

    // Drawing a line from control points 1 and 2 
    CGContextBeginPath(ctx); 
    CGContextSetRGBStrokeColor(ctx,1,0,0,1); 
    CGMutablePathRef cp1 = CGPathCreateMutable(); 
    CGPathMoveToPoint(cp1, NULL, cp1x, cp1y); 
    CGPathAddLineToPoint(cp1, NULL, cp2x, cp2y); 
    CGPathCloseSubpath(cp1); 
    CGContextAddPath(ctx, cp1); 
    CGContextStrokePath(ctx); 
} 

- (void)adjustWave { 
    [UIView beginAnimations:@"movement" context:nil]; 
    [UIView setAnimationDelegate:self]; 
    [UIView setAnimationWillStartSelector:@selector(didStart:context:)]; 
    [UIView setAnimationDidStopSelector:@selector(didStop:finished:context:)]; 
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; 
    [UIView setAnimationDuration:3.0f]; 
    [UIView setAnimationRepeatCount:3]; 
    [UIView setAnimationRepeatAutoreverses:YES]; 
    cp1x = cp1x + 20.0f; 
    [UIView commitAnimations]; 
} 

形状は変わりません。逆にCAコードを取り出し、最後のメソッドでシンプルな `[self setNeedsDisplay]を追加すると、形状は変わりますが、明らかにCAはありません。 お手伝いできますか?私はここで非常に基本的な間違いをしていると確信しています... 事前に感謝、 Davide

+0

Bradによると、CachasicAnimationまたはCAKeyframeAnimationを構築し、 'path'プロパティでアニメーション化することで、CAShapeLayerクラスを使用して任意のシェイプをアニメーション化できます。あなたがサンプルコードをチェックしたいなら、私はこのクラスについての投稿を書いた。 http://bit.ly/shapelayer –

答えて

17

iPhone OS 3.x(またはSnow Leopard)用にこれを書いている場合、新しいCAShapeLayer classはこの種のアニメーションをかなり簡単に行うことができるはずです。同じ数のコントロールポイントを保持するパス(ケースのような)がある場合、そのパスをCAShapeLayerに設定してから、その開始値から最終パスまでパスプロパティをアニメートできます。コアアニメーションは、パス内のコントロールポイントの適切な補間を実行して、2つの状態間でアニメーション化します(さらに、CAKeyframeAnimationを使用する場合)。

これはレイヤーなので、UIViewのサブレイヤとして追加する必要があります。また、パスプロパティが暗黙的にアニメーション化されるとは思わないので、パス1からパス2へのシェイプの変更をアニメートするためにCABasicAnimationを手動で作成する必要があります。

EDIT(11/21/2009):Joe Ricioppoは、CAShapeLayer hereについて、この種のアニメーションを示すいくつかのビデオを含めて素敵な記事を書いています。

+0

CAShapeLayerはiPhone OS 3.xで非常にバグです – dontWatchMyProfile

+0

@mystify - どのようにですか?私は合理的にうまく動作していましたが、あなたのパスに開始点と終了点の数が同じであることを忘れたり、結果が未定義であることを覚えておく必要があります。 –

-1

CAでシェイプをアニメーション化することはできません。カスタムプロパティではなく、CAのレイヤプロパティのみをアニメートできます。

CAは、アニメーションを実行するためにコードをコールバックする必要がないため、高速である可能性があります。実装方法について考えると、基本的にはCALayerフレームとコンテンツでGLプリミティブ演算を実行するスレッドに過ぎません。

CAアニメーションは、CAのバックグラウンドスレッドで実行するための命令セットで、コードのコールバックではなく、ファイアアンドファーニング(アニメーション完了時のコールバック)を行います。

レイヤーの内容をアニメーション化するには、CAが各フレームで描画するか、描画方法をCAに指示する必要があります。それらのどちらも起こらない。

+0

私はここで学ぶことがたくさんあると思います:) いずれにしても、私は上に示したコードを本当に気にしません。それは単なる概念証明です。 CAと同様のことをする別の方法はありますか?それとも、CAだけを残してsetNeedDisplayを呼び出す必要がありますか? – nutsmuggler

+0

setNeedsDisplayは1つの方法ですが、OpenGLは別の方法です。私はCAと一緒にできるとは思わない。 – duncanwilcox

+1

実際には、CAShapeLayerクラスを使ってシェイプをアニメーション化し、 'path'プロパティをアニメートすることができます。 –

関連する問題