如何使CATransform3dMakeRotation以其他方式旋转?并链在一起 [英] How to make a CATransform3dMakeRotation rotate the other way? And chain together

查看:157
本文介绍了如何使CATransform3dMakeRotation以其他方式旋转?并链在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次使用Core Animation,在实现可以翻转的扑克牌的过程中,我决定使用 CALayer 显示内容(不知道我将如何获得双方,但这是另一个问题)我需要能够翻转它,移动它等等...

I'm working with some Core Animation for the first time and in the process of implementing a playing card that I can flip around, I've decided to use a CALayer to display the contents (not sure how I'm going to get two sides, but that's another question) and I need to be able to flip it over, move it, etc...

我正在使用 CATransaction 取得了一些成功 - 在下面的片段中,卡片从左下角移动到左上角并翻转。问题是,我不想以相反的方式翻转,但不知道怎么说,嘿,你的方向错了!

I'm using CATransaction with some success - in the snippet below, the card moves from the bottom left to the top left and flips over. The problem is that I wan't it to flip the opposite way, but don't know how to tell it, "hey, you're going the wrong way!"

[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]; 






第二个问题是:我怎样才能得到它一次做两次变换?我已经尝试嵌套两个 CATransactions ,但第二个只是覆盖了第一个。我也尝试将旋转矢量更改为2D,就像说围绕x和y轴旋转一样,但这并不等同于只用两个单独的轴将它翻转。这是嵌套代码。


A second question would be: how can I get it to do two transforms at once? I've tried nesting two CATransactions, but the second one just overrides the first. I also tried changing the vector for the rotation to be 2D, like saying to rotate around x and y axes, but that isn't equivalent to just flipping it by pi around two individual axes. Here's the nested code.

[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。翻译时间= 2t,每次轮换每次只需t。


And here it is with UIView animation blocks inside... I've added sliders for the angle, x, y, z for the rotation vector, and t for time. The translation takes place over time = 2t and each of the rotations should take just t each.

[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]; 






这就是我现在的位置:全部有一个例外。当卡达到pi / 2和3 * pi / 2时,y旋转反转(开始沿相反方向旋转)。它也会在这些点处绕x轴翻转。但x和z效果很好。如此接近!


And this is where I am now: It all works with one exception. The y rotation reverses (starts rotating in the opposite direction) when the card gets to pi/2 and 3*pi/2. It also flips about the x axis at these points. But x and z work great. So close!

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


推荐答案

我相信在这种情况下你想要的是使用辅助键码路径,如这个答案

I believe that what you want in this case is to use a helper keypath like is described in this answer:

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

应围绕动画第一阶段的X轴旋转。对于第二个,我相信如果你使用以下

which should rotate about the X axis for the first stage of your animation. For the second, I believe if you use the following

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

它应该使动画累积并可能产生预期的效果。我自己没有试过这个,所以可能需要一些修补才能得到你需要的确切结果。

it should make the animations cumulative and may produce the desired effect. I haven't tried this myself, so some tinkering may be required to get the exact result you need.

当你直接使用变换时,Core Animation将进行插值从当前值到指定变换的转换。它将找到获得该变换的最短路径,这将限制动画方向。如果您尝试将相同的转换属性设置为两次动画,则第二个值将简单地覆盖第一个转换属性,而不是将两个转换组合在一起。

When you are working with a transform directly, Core Animation will interpolate the transform from the current value to the specified transform. It will find the shortest path to get to that transform, which will restrict the animation direction. If you try to animate the same transform property twice, the second value will simply override the first, not combine the two transforms together.

但是,当使用辅助键盘路径时这样,Core Animation将在您的起始角度和结束角度之间进行插值,因此您可以通过更改结束角度的符号来反转方向。它优化了角度值的变化,而不是底层变换的变化。您还应该能够在键路径上组合动画,因为对于每个组合键路径操作,都会为您生成转换。

However, when using a helper keypath like this, Core Animation will interpolate between your starting angle and ending angle, so you can reverse direction by changing the sign of the ending angle. It optimizes the change in angle value, not the change in the underlying transform. You also should be able to combine animations on the keypath, because the transform is generated for you under the hood for each combination of keypath manipulations.

这篇关于如何使CATransform3dMakeRotation以其他方式旋转?并链在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