2009-11-19 14 views
15

Mi avvicino all'animazione core e disegno empiricamente. Sto provando ad animare una forma semplice; la forma in questione è formata da 3 linee più una curva di bezier. Viene anche disegnata una linea rossa per mostrare i punti di controllo della curva.Animazione di una forma con CoreAnimation

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

mio controller principale aggiunge semplicemente questa visualizzazione secondaria e chiama il metodo adjustWave ogni volta touchesEnd. Ecco il codice per la mia classe di disegno della forma. Come vedi la classe ha una proprietà, cp1x (la x del bezeer control point 1). Questo è il valore che vorrei animare. Attenzione, questo è un tentativo stupido ...

- (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]; 
} 

La forma non cambia. Se, al contrario, tolgo il codice CA e aggiungo un semplice `[self setNeedsDisplay] nell'ultimo metodo che la forma cambia, ma ovviamente senza CA. Puoi aiutare sme? Sono sicuro che sto facendo un errore molto semplice qui ... Grazie in anticipo, Davide

+0

Come dice Brad, è possibile utilizzare la classe CAShapeLayer per animare una forma arbitraria costruendo un oggetto CABasicAnimation o CAKeyframeAnimation e animando con la proprietà 'path'. Ho scritto un post su questa classe se vuoi controllare il codice di esempio. http://bit.ly/shapelayer –

risposta

17

Se si sta scrivendo questo per iPhone OS 3.x (o Snow Leopard), il nuovo CAShapeLayer class dovrebbe consentire di eseguire questo tipo di animazione abbastanza facilmente. Se si dispone di un percorso che mantiene lo stesso numero di punti di controllo (come nel caso), è possibile impostare tale percorso su CAShapeLayer, quindi animare la proprietà del percorso da quel valore iniziale al percorso finale. Core Animation eseguirà l'interpolazione appropriata dei punti di controllo nel percorso per animarlo tra questi due stati (in più, se usi un CAKeyframeAnimation).

Si noti che questo è un livello, quindi sarà necessario aggiungerlo come sottolivello di UIView. Inoltre, non credo che la proprietà del path sia implicitamente animata, quindi potrebbe essere necessario creare manualmente un CABasicAnimation per animare la modifica della forma dal percorso 1 al percorso 2.

EDIT (21/11/2009): Joe Ricioppo ha una bella recensione su CAShapeLayer here, compresi alcuni video che mostrano questi tipi di animazioni.

+0

CAShapeLayer è molto buggato in iPhone OS 3.x – dontWatchMyProfile

+0

@mystify - In che modo? Ho funzionato abbastanza bene per me, ma è necessario ricordare di avere lo stesso numero di punti di controllo iniziali e finali nei percorsi o i risultati non sono definiti. –

-1

Non sarai in grado di animare la tua forma con CA. È possibile animare solo le proprietà dei livelli in CA, non le proprietà personalizzate.

CA può essere veloce perché non è necessario richiamare il codice per eseguire animazioni, se si pensa a come è implementato, fondamentalmente è solo un thread che esegue operazioni di primitive GL con frame e contenuti CALayer.

Le animazioni CA sono insiemi di istruzioni per l'esecuzione di CA sul relativo thread in background, attivazione e dimenticanza (oltre a callback al completamento dell'animazione), non callback al codice.

Per animare il contenuto di un livello, è necessario che CA ti richiami per disegnare su ciascun fotogramma o per istruire CA su come disegnare. Nessuno di questi capita.

+0

Credo di avere molto da imparare qui :) In ogni caso, non mi interessa davvero il codice che ho mostrato sopra, è solo una prova di concetto. C'è un modo alternativo per fare qualcosa di simile con CA? O dovrei lasciare solo CA e chiamare setNeedDisplay? – nutsmuggler

+0

setNeedsDisplay è unidirezionale, openGL è un altro. Non credo che tu possa con CA. – duncanwilcox

+1

In realtà è possibile animare forme utilizzando la classe CAShapeLayer e animando la proprietà 'percorso'. –

Problemi correlati