我第一次使用一些核心动画,在实现可以翻转的扑克牌的过程中,我决定使用 aCALayer
来显示内容(不知道我将如何获得两个面,但这是另一个问题)我需要能够将其翻转、移动等...
我使用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];
第二个问题是:我怎样才能让它同时进行两次转换?我试过嵌套两个CATransactions
,但第二个只是覆盖第一个。我还尝试将旋转的矢量更改为 2D,比如说围绕 x 和 y 轴旋转,但这并不等同于仅通过 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 用于时间。平移发生在时间 = 2t 中,并且每次旋转应该只花费 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];
这就是我现在所处的位置:除了一个例外,这一切都有效。当卡片到达 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"];