9

将来の視聴者:

この回転アニメーションをなんとか完成させました。説明付きのコードは、質問にあります。NSView での NSImage の回転が機能しない

続行する前に、 Duncan Cの回答に投票してください。彼の答えからこのローテーションを達成することができたので。


こんなイメージがありますが、

ここに画像の説明を入力

別のスレッドで、この同期アイコンを回転させ続けたいです。ここで、Quartz composer を使用してアニメーションを QCView に追加しようとしましたが、非常にクレイジーな効果があり、非常に遅いです。

質問 :

処理コストを非常に抑えてこの画像を連続的に回転するにはどうすればよいですか?

努力

CoreAnimation、Quartz2D のドキュメントを読みましたが、それを機能させる方法が見つかりませんでした。私がこれまでに知っている唯一のことは、私は使用しなければならないということです

  • CALayer
  • 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 に答える