2012-03-01 4 views
7

Si è verificato un problema durante la creazione di un'animazione esplicita per modificare il valore del percorso di un CAShapeLayer da un'ellisse a un rect.CAShapeLayer Animating Path Glitches/Flicker (da Ellisse a Rect e back)

Nella mia configurazione del controller tela ho un CAShapeLayer base e aggiungerlo al livello della vista root:

CAShapeLayer *aLayer; 
aLayer = [CAShapeLayer layer]; 
aLayer.frame = CGRectMake(100, 100, 100, 100); 
aLayer.path = CGPathCreateWithEllipseInRect(aLayer.frame, nil); 
aLayer.lineWidth = 10.0f; 
aLayer.strokeColor = [UIColor blackColor].CGColor; 
aLayer.fillColor = [UIColor clearColor].CGColor; 
[self.view.layer addSublayer:aLayer]; 

Poi, quando ho animare il percorso ho uno strano problema tecnico/sfarfallio negli ultimi fotogrammi del animazione quando la forma diventa retta e nei primi fotogrammi quando si anima lontano dall'essere un rect. L'animazione è configurato come segue:

CGPathRef newPath = CGPathCreateWithRect(aLayer.frame, nil); 
[CATransaction lock]; 
[CATransaction begin]; 
[CATransaction setAnimationDuration:5.0f]; 
CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"path"]; 
ba.autoreverses = YES; 
ba.fillMode = kCAFillModeForwards; 
ba.repeatCount = HUGE_VALF; 
ba.fromValue = (id)aLayer.path; 
ba.toValue = (__bridge id)newPath; 
[aLayer addAnimation:ba forKey:@"animatePath"]; 
[CATransaction commit]; 
[CATransaction unlock]; 

Ho provato molte cose diverse, come bloccare/sbloccare la CATransaction, giocando con varie modalità di riempimento, ecc ...

Ecco un'immagine del problema tecnico: http://www.postfl.com/outgoing/renderingglitch.png

un video di quello che sto vivendo può essere trovato qui: http://vimeo.com/37720876

risposta

5

Purtroppo questa è una limitazione del altrimenti soggezione alcune proprietà del percorso animabile di CAShapeLayers.

Fondamentalmente tenta di interpolare tra i due percorsi. Colpisce problemi quando il percorso di destinazione e il percorso di partenza hanno un numero diverso di punti di controllo - e le curve e i bordi dritti avranno questo problema.

È possibile provare a ridurre l'effetto disegnando l'ellisse come 4 curve anziché una singola ellisse, ma non è ancora corretta. Non ho trovato un modo per passare senza problemi da curve a poligoni.

Si può essere in grado di ottenere la maggior parte del modo lì, quindi trasferire a un'animazione dissolvenza per l'ultima parte - questo non sarà così bello, però.

+0

Tra la tua risposta e quella che ho postato da David Duncan, ho una buona idea di cosa sta succedendo. Speriamo che la proprietà del percorso animabile migliori nelle prossime versioni. –

+0

Se lo risolvi usando l'approccio ad arco rettangoli, per favore postalo qui! – jrturton

+0

Non so se hai lavorato su questo, o visto qualche buona risposta da quando questo post è stato fatto. Sto iniziando a lavorare su una circonferenza generale sull'animazione del poligono e attualmente lo faccio lavorando per un'animazione da circolare a quadrata. Ho postato questo codice come risposta a questa domanda, http://stackoverflow.com/questions/28437014/animating-between-two-bezier-path-shapes/28448397#28448397 – rdelmar

6

ho ricevuto questo feedback dalla lista di quarzo-dev:

David Duncan ha scritto:

Animare il percorso di un livello di forma è garantita solo a lavorare quando si sta animando da like a come . Un rettangolo è una sequenza di linee , mentre un'ellisse è una sequenza di archi (è possibile vedere la sequenza generata utilizzando CGPathApply) e pertanto l'animazione tra di loro non è garantita per apparire molto buona o funzionare bene affatto.

Per fare questo, si deve fondamentalmente per creare un analogo di un rettangolo utilizzando le stesse curve che si usa per creare un'ellisse, ma con i parametri che potrebbero causare il rendering a guardare come un rettangolo. Questo non dovrebbe essere troppo difficile (e ancora una volta, è possibile utilizzare ciò che si ottiene da CGPathApply sul percorso creato con CGPathAddEllipseInRect come guida), ma probabilmente richiederà qualche modifica per avere ragione.