我正在尝试做一个非常简单的动画,但它给了我很多的悲伤......我必须做一些简单的事情,并且错过了一点我想要的结果。
发布在此处:Rotating around a diagonal axis
我试图重新制作一个“黑白棋”片 - 一个正在激活的方块会围绕轴Y = X旋转,并改变颜色以产生旋转以显示其背面的错觉。所以,一边是蓝色,另一边是红色。
为了完成这项工作,我不得不将动画分成4个部分: 1)绕Y = X旋转90度 2)将颜色从oldColor更改为0.5 * oldColor(给出调暗的错觉) 3)绕Y = X旋转90度(将“后”侧面朝前面) 4)将颜色从0.5 * newColor更改为newColor(当照片更多地进入光线时,会产生照明幻觉)
理论上这很好......问题是,前两个步骤执行得非常好,但我无法解决后两个问题。
我尝试在CAAnimationGroup中进行操作,但问题是,我需要明确地将颜色设置为新颜色,否则当步骤3和4动画开始时,闪烁为原始颜色。我无法弄清楚如何在组中做到这一点,所以我将它们分解为单独的动画,并将它们链接起来如下: 1)火1& 2 2)抓住animationDidStop:finished:事件并设置颜色,然后触发3& 4
这样做,3& 4永远不会开火。它只是挂起。
所以我尝试将3& 4上的timeOffset更改为1& 2动画的持续时间。这导致1& 2没有开火,但3& 4工作得很漂亮...... ARG!
Here is the code broken out as individual animations:
<pre><code>
- (IBAction)handleButtonClick {
FlipLayer3View *v = (FlipLayer3View *)[self view];
col = ctr % 2 ? [UIColor blueColor].CGColor : [UIColor redColor].CGColor;
[self aniFromColor:v.theSquare.backgroundColor toColor:col];
ctr++;
}
- (void)aniFromColor:(CGColorRef)fromCol toColor:(CGColorRef)toCol {
FlipLayer3View *v = (FlipLayer3View *)[self view];
const CGFloat *fromColors = CGColorGetComponents(fromCol);
const CGFloat *toColors = CGColorGetComponents(toCol);
v.theSquare.backgroundColor = fromCol;
ani1 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
[ani1 setDuration:dur];
[ani1 setToValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
[ani1 setValue:@"shrink" forKey:@"name"];
[ani1 setDelegate:self];
[ani1 setFillMode:kCAFillModeForwards];
[ani1 setRemovedOnCompletion:NO];
ani2 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
UIColor *c1 = [UIColor colorWithRed:(fromColors[0]/2.0f) green:(fromColors[1]/2.0f) blue:(fromColors[2]/2.0f) alpha:1.0f];
const float *cgCol1 = CGColorGetComponents(fromCol);
const float *cgCol2 = CGColorGetComponents(c1.CGColor);
NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);
[ani2 setDuration:dur];
[ani2 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[ani2 setFromValue:(id)fromCol];
[ani2 setToValue:(id)c1.CGColor];
[ani2 setValue:@"dim" forKey:@"name"];
[ani2 setDelegate:self];
[ani2 setFillMode:kCAFillModeForwards];
[ani2 setRemovedOnCompletion:NO];
ani3 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
[ani3 setDuration:dur];
[ani3 setFromValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
[ani3 setToValue:[NSValue valueWithCATransform3D:v.theSquare.transform]];
[ani3 setValue:@"grow" forKey:@"name"];
[ani3 setTimeOffset:dur];
[ani3 setDelegate:self];
[ani3 setFillMode:kCAFillModeForwards];
[ani3 setRemovedOnCompletion:NO];
ani4 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
UIColor *c2 = [UIColor colorWithRed:(toColors[0]/2.0f) green:(toColors[1]/2.0f) blue:(toColors[2]/2.0f) alpha:1.0f];
cgCol1 = CGColorGetComponents(c2.CGColor);
cgCol2 = CGColorGetComponents(toCol);
NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);
[ani4 setDuration:dur];
[ani4 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[ani4 setFromValue:(id)c2.CGColor];
[ani4 setToValue:(id)toCol];
[ani4 setValue:@"glow" forKey:@"name"];
[ani4 setTimeOffset:dur];
[ani4 setDelegate:self];
[ani4 setFillMode:kCAFillModeForwards];
[ani4 setRemovedOnCompletion:NO];
[v.theSquare addAnimation:ani1 forKey:@"rotate1"];
[v.theSquare addAnimation:ani2 forKey:@"fadeout"];
[v.theSquare addAnimation:ani3 forKey:@"rotate2"];
[v.theSquare addAnimation:ani4 forKey:@"fadein"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (flag) {
NSString *str = [anim valueForKey:@"name"];
if ([str isEqual:@"shrink"]) {
NSLog(@"SHRINK complete...");
}
else if ([str isEqual:@"dim"]) {
NSLog(@"DIM complete...");
FlipLayer3View *theView = (FlipLayer3View *)[self view];
theView.theSquare.backgroundColor = col;
}
else if ([str isEqual:@"grow"]) {
NSLog(@"GROW complete...");
}
else if ([str isEqual:@"glow"]) {
NSLog(@"GLOW complete...");
}
}
}
</code></pre>
这里,FWIW是我在CAAnimationGroup解决方案中使用的代码:
<pre><code>
- (IBAction)handleButtonClick {
FlipLayer3View *v = (FlipLayer3View *)[self view];
CGColorRef c = ctr % 2 ? [UIColor redColor].CGColor : [UIColor blueColor].CGColor;
aniGroup = [self aniFromColor:v.theSquare.backgroundColor toColor:c];
[v.theSquare addAnimation:aniGroup forKey:@"rotate"];
ctr++;
}
- (CAAnimationGroup *)aniFromColor:(CGColorRef)fromCol toColor:(CGColorRef)toCol {
FlipLayer3View *v = (FlipLayer3View *)[self view];
const CGFloat *fromColors = CGColorGetComponents(fromCol);
const CGFloat *toColors = CGColorGetComponents(toCol);
ani1 = [CABasicAnimation animationWithKeyPath:@"transform"];
[ani1 setDuration:dur];
[ani1 setToValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
[ani1 setValue:@"shrink" forKey:@"name"];
ani2 = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
UIColor *c1 = [UIColor colorWithRed:(fromColors[0]/2.0f) green:(fromColors[1]/2.0f) blue:(fromColors[2]/2.0f) alpha:1.0f];
[ani2 setDuration:dur];
[ani2 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[ani2 setToValue:(id)c1.CGColor];
[ani2 setValue:@"dim" forKey:@"name"];
ani3 = [CABasicAnimation animationWithKeyPath:@"transform"];
[ani3 setDuration:dur];
[ani3 setFromValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
[ani3 setToValue:[NSValue valueWithCATransform3D:v.theSquare.transform]];
[ani3 setValue:@"grow" forKey:@"name"];
[ani3 setBeginTime:dur];
ani4 = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
UIColor *c2 = [UIColor colorWithRed:(toColors[0]/2.0f) green:(toColors[1]/2.0f) blue:(toColors[2]/2.0f) alpha:1.0f];
[ani4 setDuration:dur];
[ani4 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[ani4 setFromValue:(id)c2.CGColor];
[ani4 setToValue:(id)toCol];
[ani4 setValue:@"glow" forKey:@"name"];
[ani4 setBeginTime:dur];
aniGroup = [CAAnimationGroup animation];
[aniGroup setDuration:dur*2];
[aniGroup setAnimations:[NSArray arrayWithObjects:ani1, ani2, ani3, ani4, nil]];
[aniGroup setFillMode:kCAFillModeForwards];
[aniGroup setRemovedOnCompletion:NO];
return aniGroup;
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (flag) {
NSString *str = [anim valueForKey:@"name"];
if ([str isEqual:@"shrink"]) {
NSLog(@"SHRINK complete...");
}
else if ([str isEqual:@"dim"]) {
NSLog(@"DIM complete...");
}
else if ([str isEqual:@"grow"]) {
NSLog(@"GROW complete...");
}
else if ([str isEqual:@"glow"]) {
NSLog(@"GLOW complete...");
}
}
}
</code></pre>
有人请告诉我,我错过了什么样的傻瓜......这就是杀了我!
谢谢!
克里斯
答案 0 :(得分:2)
好的,所以让我成为第一个称我为白痴的人......在我首先尝试的Group版本中,我有一个beginTime设置,但是当我转换为单个动画时,一定不能删除它,导致动画序列的后半部分失败。这让我尝试设置timeOffset,这给出了一个奇怪的结果,即没有触发前半部分,但是触发了第二部分。
我刚进去并删除了所有这些,beginTime,timeOffset等。然后解雇了前两个动画。然后在animationDidStop:finished:方法中,我改变动画层的颜色以避免闪回到原始颜色,最后启动第二组动画。 Et Viola !!!
供参考,以下是工作代码:
- (IBAction)handleButtonClick {
FlipLayer3View *v = (FlipLayer3View *)[self view];
col = ctr % 2 ? [UIColor blueColor].CGColor : [UIColor redColor].CGColor;
[self aniFromColor:v.theSquare.backgroundColor toColor:col];
ctr++;
}
- (void)aniFromColor:(CGColorRef)fromCol toColor:(CGColorRef)toCol {
FlipLayer3View *v = (FlipLayer3View *)[self view];
const CGFloat *fromColors = CGColorGetComponents(fromCol);
const CGFloat *toColors = CGColorGetComponents(toCol);
v.theSquare.backgroundColor = fromCol;
ani1 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
[ani1 setDuration:dur];
[ani1 setToValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
[ani1 setValue:@"shrink" forKey:@"name"];
[ani1 setDelegate:self];
[ani1 setFillMode:kCAFillModeForwards];
[ani1 setRemovedOnCompletion:NO];
ani2 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
UIColor *c1 = [UIColor colorWithRed:(fromColors[0]/2.0f) green:(fromColors[1]/2.0f) blue:(fromColors[2]/2.0f) alpha:1.0f];
const float *cgCol1 = CGColorGetComponents(fromCol);
const float *cgCol2 = CGColorGetComponents(c1.CGColor);
NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);
[ani2 setDuration:dur];
[ani2 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[ani2 setFromValue:(id)fromCol];
[ani2 setToValue:(id)c1.CGColor];
[ani2 setValue:@"dim" forKey:@"name"];
[ani2 setDelegate:self];
[ani2 setFillMode:kCAFillModeForwards];
[ani2 setRemovedOnCompletion:NO];
ani3 = [[CABasicAnimation animationWithKeyPath:@"transform"] retain];
[ani3 setDuration:dur];
[ani3 setFromValue:[NSValue valueWithCATransform3D:CATransform3DConcat(v.theSquare.transform, CATransform3DRotate(CATransform3DIdentity, M_PI/2, -1, 1, 0))]];
[ani3 setToValue:[NSValue valueWithCATransform3D:v.theSquare.transform]];
[ani3 setValue:@"grow" forKey:@"name"]; [ani3 setDelegate:self];
[ani3 setFillMode:kCAFillModeForwards];
[ani3 setRemovedOnCompletion:NO];
ani4 = [[CABasicAnimation animationWithKeyPath:@"backgroundColor"] retain];
UIColor *c2 = [UIColor colorWithRed:(toColors[0]/2.0f) green:(toColors[1]/2.0f) blue:(toColors[2]/2.0f) alpha:1.0f];
cgCol1 = CGColorGetComponents(c2.CGColor);
cgCol2 = CGColorGetComponents(toCol);
NSLog(@"Setting color FROM R:%f G:%f B:%f", cgCol1[0], cgCol1[1], cgCol1[2]);
NSLog(@"Setting color TO R:%f G:%f B:%f", cgCol2[0], cgCol2[1], cgCol2[2]);
[ani4 setDuration:dur];
[ani4 setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[ani4 setFromValue:(id)c2.CGColor];
[ani4 setToValue:(id)toCol];
[ani4 setValue:@"glow" forKey:@"name"]; [ani4 setDelegate:self];
[ani4 setFillMode:kCAFillModeForwards];
[ani4 setRemovedOnCompletion:NO];
[v.theSquare addAnimation:ani1 forKey:@"rotate1"];
[v.theSquare addAnimation:ani2 forKey:@"fadeout"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (flag) {
NSString *str = [anim valueForKey:@"name"];
if ([str isEqual:@"shrink"]) {
NSLog(@"SHRINK complete...");
}
else if ([str isEqual:@"dim"]) {
NSLog(@"DIM complete...");
FlipLayer3View *theView = (FlipLayer3View *)[self view];
theView.theSquare.backgroundColor = col;
[theView.theSquare addAnimation:ani3 forKey:@"rotate2"];
[theView.theSquare addAnimation:ani4 forKey:@"fadein"];
}
else if ([str isEqual:@"grow"]) {
NSLog(@"GROW complete...");
}
else if ([str isEqual:@"glow"]) {
NSLog(@"GLOW complete...");
}
}
}
如果有人看到问题或知道更好的方式,我很乐意听到!!
谢谢,
克里斯