CATransForm3D matrix issue - iphone

If you want to rotate an object using core animation, in radians, in the z axis, which of the following key paths of layer's CATransform3D matrix will you use? (more than 1 options can be right).
rotation
rotation.xy
rotation.x
rotation.y
rotation.z

Not totally clear about the options you gave, but I use the code below to do rotation:
[[_yourView layer] setAnchorPoint:CGPointMake(0.0f, 0.5)];
[UIView animateWithDuration:1.0f
delay:0.0f
options:UIViewAnimationCurveEaseInOut
animations:^{
CATransform3D rotation = CATransform3DIdentity;
rotation.m34 = 1.0f / -300.0f;
rotation = CATransform3DRotate(rotation, -60.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[[_yourView layer] setTransform:rotation];
}
completion:nil];
It is rotated in y axis(so, the view will change in z direction), you can set the rotation for other axis by setting the params below:
rotation = CATransform3DRotate(rotation, -60.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);

None of the above. Use transform.rotation.z

Related

How to change for 3D rotation on UIPanGesture?

I have done animation opening a page on tapping on it but now I have to change it for Pan Gesture. How should I start?
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
CALayer *layer = ges.view.layer;
CATransform3D initialTransform = ges.view.layer.transform;
initialTransform.m34 = 1.0 / -1100;
layer.transform = initialTransform;
layer.anchorPoint = CGPointMake(-0.0, 0.5);
[UIView beginAnimations:#"Scale" context:nil];
[UIView setAnimationDuration:2];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
CATransform3D rotationAndPerspectiveTransform = ges.view.layer.transform;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, -M_PI , 0 , -ges.view.bounds.size.height/2, 0);
ges.view.transform = CGAffineTransformRotate(ges.view.transform, 0);
layer.transform = rotationAndPerspectiveTransform;
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
UIPanGestureRecognizer myPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(imagePanned:)];
[_panGesture setMaximumNumberOfTouches:1];
[yourView addGestureRecognizer:myPanGesture];
1) if you want page to turn along with the pan action as user moves the view then you have to do this way.
- (void)imagePanned:(UIPanGestureRecognizer *)iRecognizer {
CGPoint translation = [recognizer translationInView:self.view];
//Calculate transformation based on the translation value of pan gesture, this will be a tricky part
[UIView animateWithDuration:0.5 delay: 0 options: 0 animations:
^(void) {
//Apply transformation
}
completion: nil];
}
Hope this will help you.
Edit : Extended Answer
*This goes with the first idea*
You just want to rotate the view right ?
then use CATransform3D, here you will need to calculate the iAngle that we are applying to view.
iAngle = //Calculate based on translation
where translation is
CGPoint translation = [recognizer translationInView:self.view];
Then apply transformation to view
CATransform3D myTransform = CATransform3DIdentity;
myTransform.m34 = 1.0 / -500;
myTransform = CATransform3DRotate(myTransform, DEGREES_TO_RADIANS(-iAngle), 0.0f, 1.0f, 0.0f); //#define DEGREES_TO_RADIANS(d) (d * M_PI / 180)
yourView.layer.transform = myTransform;
I'll give you the math behind doing it as I don't have code right now to show. Converting finger movement to rotation value is simply a matter of setting up ratios.
For angle value (used in transform):
track_spread rotation_angle
____________ = ______________
movement_x angle = ?
angle = (rotation_angle * movement_x)/track_spread;
WHERE:
track_spread = width_of_your_view (or less e.g. 70% x width_of_your_view)
rotation_angle = the final rotation you want for your view (a constant e.g. 45 degrees)
CGPoint point = [recognizer translationInView:self];
movement_x = abs(point.x);
angle = the value (in degrees) you are interested in and will input into transform after converting to radians
If someone cant figure out and still need code snippet please leave a comment.

how to rotate a view from left to right using CATransform3DMakeRotation

