2012-08-24 46 views
1

構建一個由6面組成的立方體:每一面都是一個CALayer,然後每個CALayer作爲子視圖添加到(6)CATransformLayers(以啓用3d轉換)。 這6個CATransformLayers作爲子視圖添加到單個CATransformLayer。當我旋轉這個單一的CATransformLayer將整個立方體保存爲一個包時,一切正常,我將錨點設置爲0,0,並將anchorpointZ設置爲立方體的中間:立方體完美地圍繞其中心旋轉。沿定位點旋轉CATransformLayer

問題: 我想「展開」當前面的4個相鄰邊,這意味着左側,右側,上方和下方的側面向用戶旋轉90 *,但仍然粘在面向用戶。爲此,我例如將當前側上方的anchorpointZ設置爲0,將定位點設置爲(0.5,1),以便定位點基本上是公共邊的中間。

設置立方體:

transformLayer = [CATransformLayer layer]; 
transformLayer.position = CGPointMake([UIScreen mainScreen].bounds.size.width/2,[UIScreen mainScreen].bounds.size.height/2); 

CGRect layerRect = CGRectMake(0.0, 0.0, 150, 150); //frame rect for cube sides 
CGPoint screenCenter = CGPointMake(self.transformLayer.bounds.size.width/2, self.transformLayer.bounds.size.height/2); 

//side1 
side1 = [CALayer layer]; 
side1.borderColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
side1.backgroundColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
side1.borderWidth = 2.0; 
side1.cornerRadius = 30.0; 
side1.frame = layerRect; 
side1.position = screenCenter; 


side1t = [CATransformLayer layer]; 
[side1t addSublayer:side1]; 


