Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Animation rotation around point

I would like to make an IBOutlet rotate around a specific point in the parent view, currently i only know how to rotate it around an anchor point, however, i want to use a point outside the object's layer.

The rotation angle is calculated relative to the device heading from the point.

- (void)viewDidLoad{
[super viewDidLoad];
locationManager=[[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.headingFilter = 1;
locationManager.delegate=self;
[locationManager startUpdatingHeading];
[locationManager startUpdatingLocation];
compassImage.layer.anchorPoint=CGPointZero;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
    // Convert Degree to Radian and move the needle
    float oldRad =  -manager.heading.trueHeading * M_PI / 180.0f;
    float newRad =  -newHeading.trueHeading * M_PI / 180.0f;        
    CABasicAnimation *theAnimation;
    theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    theAnimation.fromValue = [NSNumber numberWithFloat:oldRad];
    theAnimation.toValue=[NSNumber numberWithFloat:newRad];
    theAnimation.duration = 0.5f;
    [compassImage.layer addAnimation:theAnimation forKey:@"animateMyRotation"];
    compassImage.transform = CGAffineTransformMakeRotation(newRad);

    NSLog(@"%f (%f) => %f (%f)", manager.heading.trueHeading, oldRad, newHeading.trueHeading, newRad);

  }

How can i rotate the UIImageView around (x,y) by alpha?

like image 883
user3157423 Avatar asked Nov 30 '22 11:11

user3157423


1 Answers

For rotating around a specific point (internal or external) you can change the anchor point of the layer and then apply a regular rotation transform animation similar to what I wrote about in this blog post.

You just need to be aware that the anchor point also affects where the layer appears on the screen. When you change the anchor point you will also have to change the position to make the layer appear in the same place on the screen.

Assuming that the layer is already placed in it's start position and that the point to rotate around is known, the anchor point and the position can be calculated like this (note that the anchor point is in the unit coordinate space of the layer's bounds (meaning that x and y range from 0 to 1 within the bounds)):

CGPoint rotationPoint = // The point we are rotating around

CGFloat minX   = CGRectGetMinX(view.frame);
CGFloat minY   = CGRectGetMinY(view.frame);
CGFloat width  = CGRectGetWidth(view.frame);
CGFloat height = CGRectGetHeight(view.frame);

CGPoint anchorPoint =  CGPointMake((rotationPoint.x-minX)/width,
                                   (rotationPoint.y-minY)/height);

view.layer.anchorPoint = anchorPoint;
view.layer.position = rotationPoint; 

Then you simply apply a rotation animation to it, for example:

CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotate.toValue = @(-M_PI_2); // The angle we are rotating to
rotate.duration = 1.0;

[view.layer addAnimation:rotate forKey:@"myRotationAnimation"];

Just note that you have changed the anchor point so the position is no longer in the center of the frame and if you apply other transforms (such as a scale) they will also be relative to the anchor point.

like image 87
David Rönnqvist Avatar answered Dec 05 '22 12:12

David Rönnqvist