2012-08-24 45 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"]; 
}