I know how to rotate a view from right to left
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DMakeRotation(M_PI, 0.0f, 1.0f, 0.0f);
transform.m34 = 0.0015;
view.layer.transform = transform;
But i cant rotate it from left to right.
Please help me.
I'm not sure what you mean by “left to right” and “right to left”. Anyway, as you have discovered, you can't control the direction of the animation just by setting the transform matrix, because both -M_PI and +M_PI have the same final effect, so there's no way for Core Animation to reliably know which way you want it to rotate.
Instead, you can animate the transform.rotation.y key path of the layer. This is a little more complicated to do, particularly since you want to animate a view's layer instead of a freestanding layer (not controlled by a view).
Anyway, here's the code I tested:
- (IBAction)rotateButtonWasTapped:(id)sender {
// Establish the perspective to be used during the animation.
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 0.0015;
self.imageView.layer.transform = transform;
static CGFloat kAngle = -M_PI;
[CATransaction begin]; {
// After the animation completes, make the transform “permanent”. Otherwise it
// will be undone when the animation is removed from the layer.
[CATransaction setCompletionBlock:^{
self.imageView.layer.transform = CATransform3DRotate(transform, kAngle, 0, 1, 0);
}];
// Animate the rotation using Core Animation's extension to Key Value Coding.
// The sign of kAngle determines the direction of rotation.
CABasicAnimation *animation = [CABasicAnimation
animationWithKeyPath:#"transform.rotation.y"];
animation.fromValue = #0;
animation.toValue = #(kAngle);
animation.duration = 1;
[self.imageView.layer addAnimation:animation forKey:animation.keyPath];
} [CATransaction commit];
}
This rotates the view such that the left edge of the view moves “closer” to the user during the rotation. If that's not what you mean by “left to right”, change the definition of kAngle to M_PI and it will rotate in the other direction. I have tested both ways. You can even spin the layer multiple times in one animation. For example, try defining kAngle as -3 * M_PI.
I did not find anything in the function documentation, but I think you can just make the rotation angle negative to rotate into the other direction.
if you want to rotate the view, back to the initial position... just do it with:
transform = CATransform3DMakeRotation(0, 0.0f, 1.0f, 0.0f)
or you can "combine" more..
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DMakeRotation(-M_PI_2, 0.0f, 1.0f, 0.0f);
transform = CATransform3DMakeRotation(0, 0.0f, 1.0f, 0.0f);
transform.m34 = 0.0015;
view.layer.transform = transform;
You can try... to use CATransform3D transform = starLayer.transform; instead of CATransform3D transform = CATransform3DIdentity;
-(void)updateTimer
{
if(update<125)
update=update+1;
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval interval = now - start;
int inter = (int)(interval*update);
inter*=10;
milliSec = (inter) % 1000;
seconds = (inter/1000) % 60;
minutes = (inter/60000) % 60;
timeValue = oldTimeValue+inter;
// Set Digital clock
// Set Analog clock hands
secHand.layer.transform = CATransform3DMakeRotation (Degrees2Radians(-(timeValue%1000)*360/1000), 0, 0, 1);
}

How to make image rotation and 3D transform simultaneously?

I am working on image editing application(resize, rotation, 3d transform). If I am rotate the image and then make 3D transform. Its going to initial image. Otherwise I am change the 3D transform then make rotation, Its also goes to the initial state.
For image 3D Transform I am using below code :
- (void)moveImage:(UIPanGestureRecognizer *)recognizer
{
if ([recognizer respondsToSelector:#selector(translationInView:)]) {
CGPoint translation = [(UIPanGestureRecognizer *)recognizer translationInView:recognizer.view.superview];
CALayer *layer = self.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / 500.0;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, - self.xTranslation / 50.0 * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
rotationAndPerspectiveTransform.m34 = - 1.0 / 500.0;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, - self.yTranslation / 50.0 * M_PI / 180.0f, 1.0f, 0.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
}
}
For image Rotation I am using below code :
- (void)rotateImage:(UIRotationGestureRecognizer *)recognizer
{
if (state == RSImageViewStateResizing) {
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
recognizer.rotation = 0;
}
}
How to I fix this issue. Always welcome your suggestions, sample code, Sample project, any App store applications. Thanks in advance. Any one help me.
Use CAAnimationGroup to combine multiple animation into one
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.animations=[NSArray arrayWithObject:resizeAnimation, rotationAnimation, 3d transformAnimation];// add here your CAAnimation reference and CATransform3D reference
[layer addAnimation:theGroup forKey:#"animatePosition"];

CATransform3D not working properly

CATransform3D not working properly, I am using the below code. My problem is If I change the transform Its working fine. Once I release my finger and then make more transform the image goes to the Initial image. How to set the last transform? I am using PanGesture for the transform. Please give some Idea. Thanks in advance.
if ([recognizer respondsToSelector:#selector(translationInView:)]) {
CGPoint translation = [(UIPanGestureRecognizer *)recognizer translationInView:recognizer.view.superview];
CALayer *layer = self.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, translation.x * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, -translation.y * M_PI / 180.0f, 1.0f, 0.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
}
CATransform3DIdentity means you resetting the transformation every time your view receives touch. Use CATransform3D rotationAndPerspectiveTransform = layer.transform; instead.

perspective transform on uiview

Here's the basic code to get started with:
[UIView transitionWithView:self.view duration:2.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^ {
CALayer *layer1 = leftband.layer;
layer1.anchorPoint = CGPointMake(0, 0.5);
CATransform3D rotationAndPerspectiveTransform1 = CATransform3DIdentity;
rotationAndPerspectiveTransform1.m34 = 1.0 / -500;
rotationAndPerspectiveTransform1 = CATransform3DRotate(rotationAndPerspectiveTransform1, DegreesToRadians(-180.0f), 0.0f, 1.0f, 0.0f);
layer1.transform = rotationAndPerspectiveTransform1;
CALayer *layer2 = rightband.layer;
layer2.anchorPoint = CGPointMake(0, 0.5);
CATransform3D rotationAndPerspectiveTransform2 = CATransform3DIdentity;
rotationAndPerspectiveTransform2.m34 = 1.0 / -500;
rotationAndPerspectiveTransform2 = CATransform3DRotate(rotationAndPerspectiveTransform2, DegreesToRadians(180.0f), 0.0f, 1.0f, 0.0f);
layer2.transform = rotationAndPerspectiveTransform2;
}
completion:nil {
}];
leftband and rightband are two UIImageViews. The effect I want is that the leftband animates with its transform along the Y-axis towards the left direction. And the rightband does the same along its Y-axis towards the right.
But the above code results in both left and right imageviews animating in the same direction (it happens only towards left). I guess my understanding of anchor points is wrong. Both -180° and +180° in the rotation transform result in a leftward animation.
What am I doing wrong here?
Basically setting the anchor points before the animation block runs solves the issue. Anchor point for left -> (0.0f,0.5f) and for right -> (1.0f,0.5f).