2012-05-08 65 views
5

我使用下面的函數來一個脈衝效果應用到視圖從CATransform3D到CGAffineTransform

- (void)pulse { 

    CATransform3D trasform = CATransform3DScale(self.layer.transform, 1.15, 1.15, 1); 
    trasform = CATransform3DRotate(trasform, angle, 0, 0, 0); 

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    animation.toValue = [NSValue valueWithCATransform3D:trasform]; 
    animation.autoreverses = YES; 
    animation.duration = 0.3; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.repeatCount = 2; 
    [self.layer addAnimation:animation forKey:@"pulseAnimation"]; 

} 

我想獲得使用CGAffineTransform self.transform代替CATransform3D自我相同的結果。 layer.transform。這可能嗎?

+1

出於好奇,爲什麼會如果您已經從前者獲得了您期望的結果,您是否在意將CATransform3D應用於圖層還是將CGAffineTransform應用於視圖? –

+0

,因爲self.layer.transform的初始值與self.transform不同,不是嗎? – Abramodj

+0

我的意思是,在採用脈衝方法之前,我對視圖應用了一些仿射變換,但是我沒有觸及圖層,所以我猜想變換是那裏的標識 – Abramodj

回答

2

當然。如果您在Xcode文檔中搜索CGAffineTransform,您會發現一章標題爲「CGAffineTransform Reference」。在這一章中有一節叫做「函數」。它包含等同於CATransform3DScale(CGAffineTransformScale)和CATransform3DRotate(CGAffineTransformRotate)的函數。

請注意,您對CATransform3DRotate的調用沒有任何意義。您需要圍繞一個軸旋轉,並且所有3個軸都傳遞0。典型地,您想要使用CATransform3DRotate(trasform,angle,0,0,1.0)圍繞Z軸旋轉。引用文檔:

如果矢量長度爲零,則行爲未定義。

+0

但是,(從我的問題可能不清楚)是如何有相當於[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; – Abramodj

+1

你真的不清楚。我猜測CGAffineTransform用於視圖,而CATransform3D用於你想知道如何執行基於視圖的動畫的圖層,這些動畫指定了不同的定時功能。爲此,您要使用animateWithDuration:delay:options:動畫:完成: UIView類方法。 options參數包括像UIViewAnimationOptionCurveEaseInOut,UIViewAnimationOptionCurveLinear等值。只需指定所需的選項,然後更改動畫塊中的變換。 –

7

可能會將CATransform3D轉換爲CGAffineTransform,但您將失去一些功能。我發現將圖層及其祖先的聚合變換轉換爲CGAffineTransform是非常有用的,所以我可以使用Core Graphics進行渲染。約束條件是:

  • 你的輸入將在XY平面內被視爲平面
  • 輸出將在XY平面內太
  • .m34
  • 視角/縮短將被中和被當作平坦

如果這聽起來您的用途確定:

// m13, m23, m33, m43 are not important since the destination is a flat XY plane. 
    // m31, m32 are not important since they would multiply with z = 0. 
    // m34 is zeroed here, so that neutralizes foreshortening. We can't avoid that. 
    // m44 is implicitly 1 as CGAffineTransform's m33. 
    CATransform3D fullTransform = <your 3D transform> 
    CGAffineTransform affine = CGAffineTransformMake(fullTransform.m11, fullTransform.m12, fullTransform.m21, fullTransform.m22, fullTransform.m41, fullTransform.m42); 

呦你會首先完成3D轉換的所有工作,比如說從你的超級層級連接起來,然後最終將聚合CATransform3D轉換爲CGAffineTransform。鑑於圖層是平坦的開始並呈現在平坦的目標上,我發現這非常合適,因爲我的3D旋轉變成2D剪刀。我也發現犧牲透視是可以接受的。這是沒有辦法的,因爲仿射變換必須保留平行線。

要渲染使用核芯顯卡,例如,你可能會連接變換的3D變換層(!尊重錨點),然後將轉換爲仿射,最後:

CGContextSaveGState(context); 
    CGContextConcatCTM(context, affine); 
    [layer renderInContext:context]; 
    CGContextRestoreGState(context); 
+0

謝謝,這是正確的答案。不幸的是,它是應該包含在Cocoa API中的那些函數之一,但並不是因爲它不是一個「完整的」轉換(並且永遠不會)。 – SG1

+0

我很高興我找到了這個。我一直在尋找「3d到2d矩陣」一週,剛剛發現了一堆數學亂碼。 – xtravar

+0

你到底是怎麼想出來的?這太棒了!我向你的數學天才屈服。 – jjxtra