catransform3dmakerotationを逆方向に回転させる方法は?そして一緒にチェーン

StackOverflow https://stackoverflow.com/questions/3799194

質問

私は初めていくつかのコアアニメーションを使用していますが、ひっくり返すことができるトランプを実装する過程で、私は使用することにしました CALayer 内容を表示するには(私が2つの側面を取得する方法がわかりませんが、それは別の質問です)、私はそれを裏返したり、動かしたりすることができる必要があります...

私は使用しています CATransaction ある程度の成功 - 下のスニペットでは、カードは左下から左上に移動し、ひっくり返します。問題は、私が反対の方法をひっくり返すことはないということですが、「ねえ、あなたは間違った方法で進んでいます!」と言う方法がわかりません。


[CATransaction begin]; 
[CATransaction setValue:[NSNumber numberWithFloat:2.0f] forKey:kCATransactionAnimationDuration];
myCard.position = CGPointMake(CGRectGetMidX(self.bounds)/2,CGRectGetMidY(self.bounds)/2);
myCard.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
[CATransaction commit]; 

2番目の質問は次のとおりです。どうすれば2つの変換を一度に実行させることができますか?私は2つをネストしようとしました CATransactions, 、しかし、2番目は最初のものを無効にします。また、XとYの軸の周りを回転するように言うように、回転のベクトルを2Dに変更しようとしましたが、それは2つの個々の軸の周りでPIでそれをひっくり返すだけではありません。これがネストされたコードです。


[CATransaction begin]; 
[CATransaction setValue:[NSNumber numberWithFloat:2.0f] forKey:kCATransactionAnimationDuration];
myCard.position = CGPointMake(CGRectGetMidX(self.bounds)/2,CGRectGetMidY(self.bounds)/2);
myCard.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0); // rotate about x

  [CATransaction begin]; 
  [CATransaction setValue:[NSNumber numberWithFloat:1.0f] forKey:kCATransactionAnimationDuration];
  myCard.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0); // rotate about y
  [CATransaction commit]; 

[CATransaction commit]; 

そして、ここにあります UIView アニメーションは内部にブロックされます...角度にスライダー、x、y、zを回転ベクトルに、t時間に追加しました。翻訳は時間の経過とともに行われ、各回転はそれぞれtを取る必要があります。

[CATransaction begin]; 
[CATransaction setValue:[NSNumber numberWithFloat:t * 2] forKey:kCATransactionAnimationDuration];
myCard.position = CGPointMake(CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2);

  [UIView beginAnimations:nil context:nil];
  [UIView setAnimationDuration:t];
  myCard.transform = CATransform3DMakeRotation(angle, x, y, z);
  [UIView commitAnimations]; 

  [UIView beginAnimations:nil context:nil];
  [UIView setAnimationDuration:t];
  [UIView setAnimationDelay:t];
  myCard.transform = CATransform3DMakeRotation(angle * 2, x, y, z);
  [UIView commitAnimations];

[CATransaction commit]; 

そして、これは私が今いるところです:それはすべて1つの例外を伴うものです。カードがpi/2および3*pi/2に到達すると、y回転が反転します(反対方向に回転します)。また、これらのポイントでx軸をめくります。しかし、XとZはうまく機能します。とても近い!

CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2*3);
CGPathAddCurveToPoint(thePath,NULL,
                      CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2*2,
                      CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2*1.5,
                      CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2);
CAKeyframeAnimation *moveAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
moveAnimation.path=thePath;
CFRelease(thePath);

CABasicAnimation *xRotation;
xRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
xRotation.fromValue = [NSNumber numberWithFloat:0.0];
xRotation.toValue = [NSNumber numberWithFloat:x * angle * M_PI];

CABasicAnimation *yRotation;
yRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
yRotation.fromValue = [NSNumber numberWithFloat:0.0];
yRotation.toValue = [NSNumber numberWithFloat:y * angle * M_PI];

CABasicAnimation *zRotation;
zRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
zRotation.fromValue = [NSNumber numberWithFloat:0.0];
zRotation.toValue = [NSNumber numberWithFloat:z * angle * M_PI];

CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.duration = t;
groupAnimation.removedOnCompletion = NO;
groupAnimation.fillMode = kCAFillModeForwards;
groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
groupAnimation.animations = [NSArray arrayWithObjects:moveAnimation, xRotation, yRotation, zRotation, nil];

[myCard addAnimation:groupAnimation forKey:@"animateCard"];
役に立ちましたか?

解決

この場合にあなたが望むのは、次のようにヘルパーキーパスを使用することだと思います この答え:

CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI];
rotationAnimation.duration = duration;
[myCard.layer addAnimation:rotationAnimation forKey:@"rotationAnimation1"];

これは、アニメーションの最初の段階でx軸を回転させるはずです。第二に、あなたが次のものを使用するなら私は信じています

CABasicAnimation *rotationAnimation2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
rotationAnimation2.toValue = [NSNumber numberWithFloat: M_PI];
rotationAnimation2.duration = duration2;
rotationAnimation2.cumulative = YES;
[myCard.layer addAnimation:rotationAnimation2 forKey:@"rotationAnimation2"];

アニメーションを累積的にする必要があり、望ましい効果を生成する可能性があります。私はこれを自分で試したことがないので、必要な正確な結果を得るために、いくつかのいじくり回しが必要になる場合があります。

Transformを直接使用している場合、Core Animationは変換を現在の値から指定された変換に補間します。その変換に到達するための最短パスが見つかり、アニメーションの方向を制限します。同じ変換プロパティを2回アニメーション化しようとすると、2番目の値が2つの変換を組み合わせるのではなく、最初の値を単純にオーバーライドします。

ただし、このようなヘルパーキーパスを使用する場合、コアアニメーションは開始角度とエンディング角を補間するため、終了角の符号を変更することで方向を逆にすることができます。基礎となる変換の変化ではなく、角度値の変化を最適化します。また、キーパス操作の各組み合わせのフードの下で変換が生成されるため、キーパスのアニメーションを組み合わせることができるはずです。

他のヒント

軸上の反転は、Appleのライブラリ内で起こっているジンバルロックによって引き起こされると推測しています。 99.999%の時間の簡単な修正は、正確な0、90、180、270、360度の回転を使用しないことです。私は自分のコードでこのようなことが起こるのを見てきましたが、M_PIの代わりに(M_PI*0.99)のようなものを使用しています。これは、ビデオカードのマトリックス乗数をオイラー角度で使用している場合、常に問題です。

複数の変換を同時に適用するには、それらをネストすることができます。これは、OpenGLのマトリックスを掛けるのとまったく同じように機能します。

// translate and scale at the same time
float scale = 1.6;
CATransform3D scaleMatrix = CATransform3DMakeScale(scale, scale, 1);
CATransform3D finalMatrix = CATransform3DTranslate(scaleMatrix, frame.size.width/scale, frame.size.height/scale, 0);
CABasicAnimation* animBottomTrans = [CABasicAnimation animationWithKeyPath:@"transform"];
[animBottomTrans setFromValue:[NSValue valueWithCATransform3D:finalMatrix]];
[animBottomTrans setToValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]];
[animBottomTrans setDuration:duration];
[myLayer addAnimation:animBottomTrans forKey:@"transform"];

これらはネストされているので、その後に来る変革で以前の変換に対処する必要があることを忘れないでください。このコードでは、すでにスケーリングしているため、翻訳した金額を変更する必要があります。 Z軸で90度を回転させてからY軸で90度回転すると、Z軸とX軸(Z回転はXとYの軸を交換します)で効果的に回転します。

結果の変換は同じです: (CGAffineTransform){-1,0,0,-1,0,0}. 。 CoreAnimationは、トリックを行う最短回転を選択し、デフォルトで時計回りに回転します(私は思う)。

他の方法を回転させる最も簡単な方法は、 ほとんど -M_PI (「間違った」方法を回転させる前に、どれだけ近づくことができるかは正確にはわかりません)。

より複雑な方法は、それを2つの回転に分割することです。1つは0から-M_PI/2、もう1つは-M_PI/2から-M -PIです。アニメーションの遅延を設定してこれを実現できると思います...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top