How to rotate a CAShapeLayer at its center point - ios

I have made a CAShapeLayer with few points by setting its stroke color to red . Then i have filled the color with a pattern of an UIImage. I want to rotate that CAShapeLayer along with its filled pattern using UIRotationGestureRecognizer.
I have used CATransform3DRotate but it is not working properly.
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, recognizer.rotation, 0.0, 0.0, 1.0);
shapeLayer.transform = transform;
Thanks in advance

You'll want to call:
shapeLayer.anchorPoint = (CGPoint){0.5, 0.5};
You're also starting with the identity transform, which throws away any transformations you've done before, like positioning the layer. What you want to do is:
shapeLayer.transform = CATransform3DRotate(shapeLayer.transform, recognizer.rotation, 0.0, 0.0, 1.0);

Related

How to convert a point to a device point with GPUImageView?

I want to use the instance method "-captureDevicePointOfInterestForPoint:" of AVCaptureVideoPreviewLayer, but the project uses GPUImageView instead of AVCaptureVideoPreviewLayer.
Is there any way to convert a point to a device point with GPUImageView?
You can achieve it with two steps:
Convert coordinates from OpenGL to GPUImageView.
Convert coordinates from GPUImageView to other UIView or to a device by using UIView's methods.
OpenGL in GPUImage has next coordinate system: X: [-1.0, 1.0] (from left to right), Y: [-1.0, 1.0] (from bottom, to top).
We can get next affine transform to convert point from OpenGL to GPUImageView:
//self is GPUImageView
CGAffineTransform moveToPositive = CGAffineTransformMakeTranslation(1.0, 1.0);
CGAffineTransform normolizeTransform = CGAffineTransformMakeScale(1.0 / 2.0, 1.0 / 2.0);
CGAffineTransform invertion = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, -1.0), CGAffineTransformMakeTranslation(0.0, 1.0));
CGAffineTransform scaleToSelfBounds = CGAffineTransformMakeScale(CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
CGAffineTransform resultTransform = CGAffineTransformConcat(CGAffineTransformConcat(CGAffineTransformConcat(moveToPositive, normolizeTransform), invertion), scaleToSelfBounds);
You can use this transformation to convert points from OpenGL to GPUImageView.

Progress View Flip and Scale

I am trying to flip a UIProgressView 180 in Xcode and I am trying to scale the progress view at the same time. The scaling works great until I add the flip and then the scaling does not work anymore. Any suggestions? Thanks!
[self.secondsPorgressBarTicker setTransform:CGAffineTransformMakeScale(1.0, 10.0)];
[self.secondsPorgressBarTicker setTransform:CGAffineTransformMakeRotation(-M_PI)];
You are setting the transform and then resetting it. If you want to combine transforms, you need to use different CG functions. Remember, order matters with transforms, so use whichever one solves your issue:
CGAffineTransform transform = CGAffineTransformMakeRotation(-M_PI);
transform = CGAffineTransformScale(transform, 1.0, 10.0);
[self.secondsPorgressBarTicker setTransform:transform];
or
CGAffineTransform transform = CGAffineTransformMakeScale(1.0, 10.0);
transform = CGAffineTransformRotate(transform, -M_PI);
[self.secondsPorgressBarTicker setTransform:transform];
You're making a new transform. Modify the existing one:
[self.secondsPorgressBarTicker setTransform:CGAffineTransformMakeScale(1.0, 10.0)];
[self.secondsPorgressBarTicker setTransform:CGAffineTransformRotate(self.secondsPorgressBarTicker, -M_PI)

Changing the CALayer anchor point

Changing the anchor point of a CALayer after a CATransform3dRotate gives weird results. I think the problem is, anchorPoint property is set on the previous state (no transform) of layer not the current state (after transform) of the layer.
Is there a way to change the anchorPoint of a CALayer's current state??
Code for Transform:
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -(1.0/800.0);
videoPlayerView.layer.zPosition = 100;
videoPlayerView.layer.transform = CATransform3DRotate(transform, (30*M_PI)/180, 1.0f, 0.0f, 0.0f);
Code to change the anchor Point
if(videoPlayerView.layer.anchorPoint.x != 0.0)
{
videoPlayerView.layer.anchorPoint = CGPointMake(0.0, 0.5);
videoPlayerView.layer.position = CGPointMake(videoPlayerView.layer.frame.origin.x - videoPlayerView.layer.frame.size.width/2,videoPlayerView.layer.position.y);
}
Basically, I have to rotate the Layer like a book flip. I have already done this without using the 30 degree transofrm, but I want it to look more 3D so applied the 30 degree transform along the x axis. So that it looks like the book is placed on a table.
And in order to rotate, setting the anchor point is necessary. If not, please advice otherwise...
instead of changing anchorPoint use
CATransform3DTranslate(transform, 50.0000f, 0.0000f, 0.0000f);
Translate along X by 50.00 points
Apply 0.40 percent of perspective or you can use the same code you are using right now
rotate the CAlayer using Y .
CATransform3D transform = CATransform3DIdentity;
CATransform3D tmp = CATransform3DIdentity;
transform = CATransform3DRotate(transform, 0.0146f, 0, 1, 0);
transform = CATransform3DTranslate(transform, 50.0000f, 0.0000f, 0.0000f);
tmp = CATransform3DIdentity;
tmp.m34 = 0.0040f;
transform = CATransform3DConcat(transform, tmp);
check the link for more reference.
let me know if it works.

UIView Perspective feature

I've got a view and I would like to scale this view as like below image. How do we achieve this?
Thanks,
Mahesh
You need to rotate your view's layer. Something like this,
CALayer *layer = yourView.layer;
CATransform3D rotationTransform = CATransform3DIdentity;
rotationTransform.m24 = 1.0 / -350;
rotationTransform = CATransform3DRotate(rotationTransform, 60*M_PI/180, 1.0, 0.0, -0.1);
[layer setTransform: rotationTransform];
Check out this guide to understand CALayer's geometry and how it works.

What's the difference between setting the zPosition of a layer vs changing it via CATransform3DTranslate

I have a layer where I am modofying its m34 transform property to get perspective.
I would have expected that by changing the zPosition, the size will change (as it appears further away) however when I set the zPosition property, the size does not change, but it does when I use CATransform3DTranslate.
Why is this? What's the difference between the following:
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -4000;
myLayer.transform = transform;
myLayer.zPosition = -500;
and
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -4000;
transform = CATransform3DTranslate(transform, 0, 0, -500);
myLayer.transform = transform;
The latter works how I expect, but I want to understand why the first does not.
zPosition is just for the drawing order of siblings layers, not for perspective drawing: you can use it to get a "bring to front" / "send to back" effect without adding/removing the layer.

Resources