Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I achieve continuous rotation of an NSImage inside NSImageView?

FUTURE VIEWERS:

I have managed to finish this rotation animation and code with description can be found on tho question. NSImage rotation in NSView is not working

Before you proceed please up vote Duncan C 's answer. As I manage to achieve this rotation from his answer.


I have an image like this,

enter image description here

I want to keep rotating this sync icon, On a different thread. Now I tried using Quartz composer and add the animation to QCView but it is has very crazy effect and very slow too.

Question :

How do I rotate this image continuously with very less processing expense?

Effort

I read CoreAnimation, Quartz2D documentation but I failed to find the way to make it work. The only thing I know so far is, I have to use

  • CALayer
  • CAImageRef
  • AffineTransform
  • NSAnimationContext

Now, I am not expecting code, but an understanding with pseudo code will be great!

like image 460
TeaCupApp Avatar asked May 31 '12 01:05

TeaCupApp


1 Answers

Update:

I've recently learned of another way to handle rotations of greater than 180 degrees, or continuous rotations.

There is a special object called a CAValueFunction that lets you apply a change to your layer's transform using an arbitrary value, including values that specify multiple full rotations.

You create a CABasicAnimation of your layer's transform property, but then instead of providing a transform, the value you supply is an NSNumber that gives the new rotation angle. If you provide a new angle like 20pi, your layer will rotate 10 full rotations (2pi/rotation). The code looks like this:

//Create a CABasicAnimation object to manage our rotation.
CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform"];

rotation.duration = 10.0;
CGFLOAT angle = 20*M_PI;

//Set the ending value of the rotation to the new angle.
rotation.toValue = @(angle);

//Have the rotation use linear timing.
rotation.timingFunction = 
  [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

/*
 This is the magic bit. We add a CAValueFunction that tells the CAAnimation we are 
 modifying the transform's rotation around the Z axis.
 Without this, we would supply a transform as the fromValue and toValue, and 
 for rotations > a half-turn, we could not control the rotation direction.

 By using a value function, we can specify arbitrary rotation amounts and 
 directions and even rotations greater than 360 degrees.
*/

rotation.valueFunction = 
  [CAValueFunction functionWithName: kCAValueFunctionRotateZ];



/*
 Set the layer's transform to it's final state before submitting the animation, so 
 it is in it's final state once the animation completes.
*/
imageViewToAnimate.layer.transform = 
  CATransform3DRotate(imageViewToAnimate.layer.transform, angle, 0, 0, 1.0);

[imageViewToAnimate.layer addAnimation:rotation forKey:@"transform.rotation.z"];

(I Extracted the code above from a working example application, and took out some things that weren't directly related to the subject. You can see this code in use in the project KeyframeViewAnimations (link) on github. The code that does the rotation is in a method called `handleRotate'

like image 188
Duncan C Avatar answered Sep 30 '22 08:09

Duncan C