2012-02-13 7 views
5

Uygulamamda yavaş hareket efekti uygulamak için çalışıyorum, tıpkı Shift tuşuna basarsanız Mac OS'un grafiksel etkilerini nasıl yavaşlatabiliyorsunuz.Animasyonları CoreAnimation ile yavaşlatın ve hızlandırın

başvurum CoreAnimation kullanır, bu yüzden büyütecek bir şey yok olması gerektiğini düşündüm: Ben gidip burada biraz daha yavaş değere (gibi 0.1) için speed ayarlayabilir ve geri ben bittim kez 1 olarak ayarlayın ve.

Maalesef bu doğru yol değil gibi görünüyor. Yavaşlama gayet iyi çalışıyor, ancak normal hıza geri dönmek istediğimde, hız tüm saatte 1 sanki devam ediyor. Bu temel olarak, Shift'i yeterince uzun tuttuğumda, yayınladığım anda animasyonun anında tamamlandığı anlamına gelir.

Animasyonun nasıl duraklatılacağını ve devam ettirileceğini açıklayan bir Teknik QA sayfası buldum, ancak animasyonu tamamen duraklatmayla ilgili değilse, doğru bir şekilde görünmüyorum. Zaman eğrinde kesinlikle çok iyi değilim.

Yavaşlama ve CoreAnimation ile bir animasyonu devam ettirmenin doğru yolu ne olurdu?

Ben basit UIView ile bir test kurmak ...

-(void)flagsChanged:(NSEvent *)theEvent 
{ 
    CALayer* layer = self.layer; 
    [CATransaction begin]; 
    CATransaction.disableActions = YES; 
    layer.speed = (theEvent.modifierFlags & NSShiftKeyMask) ? 0.1 : 1; 
    [CATransaction commit]; 
} 
+1

Tipik vardiya tutan ... değil AutoReverse animasyonlarla, sadece 1 yönde çalışır vardiya düzenlenen ve bunun salıverme anında yok iken sadece başladı animasyonlar için geçerlidir animasyonu hızlandır. Bu genellikle animasyonun süresinin, animasyonun oluşturulduğu anda vardiya tutulup tutulmadığına bağlı olarak yapılmasıyla gerçekleştirilebilir. –

+1

@Kevin Ballard, biliyorum; ama bunun serin bir etki yaratması bir yana, herhangi bir noktada yavaşlatmak için içeriğimde de muhtemelen _useful_ olacaktır. – zneak

+0

Sanırım hızı değiştirdiğinizde, bir zaman ofseti hesaplamak zorunda kalacaksınız, böylece oldspeed * time == newspeed * time + offset –

cevap

4

Tricky sorun:

İşte kullanışlı kod. Katmanından mevcut noktadan bir hedef noktasına kadar bir animasyon başlatıyorum.

Çekirdek animasyonunu yavaşlatmak için aslında yeni bir animasyon oluşturmalı ve değiştirmeliydim (çünkü mevcut animasyonu değiştiremezsiniz).

Geçerli animasyon boyunca ilerlemenin ne kadar sürdüğünü anlamak özellikle önemlidir. Bu, beginTime'a, currentTime'a erişerek, geçen süreyi hesaplayarak ve ardından yeni animasyonun ne kadar süre kalacağını anlayarak yapılır.

- (void)initiate { 
    if(!initiated) { 
     [CATransaction begin]; 
     [CATransaction disableActions]; 
     [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]]; 
     CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"position"]; 
     ba.duration = 10.0f; 
     ba.fromValue = [NSValue valueWithCGPoint:view.layer.position]; 
     ba.toValue = [NSValue valueWithCGPoint:CGPointMake(384, 512)]; 
     [view.layer addAnimation:ba forKey:@"animatePosition"]; 
     [CATransaction commit]; 
     initiated = YES; 
    } 
} 

- (void)slow { 
    [CATransaction begin]; 
    CABasicAnimation *old = (CABasicAnimation *)[view.layer animationForKey:@"animatePosition"]; 
    CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"position"]; 
    CFTimeInterval animationBegin = old.beginTime; 
    CFTimeInterval currentTime = CACurrentMediaTime(); 
    CFTimeInterval elapsed = currentTime - animationBegin; 
    ba.duration = [[old valueForKey:@"duration"] floatValue] - elapsed; 
    ba.duration = [[old valueForKey:@"duration"] floatValue]; 
    ba.autoreverses = [[old valueForKey:@"autoreverses"] boolValue]; 
    ba.repeatCount = [[old valueForKey:@"repeatCount"] floatValue]; 
    ba.fromValue = [NSValue valueWithCGPoint:((CALayer *)[view.layer presentationLayer]).position]; 
    ba.toValue = [old valueForKey:@"toValue"]; 
    ba.speed = 0.1; 
    [view.layer addAnimation:ba forKey:@"animatePosition"]; 
    [CATransaction commit]; 
} 

- (void)normal { 
    [CATransaction begin]; 
    CABasicAnimation *old = (CABasicAnimation *)[view.layer animationForKey:@"animatePosition"]; 
    CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@"position"]; 
    CFTimeInterval animationBegin = old.beginTime; 
    CFTimeInterval currentTime = CACurrentMediaTime(); 
    CFTimeInterval elapsed = currentTime - animationBegin; 
    ba.duration = [[old valueForKey:@"duration"] floatValue] - elapsed; 
    ba.autoreverses = [[old valueForKey:@"autoreverses"] boolValue]; 
    ba.repeatCount = [[old valueForKey:@"repeatCount"] floatValue]; 
    ba.fromValue = [NSValue valueWithCGPoint:((CALayer *)[view.layer presentationLayer]).position]; 
    ba.toValue = [old valueForKey:@"toValue"]; 
    ba.speed = 1; 
    [view.layer addAnimation:ba forKey:@"animatePosition"]; 
    [CATransaction commit]; 
} 

Not: Yukarıdaki kod

+1

Kodumu gönderdim. – zneak

İlgili konular