//side2 
side2 = [CALayer layer]; 
side2.borderColor = [UIColor colorWithHue:0.25 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
side2.backgroundColor = [UIColor colorWithHue:0.25 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
side2.borderWidth = 2.0; 
side2.cornerRadius = 30.0;  
side2.frame = layerRect; 
side2.position = screenCenter; 
//positioning 
CATransform3D rotation = CATransform3DMakeRotation(M_PI/2, 0.0, 1.0, 0.0); 
CATransform3D translation = CATransform3DMakeTranslation(150/2, 0.0, 150/-2); 
CATransform3D position = CATransform3DConcat(rotation, translation); 
side2.transform = position; 

side2t = [CATransformLayer layer]; 
[side2t addSublayer:side2]; 


//side3 
side3 = [CALayer layer]; 
side3.borderColor = [UIColor colorWithHue:0.0 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
side3.backgroundColor = [UIColor colorWithHue:0.0 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
side3.borderWidth = 2.0; 
side3.cornerRadius = 30.0; 
side3.frame = layerRect; 
side3.position = screenCenter; 
//positioning 
translation = CATransform3DMakeTranslation(0.0, 0.0, -150); //150 
side3.transform = translation; 

side3t = [CATransformLayer layer]; 
[side3t addSublayer:side3]; 


//side4 
side4 = [CALayer layer]; 
side4.borderColor = [UIColor colorWithHue:0.2 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
side4.backgroundColor = [UIColor colorWithHue:0.2 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
side4.borderWidth = 2.0; 
side4.cornerRadius = 30.0; 
side4.frame = layerRect; 
side4.position = screenCenter; 
//positioning 
rotation = CATransform3DMakeRotation(M_PI/2, 0.0, 1.0, 0.0); 
translation = CATransform3DMakeTranslation(150/-2, 0.0, 150/-2); 
side4.transform = CATransform3DConcat(rotation, translation); 

side4t = [CATransformLayer layer]; 
[side4t addSublayer:side4]; 


//side5 
side5 = [CALayer layer]; 
side5.borderColor = [UIColor colorWithHue:0.8 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
side5.backgroundColor = [UIColor colorWithHue:0.8 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
side5.borderWidth = 2.0; 
side5.cornerRadius = 30.0; 
side5.frame = layerRect; 
side5.position = screenCenter; 
//positioning 
rotation = CATransform3DMakeRotation(M_PI/2, 1.0, .0, 0.0); 
translation = CATransform3DMakeTranslation(0.0, 150/-2, 150/-2); 
side5.transform = CATransform3DConcat(rotation, translation); 

side5t = [CATransformLayer layer]; 
[side5t addSublayer:side5]; 


//side6 
side6 = [CALayer layer]; 
side6.borderColor = [UIColor colorWithHue:0.0845 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
side6.backgroundColor = [UIColor colorWithHue:0.0845 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
side6.borderWidth = 2.0; 
side6.cornerRadius = 30.0; 
side6.frame = layerRect; 
side6.position = screenCenter; 
//positioning 
rotation = CATransform3DMakeRotation(M_PI/2, 1.0, .0, 0.0); 
translation = CATransform3DMakeTranslation(0.0, 150/2, 150/-2); 
side6.transform = CATransform3DConcat(rotation, translation); 

side6t = [CATransformLayer layer]; 
[side6t addSublayer:side6]; 


[self.transformLayer addSublayer:side1t]; 
[self.transformLayer addSublayer:side2t]; 
[self.transformLayer addSublayer:side3t]; 
[self.transformLayer addSublayer:side4t]; 
[self.transformLayer addSublayer:side5t]; 
[self.transformLayer addSublayer:side6t]; 

self.transformLayer.anchorPointZ = -150/2; 
[self.layer addSublayer: transformLayer]; 

這部分不工作。旋轉角度(90°)是正確的,但側面會完全錯誤位置,在當前側(z座標)前面的立方體大小的一半,並覆蓋xy空間中的前側的一半,請參閱屏幕截圖

-(void)unfoldUpperSide { 
[CATransaction begin]; 
[CATransaction setAnimationDuration: 3.0]; 
side5t.anchorPoint = CGPointMake(0.5, 0); 
side5t.anchorPointZ = 0; 
side5t.transform = CATransform3DMakeRotation(-M_PI/2, 1, 0, 0); 
[CATransaction commit]; 
} 

after rotation

我被困在這整整一天,希望有人能幫助我..!

回答

0

您不需要爲每個圖層製作一個CATransformLayer,只有一個用於保存所有圖層的CATransformLayer就足夠了,您仍然可以進行3d變換,因爲CATransformLayer變換適用於圖層中所有圖層的錨點。

爲什麼你的各邊的旋轉是關閉的,因爲各方面的anchorPoint是0.5,0.5(也就是它們各自的中心,所以你繞該中心)

你可以去解決這個通過翻譯層的一半大小在兩個期望的方向,雖然它的旋轉儘管有一個輕微的剪裁最初,這裏是下面的osx代碼,只需將NSColor等改爲UIKit對應。

enter image description here

-(void)cubeTest{ 

    float size = 100.0; 

    CATransformLayer *transformLayer = [CATransformLayer layer]; 
    transformLayer.position = CGPointMake(cubeView.bounds.size.width/2,cubeView.bounds.size.height/2); 

    CGRect layerRect = CGRectMake(0.0, 0.0, size, size); //frame rect for cube sides 
    CGPoint screenCenter = CGPointMake(transformLayer.bounds.size.width/2, transformLayer.bounds.size.height/2); 

    //side1 
    CALayer *side1 = [CALayer layer]; 
    side1.borderColor = [NSColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
    side1.backgroundColor = [NSColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
    side1.borderWidth = 2.0; 
    side1.cornerRadius = 30.0; 
    side1.frame = layerRect; 
    side1.position = screenCenter; 
    [transformLayer addSublayer:side1]; 

    //side2 
    CALayer *side2 = [CALayer layer]; 
    side2.borderColor = [NSColor colorWithHue:0.25 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
    side2.backgroundColor = [NSColor colorWithHue:0.25 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
    side2.borderWidth = 2.0; 
    side2.cornerRadius = 30.0; 
    side2.frame = layerRect; 
    side2.position = screenCenter; 
    //positioning 
    CATransform3D rotation = CATransform3DMakeRotation(M_PI/2, 0.0, 1.0, 0.0); 
    CATransform3D translation = CATransform3DMakeTranslation(size/2, 0.0, size/-2); 
    CATransform3D position = CATransform3DConcat(rotation, translation); 
    side2.transform = position; 
    [transformLayer addSublayer:side2]; 

    //side3 
    CALayer *side3 = [CALayer layer]; 
    side3.borderColor = [NSColor colorWithHue:0.0 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
    side3.backgroundColor = [NSColor colorWithHue:0.0 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
    side3.borderWidth = 2.0; 
    side3.cornerRadius = 30.0; 
    side3.frame = layerRect; 
    side3.position = screenCenter; 
    //positioning 
    translation = CATransform3DMakeTranslation(0.0, 0.0, -size); //size 
    side3.transform = translation; 
    [transformLayer addSublayer:side3]; 

    //side4 
    CALayer *side4 = [CALayer layer]; 
    side4.borderColor = [NSColor colorWithHue:0.2 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
    side4.backgroundColor = [NSColor colorWithHue:0.2 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
    side4.borderWidth = 2.0; 
    side4.cornerRadius = 30.0; 
    side4.frame = layerRect; 
    side4.position = screenCenter; 
    //positioning 
    rotation = CATransform3DMakeRotation(M_PI/2, 0.0, 1.0, 0.0); 
    translation = CATransform3DMakeTranslation(size/-2, 0.0, size/-2); 
    side4.transform = CATransform3DConcat(rotation, translation); 
    [transformLayer addSublayer:side4]; 

    //side5 
    CALayer *side5 = [CALayer layer]; 
    side5.borderColor = [NSColor colorWithHue:0.8 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
    side5.backgroundColor = [NSColor colorWithHue:0.8 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
    side5.borderWidth = 2.0; 
    side5.cornerRadius = 30.0; 
    side5.frame = layerRect; 
    side5.position = screenCenter; 
    //positioning 
    rotation = CATransform3DMakeRotation(M_PI/2, 1.0, .0, 0.0); 
    translation = CATransform3DMakeTranslation(0.0, size/-2, size/-2); 
    side5.transform = CATransform3DConcat(rotation, translation); 
    [transformLayer addSublayer:side5]; 

    //side6 
    CALayer *side6 = [CALayer layer]; 
    side6.borderColor = [NSColor colorWithHue:0.0845 saturation:1.0 brightness:1.0 alpha:1.0].CGColor; 
    side6.backgroundColor = [NSColor colorWithHue:0.0845 saturation:1.0 brightness:1.0 alpha:0.8].CGColor; 
    side6.borderWidth = 2.0; 
    side6.cornerRadius = 30.0; 
    side6.frame = layerRect; 
    side6.position = screenCenter; 
    //positioning 
    rotation = CATransform3DMakeRotation(M_PI/2, 1.0, .0, 0.0); 
    translation = CATransform3DMakeTranslation(0.0, size/2, size/-2); 
    side6.transform = CATransform3DConcat(rotation, translation); 
    [transformLayer addSublayer:side6]; 

    transformLayer.anchorPointZ = -size/2; 
    [cubeView setWantsLayer:YES]; 
    [cubeView.layer addSublayer:transformLayer]; 

    //animate 

    CGFloat perspective = -1.0/10000.0; 
    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; 

    CATransform3D transform = CATransform3DIdentity; 
    transform.m34 = perspective; 
    transformAnimation.fromValue = [NSValue valueWithCATransform3D:transform]; 

    transform.m34 = perspective; 
    transform = CATransform3DRotate(transform, DEGREES_TO_RADIANS(90) , 1, 0, 0); 

    transformAnimation.toValue = [NSValue valueWithCATransform3D:transform]; 

    transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    transformAnimation.repeatCount = INFINITY; 
    transformAnimation.duration = 10.0; 
    [transformLayer addAnimation:transformAnimation forKey:@"RotateTheBox"]; 

    [self sideAnimation:side1 transform:CATransform3DTranslate(CATransform3DRotate(side1.transform, DEGREES_TO_RADIANS(90) , 1, 0, 0), 0, size/2, size/2)]; 
    [self sideAnimation:side3 transform:CATransform3DTranslate(CATransform3DRotate(side3.transform, DEGREES_TO_RADIANS(-90) , 1, 0, 0), 0, size/2, -size/2)]; 
    [self sideAnimation:side2 transform:CATransform3DTranslate(CATransform3DRotate(side2.transform, DEGREES_TO_RADIANS(90) , 1, 0, 0), 0, size/2, size/2)]; 
    [self sideAnimation:side4 transform:CATransform3DTranslate(CATransform3DRotate(side4.transform, DEGREES_TO_RADIANS(-90) , 1, 0, 0), 0, size/2, -size/2)]; 
    [self sideAnimation:side6 transform:CATransform3DTranslate(side6.transform, 0, 0, size)];//lower cap 

} 

-(void)sideAnimation:(CALayer*)side transform:(CATransform3D)transform 
{ 
    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    transformAnimation.toValue = [NSValue valueWithCATransform3D:transform]; 
    transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    transformAnimation.repeatCount = INFINITY; 
    transformAnimation.duration = 10.0; 
    [side addAnimation:transformAnimation forKey:@"rotateSide"]; 
}