OpenGL ES 案例03:CoreAnimation繪制立方體+旋轉(zhuǎn)

OpenGL + OpenGL ES +Metal 系列文章匯總

在不會OpenGL ES的情況下,如何利用CoreAnimation實(shí)現(xiàn)一個立方體,并旋轉(zhuǎn),整體效果如下


OpenGL_ES_03_效果圖

整體實(shí)現(xiàn)的思路如下


整體實(shí)現(xiàn)思路

主要分為兩部分

  • ViewDidLoad函數(shù):初始化工作
  • update更新:定時器實(shí)現(xiàn)旋轉(zhuǎn)

ViewDidLoad函數(shù)

初始化工作包含兩部分:

  • addFaces:添加6個面,通過變換組合成立方體
  • addCADisplayLink:添加定時器,并放入runloop

addFaces函數(shù)
這部分主要是將6個面作相應(yīng)的變換添加到容器中

6個面的變換

  • OC版本
//添加面
- (void)addFaces{
    self.faces = @[_view0, _view1, _view2, _view3, _view4, _view5];
    
//    主view
    CATransform3D perspective = CATransform3DIdentity;
//    核心動畫設(shè)置透視投影
    perspective.m34 = -1.0 / 500.0;
//    圍繞x,y分別旋轉(zhuǎn),M_PI_4 = π/4,π=180°
//      x:順時針旋轉(zhuǎn)45°,y:順時針旋轉(zhuǎn)45°
    perspective = CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);
    perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);
    self.containerView.layer.sublayerTransform = perspective;
    
    //添加face1
//    z軸平移100
//    (除了第一個視圖外,其余的視圖都是基于第一個視圖的位置進(jìn)行平移+旋轉(zhuǎn)的)
    CATransform3D transform = CATransform3DMakeTranslation(0, 0, 100);
    [self addFace:0 withTransform:transform];
    
////    添加face2 --平移y+旋轉(zhuǎn)y
    transform = CATransform3DMakeTranslation(100, 0, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
    [self addFace:1 withTransform:transform];
//
//     添加face3 -- 平移y+旋轉(zhuǎn)x
    transform = CATransform3DMakeTranslation(0, -100, 0);
    transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
//    [self addFace:2 withTransform:transform];
    
//    添加face4 -- 平移y+旋轉(zhuǎn)x
    transform = CATransform3DMakeTranslation(0, 100, 0);
    transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
    [self addFace:3 withTransform:transform];

//    添加face5 -- 平移+旋轉(zhuǎn)
    transform = CATransform3DMakeTranslation(-100, 0, 0);
    transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
    [self addFace:4 withTransform:transform];

//    添加face6 -- 平移z+旋轉(zhuǎn)y
    transform = CATransform3DMakeTranslation(0, 0, -100);
    transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
    [self addFace:5 withTransform:transform];
}

- (void)addFace: (NSInteger)index withTransform: (CATransform3D)transform
{
//    獲取face視圖,并將其加入容器中
    UIView *face = self.faces[index];
    [self.containerView addSubview:face];
    
//    將face視圖放在容器的中心
    CGSize containerSize = self.containerView.bounds.size;
    face.center = CGPointMake(containerSize.width/2.0, containerSize.height/2.0);
    
//    添加tansform,tansform就是一個矩陣
    face.layer.transform = transform;
}
  • Swift版本
fileprivate func addFaces(){
        faces = [view0, view1, view2, view3, view4, view5]
        
//        父view的layer圖層
        var perspective: CATransform3D = CATransform3DIdentity
        perspective.m34 = -1.0 / 500.0
        perspective = CATransform3DRotate(perspective, -.pi/4, 1, 0, 0)
        perspective = CATransform3DRotate(perspective, -.pi/4, 0, 1, 0)
        self.containerView.layer.sublayerTransform = perspective
        
//        添加face1
        var transform = CATransform3DMakeTranslation(0, 0, 100)
        self.addFaceWithTransform(0, transform)
        
//        添加face2
        transform = CATransform3DMakeTranslation(100, 0, 0)
        transform = CATransform3DRotate(transform, .pi/2, 0, 1, 0)
        self.addFaceWithTransform(1, transform)
        
//        添加face3
        transform = CATransform3DMakeTranslation(0, -100, 0)
//        transform = CATransform3DRotate(transform, .pi/2, 1, 0, 0)
//        self.addFaceWithTransform(2, transform)
//
//        添加face4
        transform = CATransform3DMakeTranslation(0, 100, 0)
        transform = CATransform3DRotate(transform, -.pi/2, 1, 0, 0)
        self.addFaceWithTransform(3, transform)
//
//        添加face5
        transform = CATransform3DMakeTranslation(-100, 0, 0)
//        transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0)
        self.addFaceWithTransform(4, transform)
//
////        添加face6
//        transform = CATransform3DMakeTranslation(0, 0, -100)
//        transform = CATransform3DRotate(transform, .pi, 0, 1, 0)
//        self.addFaceWithTransform(5, transform)

    }
    
    private func addFaceWithTransform(_ index: Int, _ transform: CATransform3D){
//        獲取face,并加入容器中
        let face = self.faces[index]
        self.containerView.addSubview(face)
        
//        將face視圖放入容器的中心
        let containerSize = self.containerView.bounds.size
        face.center = CGPoint(x: containerSize.width/2, y: containerSize.height/2)
        
//        添加transform
        face.layer.transform = transform
        
    }

addCADisplayLink函數(shù)
這部分主要初始化定時器,并將定時器加入runloop循環(huán)中

  • OC版本
//添加定時器
- (void)addCADisplayLink{
    self.angle = 0;
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
  • Swift版本
fileprivate func addCADisplayLink(){
    self.displayLink.add(to: RunLoop.main, forMode: .common)
   }

update更新

主要是計算旋轉(zhuǎn)度數(shù),并將容器的子layer圍繞任意方向旋轉(zhuǎn)

  • OC版本
- (void)update{
    
//    計算旋轉(zhuǎn)度數(shù)
    self.angle = (self.angle + 5) % 360;
//    將度數(shù)轉(zhuǎn)化為弧度
    float deg = self.angle * (M_PI / 180);
    CATransform3D temp = CATransform3DIdentity;
//    圍繞(0.3, 1, 0.7)方向旋轉(zhuǎn)
    temp = CATransform3DRotate(temp, deg, 0.3, 1, 0.7);
//    旋轉(zhuǎn)容器的子layer
    self.containerView.layer.sublayerTransform = temp;
}
  • Swift版本
@objc fileprivate func update(){
    self.angle = (self.angle+5).truncatingRemainder(dividingBy: 360)
    let deg = self.angle * (.pi/180)
    var temp = CATransform3DIdentity
    temp = CATransform3DRotate(temp, CGFloat(deg), 0.3, 1, 0.7)
    
    self.containerView.layer.sublayerTransform = temp
   }

完整的代碼見github - 09_CoreAnimation_立方體+旋轉(zhuǎn)OC、09_CoreAnimation立方體+旋轉(zhuǎn)_Swift,分別提供了OC和Swift版本

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容