How to animate CATransform3D with multiple transforms? - ios

Basically, I'm rotating a layer about a point as :
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -500;
transform = CATransform3DTranslate(transform, rotationPoint.x-center.x, rotationPoint.y-center.y, 0.0);
transform = CATransform3DRotate(transform, (rotationAngleFor) * M_PI / 180.0f, 0.0, 1.0, 0);
transform = CATransform3DTranslate(transform, center.x-rotationPoint.x, center.y-rotationPoint.y, 0.0);
I also create a layer, add it to a bigger layer and then apply the transform to it:
[self.layer addSublayer:myLayer];
myLayer.transform = transform;
How to animate this?
Note- Putting this in a UIView animation block doesn't work.

Edit: As #DuncanC pointed out my description did not match the actual code.
You can use a CABasicAnimation that is added to the layer as follows.
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: #"transform"];
<here goes your definition of transform>
transformAnimation.toValue = [NSValue valueWithCATransform3D:newTransform];
transformAnimation.duration = 10;
[self.layer addAnimation:transformAnimation forKey:#"transform"];
This animation performs a continuous change of the transform property of the layer from the original value of the transform property of the layer to the newTransform transformation. The change takes 10 seconds.

Related

How to do transform CALayer without changing it's shape

I've a rectangle shaped CALayer, which I've scaled as below:
CATransform3D currentTransform = layer.transform;
CATransform3D newTransform = CATransform3DScale(currentTransform, xscale, yscale, 1.0);
[layer setTransform:newTransform];
After applying CATransform3DScale, transformed CALayer is also a rectangle.
But when I apply CATransform3DRotate, transformed CALayer becomes a rhombus.
CATransform3D currentTransform = layer.transform;
CATransform3D newTransform = CATransform3DRotate(currentTransform, rotation, 0.0, 0.0, 1.0);
[layer setTransform:newTransform];
How can I get the rectangle shape after applying rotate transform?
I didn't change anchor point of the layer. Sometimes I need to change the position of the layer.

How to rotate UIView in 3D?

I have very simple task, but I can't understand CATransform3DRotate.
I have 3 UIImageView with equal height and width, and I need set some transformation for left and right items for next result:
https://dl.dropboxusercontent.com/u/15196617/result.png
Original screen:
https://dl.dropboxusercontent.com/u/15196617/original.png
My sources:
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.f / self.prevItemImageView.bounds.size.width;
transform = CATransform3DRotate(transform, (CGFloat) -(M_PI / 3.f), 0, 1.f, 0);
self.prevItemImageView.layer.anchorPoint = CGPointMake(1.f, 0.5f);
self.prevItemImageView.layer.transform = transform;
transform = CATransform3DIdentity;
transform.m34 = -1.f / self.nextItemImageView.bounds.size.width;
transform = CATransform3DRotate(transform, (CGFloat) (M_PI / 3.f), 0, 0.5f, 0);
self.nextItemImageView.layer.anchorPoint = CGPointMake(0.f, 0.5f);
self.nextItemImageView.layer.transform = transform;
It is not work.
What you want to do is apply the transform with altered .m34 component to the superlayer of your image views, as a sublayerTransform. That is what gives transforms on the image views the appearance of depth.
This image started life as a square. But it looks rotated in 3D because its superlayer has a sublayerTransform:

CATransform3DMakeRotation how to stop going off the screen

I am rotating a layer using CATransform3DMakeRotation. I am having two issues:
a) Sometimes going out of the screen
b) Sometimes positioning on top of other layer.
int randrotate=arc4random()%3+1;
CATransform3D trans5=CATransform3DMakeRotation(M_PI*randrotate , 1.0, 0.0, 0.0);
randrotate=arc4random()%4+1;
CATransform3D trans6=CATransform3DRotate(trans5,M_PI*randrotate, 0.0, 0.0, 1.0);
randrotate=arc4random()%3+1;
CATransform3D trans7=CATransform3DRotate(trans5,M_PI_2*randrotate, 0.0, 1.0, 0.0);
CATransform3D trans=CATransform3DRotate(trans7,M_PI*45/180, 0.0, 1.0, 0.0);
CATransform3D trans8=CATransform3DRotate(trans,DEGREES_TO_RADIANS(-45), 1.0, 0.0, 0.0);
CABasicAnimation *ganimation = [CABasicAnimation animationWithKeyPath: #"transform"];
ganimation.beginTime=CACurrentMediaTime();
ganimation.toValue = [NSValue valueWithCATransform3D: trans];
ganimation.duration = 0;
ganimation.cumulative = NO;
ganimation.repeatCount = 0;
ganimation.removedOnCompletion = NO;
ganimation.fillMode = kCAFillModeForwards;
ganimation.delegate=self;
[correctbase addAnimation:ganimation forKey:#"green"];
after animation correct base is changing his position.
Now after animation, I want to put the correctbase in it's original position back, correctbase is a CATransformLayer.
if i try to access presentation layer it's always nil
CATransformLayer *layer=(CATransformLayer*)correctbase.presentationLayer;
Can someone help me?
Thanks in advance.

CAShapeLayer path animation -- shrinking a circle

I'm trying to shrink a circular CAShapeLayer but using the key path 'path' does not seem to be working.
CGPathRef startPath = [UIBezierPath bezierPathWithOvalInRect:startRect].CGPath;
CGPathRef endPath = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(startRect, 15, 15)].CGPath;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"path"];
animation.duration = 1.0;
animation.fromValue = (__bridge id)startPath;
animation.toValue = (__bridge id)endPath;
animation.autoreverses = YES;
animation.repeatCount = CGFLOAT_MAX;
animation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.6 :0.3 :0.8 :0.45];
//circleLayer is a CAShapeLayer
[self.circleLayer addAnimation:animation forKey:#"pathAnimation"];
I think i must be misunderstanding about how a path animation works because pretty much identical code seems to work fine if i am try to animate, say, the opacity or the transform.
Any ideas?
I recently had the same question and ended up solving it by creating the circle, then animating the scale CGAffineTransform. In the view whose layer is the circle, I simply used
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformScale(transform, scaleX, scaleY);
[UIView animateWithDuration: 0.5 animations: ^{
self.transform = transform;
}];
Hope this helps!

My CALayer transform holds after animation, but the perspective disappears

I have the following code that rotates a CALayer by -45degrees on the Y axis:
#define D2R(x) (x * (M_PI/180.0))
- (void) swipe:(UISwipeGestureRecognizer *)recognizer
{
CATransform3D transform = CATransform3DMakeRotation(D2R(-45), 0, 1.0, 0);
transform.m34 = -1.0 / 850;
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: #"transform"];
transformAnimation.fillMode = kCAFillModeForwards;
transformAnimation.removedOnCompletion = NO;
transformAnimation.toValue = [NSValue valueWithCATransform3D:transform];
transformAnimation.duration = 0.5;
[self.layer addAnimation:transformAnimation forKey:#"transform"];
}
The animation works, except it ends with no perspective - ignoring my m34 setting if I'm understanding things correctly.
Halfway through:
At the end:
What am I doing wrong?
Animation only affects the appearance of the view during the animation. It doesn't get applied to the view after the animation ends. You need to do this yourself. I'm guessing something like this right after adding the animation will work:
self.layer.transform = transform;
You can do this right away, as the animation will hide it until the animation completes.
Try this :
- (void) swipe:(UISwipeGestureRecognizer *)recognizer
{
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -10 / 850.0;
transform = CATransform3DRotate(transform, D2R(-45), 0, 1.0, 0);
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath: #"transform"];
transformAnimation.fillMode = kCAFillModeForwards;
transformAnimation.removedOnCompletion = NO;
transformAnimation.toValue = [NSValue valueWithCATransform3D:transform];
transformAnimation.duration = 0.5;
[self.layer addAnimation:transformAnimation forKey:#"transform"];
}
And end the effect is like this :

Resources