Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change perspective angle from right to left, in CATransformLayer iOS using CATransform3D

I am trying to draw one 3d block!

Using 2 layers and it is looking good in 3d for right side. see the attached image.

enter image description here

When I am trying to reuse same code for minor modification for left side! it's looking weird. See the attached image bellow,

enter image description here

I feel we can improve if we can change perspective angle, but don't know how to achieve that.

using transform.m34 for perspective. any help would be greatly appreciated.

Here is source code I am using.

// left Bar
/*{
    CGFloat aViewWidth = 1000;

    CAGradientLayer *blueLayer = [CAGradientLayer layer];
    blueLayer.anchorPoint = P(0,0.5);

    blueLayer.colors = @[
                        (id)aBarColor.CGColor,
                        (id)[UIColor blackColor].CGColor
                        ];
    blueLayer.startPoint = CGPointMake(0.0, 0.5);
    blueLayer.endPoint = CGPointMake(1.5, 0.5);

    blueLayer.frame = CGRectMake(125, 0, aViewWidth, 250);
    blueLayer.transform = CATransform3DRotate(CATransform3DIdentity, M_PI_2, 0.0f, 1.0f, 0.0f);


    [baseLayer addSublayer:blueLayer];

    CAGradientLayer *redLayer = [CAGradientLayer layer];

    redLayer.colors = @[
                        (id)[UIColor whiteColor].CGColor,
                        (id)aBarColor.CGColor
                        ];
    redLayer.startPoint = CGPointMake(-10.0, 0.5);
    redLayer.endPoint = CGPointMake(1.0, 0.5);
    redLayer.anchorPoint = P(0.5,0.5);

    redLayer.frame = CGRectMake(0, 0, 125, 250);

    [baseLayer addSublayer:redLayer];

    CGFloat perspective = -1000; //This relates to the m34 perspective matrix.

    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform.m34 = 1.0 / perspective;
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, degreesToRadians(-10.0) , 0.0f, 1.0f, 0.0f);

    baseLayer.sublayerTransform = rotationAndPerspectiveTransform;

    [self.view.layer addSublayer:baseLayer];

    return;

    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: @"sublayerTransform"];
    transformAnimation.fillMode = kCAFillModeForwards;
    transformAnimation.removedOnCompletion = NO;
    {

        CGFloat w0 = 0;
        CGFloat w1 = aViewWidth;

        w0 = w0 * sin(degreesToRadians(10)) - perspective * cos(degreesToRadians(10));
        w1 = w1 * sin(degreesToRadians(10)) - perspective * cos(degreesToRadians(10));

        CGFloat newWidth = w1 - w0;
        newWidth = newWidth * 1.2;

        CATransform3D newTransform = CATransform3DIdentity;
        newTransform.m34 = 1.0 / perspective;
        newTransform = CATransform3DRotate(newTransform, degreesToRadians(-10) , 0.0f, 1.0f, 0.0f);
        newTransform = CATransform3DScale(newTransform, 1.0f, 1.0f, 1.0f);
        newTransform = CATransform3DTranslate(newTransform, newWidth, 0.0f, 0.0f);

        transformAnimation.toValue = [NSValue valueWithCATransform3D:newTransform];
        transformAnimation.duration = 10.0;
    }
    [baseLayer addAnimation:transformAnimation forKey:@"transform"];
}*/

