9

未来的观众:

我已经设法完成了这个旋转动画,并且可以在这个问题上找到带有描述的代码。NSView 中的 NSImage 旋转不起作用

在您继续之前,请投票Duncan C的答案。当我设法从他的回答中实现这种轮换时。


我有这样的图

在此处输入图像描述

我想在不同的线程上继续旋转这个同步图标。现在我尝试使用 Quartz composer 并将动画添加到 QCView 但它的效果非常疯狂而且也很慢。

问题 :

如何以非常少的处理费用连续旋转此图像?

努力

我阅读了 CoreAnimation、Quartz2D 文档,但我没有找到让它工作的方法。到目前为止我唯一知道的是,我必须使用

  • 图层
  • CAImageRef
  • 仿射变换
  • NSAnimationContext

现在,我并不期待代码,但是对伪代码的理解会很棒!

4

2 回答 2

15

让物体旋转超过 180 度实际上有点棘手。问题是您为结束旋转指定了一个变换矩阵,而系统决定向另一个方向旋转。

我所做的是创建一个小于 180 度的 CABasicAnimation,设置为相加,并具有重复计数。动画中的每一步都会为对象设置更多动画。

以下代码取自 iOS 应用程序,但在 Mac OS 中该技术是相同的。

  CABasicAnimation* rotate =  [CABasicAnimation animationWithKeyPath: @"transform.rotation.z"];
  rotate.removedOnCompletion = FALSE;
  rotate.fillMode = kCAFillModeForwards;

  //Do a series of 5 quarter turns for a total of a 1.25 turns
  //(2PI is a full turn, so pi/2 is a quarter turn)
  [rotate setToValue: [NSNumber numberWithFloat: -M_PI / 2]];
  rotate.repeatCount = 11;

  rotate.duration = duration/2;
  rotate.beginTime = start;
  rotate.cumulative = TRUE;
  rotate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

CAAnimation 对象对图层进行操作,因此对于 Mac OS,您需要在界面生成器中设置“想要图层”属性,然后将动画添加到视图的图层。

为了让您的视图永远旋转,您需要将重复计数设置为一个非常大的数字,例如 1e100。

创建动画后,您可以使用如下代码将其添加到视图层:

[myView.layer addAnimation: rotate forKey: @"rotateAnimation"];

这就是它的全部内容。

于 2012-05-31T02:08:10.000 回答
2

更新:

我最近了解到另一种处理大于 180 度的旋转或连续旋转的方法。

有一个称为 CAValueFunction 的特殊对象,可让您使用任意值(包括指定多个完整旋转的值)对图层的变换进行更改。

您创建图层变换属性的 CABasicAnimation,但随后提供的值不是提供变换,而是提供新旋转角度的 NSNumber。如果您提供像 20pi 这样的新角度,您的图层将旋转 10 个完整旋转(2pi/旋转)。代码如下所示:

//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"];

(我从一个工作示例应用程序中提取了上面的代码,并取出了一些与主题没有直接关系的东西。您可以在 github 上的项目KeyframeViewAnimations (链接)中看到正在使用的此代码。执行旋转的代码在一个名为“handleRotate”的方法中

于 2014-04-04T19:22:18.440 回答