small medium large xlarge

Cbphoto3_pragsmall
18 Jun 2010, 18:43
Christopher Burns (1 post)

Hi gang,

Hoping someone here can guide me… I am trying to accomplish a simple-seeming thing that is turning out to be a beast (isn’t that always the case ?).

I have a 200x200 blue square, drawn in a layer on my view like this:

lyr = [CALayer layer];
lyr.frame = CGRectMake(284, 284, 200, 200);
lyr.backgroundColor = [UIColor blueColor].CGColor;
[lyr retain];
	
[[self layer] addSublayer:lyr];

I have a button on the screen, and when I click the button, I want the square to rotate diagonally, so that the upper-left corner becomes the lower-right corner and we are effectively looking at the “back” of the square.

Halfway through the animation, essentially when the square is flat and invisible to the viewer, I want to change its color, giving the effect that it was blue on one side and purple on the other.

This seems like is should be trivial with all of the power of CA, but I am running into all sorts of troubles.

Here is what I have so far: In the ViewController:

- (IBAction)handleButtonClick {
	CAAnimation *ani1 = [self affineTransAnimation1];
	CAAnimation *ani2 = [self affineTransAnimation2];
	CGColorRef col = ctr%2 ? [UIColor blueColor].CGColor : [UIColor purpleColor].CGColor;
	
	[((FlippingLayerTestView *)[self view]).lyr addAnimation:ani1 forKey:@"flip"];
	((FlippingLayerTestView *)[self view]).lyr.backgroundColor = col;
	[((FlippingLayerTestView *)[self view]).lyr addAnimation:ani2 forKey:@"flipReverse"];
	
	ctr++;
}

- (CAAnimation *)affineTransAnimation1 {
	CAKeyframeAnimation *rotateColor1 = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
	NSMutableArray *values = [[[NSMutableArray alloc] init] autorelease];
	NSMutableArray *times = [[[NSMutableArray alloc] init] autorelease];

	//  Rotate color1
	for (int i = 0; i < frames/2; i++) {
		/* create a scale value going from 1.0 to 0.1 to 1.0 */
		float scale = MAX(fabs((float)(frames-i*2)/frames), 0.063);
		
		CGAffineTransform t1, t2, t3;
		t1 = CGAffineTransformMakeRotation(180);
		t2 = CGAffineTransformScale(t1, scale, 1.0f);
		t3 = CGAffineTransformRotate(t2, -180);
		CATransform3D trans = CATransform3DMakeAffineTransform(t3);
		
		[values addObject:[NSValue valueWithCATransform3D:trans]];
		[times addObject:[NSNumber numberWithFloat:(float)i/frames]];
	}
	
	rotateColor1.values = values;
	rotateColor1.keyTimes = times;
	rotateColor1.duration = duration/2;
	rotateColor1.calculationMode = kCAAnimationLinear;
	
	return rotateColor1;
}
	
- (CAAnimation *)affineTransAnimation2 {
	CAKeyframeAnimation *rotateColor2 = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
	NSMutableArray *cc2Vals = [[[NSMutableArray alloc] init] autorelease];
	NSMutableArray *cc2Times = [[[NSMutableArray alloc] init] autorelease];
	
	for (int i = frames/2; i < frames; i++) {
		/* create a scale value going from 1.0 to 0.1 to 1.0 */
		float scale = MAX(fabs((float)(frames-i*2)/frames), 0.063);
		
		CGAffineTransform t1, t2, t3;
		t1 = CGAffineTransformMakeRotation(180);
		t2 = CGAffineTransformScale(t1, scale, 1.0f);
		t3 = CGAffineTransformRotate(t2, -180);
		CATransform3D trans = CATransform3DMakeAffineTransform(t3);
		
		[cc2Vals addObject:[NSValue valueWithCATransform3D:trans]];
		[cc2Times addObject:[NSNumber numberWithFloat:(float)i/frames]];
	}
	rotateColor2.values = cc2Vals;
	rotateColor2.keyTimes = cc2Times;
	rotateColor2.duration = duration/2;
	rotateColor2.calculationMode = kCAAnimationLinear;

	return rotateColor2;
}

I am running into two problems with this code.

The 0.063 value SHOULD be zero so the transform goes as small as possible to create the effect. However, anything below 0.063, for some reason, causes degeneration in the image and I get a solid line extending (assumedly) infinitely in the -X,-Y to X,Y direction (lower-left of the screen to upper-right). Why???

# There is a timing issue with running the two animations. The first one (the diminution) is truncated by the second (the expansion). It seems I should be able to just create 3 animations (shrink, change color, grow) in a group and run the group, but I cannot figure out how to do the color change in a single frame in that way.

Can anyone show me a better way of doing this, or barring that, explain what I am doing wrong here?

Thanks a million for ANY input.

Cheers,

Chris

You must be logged in to comment