// Right Bar
{
    CGFloat aViewWidth = 1000;

    CAGradientLayer *redLayer = [CAGradientLayer layer];

    redLayer.colors = @[
                        (id)aBarColor.CGColor,
                        (id)[UIColor blackColor].CGColor
                    ];
    redLayer.startPoint = CGPointMake(0.0, 0.5);
    redLayer.endPoint = CGPointMake(1.5, 0.5);

    redLayer.frame = CGRectMake(0, 0, aViewWidth, 250);
    redLayer.position = CGPointMake(0,0);
    redLayer.anchorPoint = CGPointMake(0, 0.5); // right
    redLayer.transform = CATransform3DRotate(CATransform3DIdentity, M_PI_2,0.0f, 1.0f, 0.0f);

    [baseLayer addSublayer:redLayer];

    CAGradientLayer *blueLayer = [CAGradientLayer layer];

    blueLayer.colors = @[
                        (id)[UIColor whiteColor].CGColor,
                        (id)aBarColor.CGColor
                        ];
    blueLayer.startPoint = CGPointMake(-10.0, 0.5);
    blueLayer.endPoint = CGPointMake(1.0, 0.5);

    blueLayer.frame = CGRectMake(0, 0, 125, 250);
    blueLayer.anchorPoint = CGPointMake(0, 0.5); // right
    blueLayer.position = CGPointMake(0,0);

    [baseLayer addSublayer:blueLayer];

    CGFloat perspective = -1 * aViewWidth; //This relates to the m34 perspective matrix.

    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform.m34 = 1.0 / perspective;
    rotationAndPerspectiveTransform = CATransform3DScale(rotationAndPerspectiveTransform, 0.1f, 0.1f, 0.1f);

    baseLayer.sublayerTransform = rotationAndPerspectiveTransform;

    [self.view.layer addSublayer:baseLayer];

    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: @"sublayerTransform"];
    transformAnimation.fillMode = kCAFillModeForwards;
    transformAnimation.removedOnCompletion = NO;
    {

        CGFloat w0 = 0;
        CGFloat w1 = aViewWidth;

        w0 = w0 * sin(degreesToRadians(10)) - perspective * cos(degreesToRadians(10));
        w1 = w1 * sin(degreesToRadians(10)) - perspective * cos(degreesToRadians(10));

        CGFloat newWidth = w1 - w0;
        newWidth = newWidth * 1.225;

        CATransform3D newTransform = CATransform3DIdentity;
        newTransform.m34 = 1.0 / perspective;
        newTransform = CATransform3DRotate(newTransform, degreesToRadians(10) , 0.0f, 1.0f, 0.0f);
        newTransform = CATransform3DScale(newTransform, 1.0f, 1.0f, 1.0f);
        newTransform = CATransform3DTranslate(newTransform, newWidth, 0.0f, 0.0f);

        transformAnimation.toValue = [NSValue valueWithCATransform3D:newTransform];
        transformAnimation.duration = 10.0;
    }
    [baseLayer addAnimation:transformAnimation forKey:@"transform"];
}
like image 295
Milan V. Avatar asked Jun 13 '16 08:06

Milan V.


1 Answers

here is the working code :

// left Bar
{
 CGFloat aViewWidth = 1000;

 CAGradientLayer *blueLayer = [CAGradientLayer layer];
 blueLayer.anchorPoint = P(0,0.5);

 blueLayer.colors = @[
 (id)aBarColor.CGColor,
 (id)[UIColor blackColor].CGColor
 ];
 blueLayer.startPoint = CGPointMake(0.0, 0.5);
 blueLayer.endPoint = CGPointMake(1.5, 0.5);

 blueLayer.frame = CGRectMake(125, 0, aViewWidth, 250);
 blueLayer.transform = CATransform3DRotate(CATransform3DIdentity, M_PI_2, 0.0f, 1.0f, 0.0f);


 [baseLayer addSublayer:blueLayer];

 CAGradientLayer *redLayer = [CAGradientLayer layer];

 redLayer.colors = @[
 (id)[UIColor whiteColor].CGColor,
 (id)aBarColor.CGColor
 ];
 redLayer.startPoint = CGPointMake(-10.0, 0.5);
 redLayer.endPoint = CGPointMake(1.0, 0.5);

redLayer.anchorPoint = P(1.0,0.5);

 redLayer.frame = CGRectMake(0, 0, 125, 250);

 [baseLayer addSublayer:redLayer];

 CGFloat perspective = -1000; //This relates to the m34 perspective matrix.
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / perspective;
rotationAndPerspectiveTransform = CATransform3DScale(rotationAndPerspectiveTransform, 0.1f, 0.1f, 0.1f);
 baseLayer.sublayerTransform = rotationAndPerspectiveTransform;

 [self.view.layer addSublayer:baseLayer];

 CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: @"sublayerTransform"];
 transformAnimation.fillMode = kCAFillModeForwards;
 transformAnimation.removedOnCompletion = NO;
 {

 CGFloat w0 = 0;
 CGFloat w1 = aViewWidth;
 w0 = w0 * sin(degreesToRadians(-10)) - perspective * cos(degreesToRadians(-10));
 w1 = w1 * sin(degreesToRadians(-10)) - perspective * cos(degreesToRadians(-10));
 CGFloat newWidth = w1 - w0;
 newWidth = newWidth * 1.2;

 CATransform3D newTransform = CATransform3DIdentity;
 newTransform.m34 = 1.0 / perspective;
 newTransform = CATransform3DRotate(newTransform, degreesToRadians(-10) , 0.0f, 1.0f, 0.0f);
 newTransform = CATransform3DScale(newTransform, 1.0f, 1.0f, 1.0f);
 newTransform = CATransform3DTranslate(newTransform, newWidth, 0.0f, 0.0f);

 transformAnimation.toValue = [NSValue valueWithCATransform3D:newTransform];
 transformAnimation.duration = 10.0;
 }
 [baseLayer addAnimation:transformAnimation forKey:@"transform"];
 }

Change your redLayer ancherPoint to (1.0, 0.5) and use negative value of angle in w0 and w1. newWidth (which is used for translation) variable should be negative value for left side animation and positive value for right side animation.

like image 91
Shivani Gor Avatar answered Nov 13 '22 12:11

Shivani Gor