CoreAnimation 變換

CoreAnimation 變換


    CoreAnimation 目錄html

    博客園MakeDown支持不佳,若有須要請進GitHubgit

    本片博客主要內容:github

  • 仿射變換 - CGAffineTransform
  • 3D變換 - CATransform3D

仿射變換 - CGAffineTransform

     CGAffineTransform 是用於二維空間的旋轉,縮放和平移的屬性.首先展現一個簡單的樣例,將圖片順時針旋轉45°⬇️.ide

圖片一
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, M_PI_4);
self.imageView.layer.affineTransform = transform;

    向右平移200⬇️.測試

圖片二
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, 200, 0);
self.imageView.layer.affineTransform = transform;

    先進行旋轉後進行向右平移⬇️.3d

圖片三
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, M_PI_4);
transform = CGAffineTransformTranslate(transform, 200, 0);
self.imageView.layer.affineTransform = transform;

注意:
圖片二與圖片三同是向右平移200,可是經過觀察兩圖的對比不難發現,圖片三的平移距離明顯比圖片二的距離小,與此同時圖片三相對圖片二向下也有必定的平移,這是由於transform的上一次設置會對下一次設置的效果產生影響.code

    混合變換方法 CGAffineTransformConcat ⬇️.orm

圖片四
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, M_PI_4);
CGAffineTransform transformTwo = CGAffineTransformMakeTranslation(-200, 0);
transform = CGAffineTransformConcat(transform, transformTwo);
self.imageView.layer.affineTransform = transform;

3D變換 - CATransform3D

     CATransform3D 支持圖層在三維空間內的操做,x軸旋轉⬇️.htm

圖片五
CATransform3D transform3d = CATransform3DIdentity;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 1, 0, 0);
self.imageView.layer.transform = transform3d;

    y軸旋轉⬇️.對象

圖片六
CATransform3D transform3d = CATransform3DIdentity;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 1, 0);
self.imageView.layer.transform = transform3d;

    z軸旋轉⬇️.

圖片七
CATransform3D transform3d = CATransform3DIdentity;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 0, 1);
self.imageView.layer.transform = transform3d;

    以上三張樣圖只能讓咱們發現與原有圖片有所不一樣,可是不能明顯的區別出差異在哪裏,此時咱們能夠設置m34來實現透視投影的效果.

    透視投影 - x軸旋轉⬇️.

圖片八
CATransform3D transform3d = CATransform3DIdentity;
transform3d.m34 = - 1.0 / 500.0;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 1, 0, 0);
self.imageView.layer.transform = transform3d;

    透視投影 - y軸旋轉⬇️.

圖片九
CATransform3D transform3d = CATransform3DIdentity;
transform3d.m34 = - 1.0 / 500.0;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 1, 0);
self.imageView.layer.transform = transform3d;

    透視投影 - z軸旋轉⬇️.

圖片十
CATransform3D transform3d = CATransform3DIdentity;
transform3d.m34 = - 1.0 / 500.0;
transform3d = CATransform3DRotate(transform3d, M_PI_4, 0, 0, 1);
self.imageView.layer.transform = transform3d;

    滅點 : 當在透視角度繪圖的時候,遠離相機視角的物體將會變小變遠,當遠離到一個極限距離,它們就縮成了一個點,所以全部的物體最後都匯聚消失在同一個點.在現實中,這個點一般是視圖的中心,因而爲了在應用中建立擬真效果的透視,這個點應該聚在屏幕中點,或者至少是包含全部3D對象的視圖中點.

圖片十一

    瞭解滅點後便會遇到一個問題,一般狀態下手機屏幕所顯示的內容存在着不少圖層,那麼咱們要一一設置他們的滅點嗎?顯然這種方法是不可行的覺得它十分不方便.封裝?或許是一個錯的方法,可是那樣會帶來一個嚴重的後果就是不靈活,那麼應該怎樣去作?sublayerTransform是最完美的選擇,它也是CATransform3D類型,但和對一個圖層的變換不一樣,它影響到全部的子圖層.這意味着你能夠一次性對包含這些圖層的容器作變換,因而全部的子圖層都自動繼承了這個變換方法.

    作一個簡單的測試.

圖片十二
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D transform = CATransform3DIdentity;
CATransform3D twoTransform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
twoTransform = CATransform3DRotate(twoTransform, -M_PI_4, 0, 1, 0);
self.imageView.layer.transform = transform;
self.imageTwoView.layer.transform = twoTransform;

     背面 : 設置圖層翻轉180°.

圖片十三
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D transform = CATransform3DIdentity;
CATransform3D twoTransform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
twoTransform = CATransform3DRotate(twoTransform, -M_PI, 0, 1, 0);
self.imageView.layer.transform = transform;
self.imageTwoView.layer.transform = twoTransform;

    背面的繪製是很浪費cpu以及gpu的,所以咱們更多的時候是須要禁止繪製圖層背面的.

圖片十四
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D transform = CATransform3DIdentity;
CATransform3D twoTransform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
twoTransform = CATransform3DRotate(twoTransform, -M_PI, 0, 1, 0);
self.imageView.layer.transform = transform;
self.imageTwoView.layer.transform = twoTransform;
self.imageTwoView.layer.doubleSided = NO;// 不繪製背面

    最後來討論一下,子圖的相對父圖層的逆變換是否會恢復原狀.z軸?

圖片十五
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D outer = CATransform3DIdentity;
CATransform3D inter = CATransform3DIdentity;
outer = CATransform3DRotate(outer, M_PI_4, 0, 0, 1);
inter = CATransform3DRotate(inter, -M_PI_4, 0, 0, 1);
self.outer.layer.transform = outer;
self.inter.layer.transform = inter;

    z軸狀態下是能夠恢復原狀的.y軸?

圖片十六
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = - 1.0 / 500;
self.view.layer.sublayerTransform = perspective;
CATransform3D outer = CATransform3DIdentity;
CATransform3D inter = CATransform3DIdentity;
outer = CATransform3DRotate(outer, M_PI_4, 0, 1, 0);
inter = CATransform3DRotate(inter, -M_PI_4, 0, 1, 0);
self.outer.layer.transform = outer;
self.inter.layer.transform = inter;

y軸並非,這是因爲儘管Core Animation圖層存在於3D空間以內,但它們並不都存在同一個3D空間.每一個圖層的3D場景實際上是扁平化的,當你從正面觀察一個圖層,看到的實際上由子圖層建立的想象出來的3D場景,但當你傾斜這個圖層,你會發現實際上這個3D場景僅僅是被繪製在圖層的表面.

相關文章
相關標籤/搜索