Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

changing image during translation

How can I change myLayer.contents with a set of images (i.e. switching between img1 and img2) during the translation? thanks!

UIImage *myImage = [UIImage imageNamed:@"img1.png"];
CALayer *myLayer = [CALayer layer];
myLayer.contents = (id)myImage.CGImage;
myLayer.Position = CGPointMake(0,0);
myLayer.Bounds=CGRectMake(0.0, 0.0, 50, 50);
[self.view.layer addSublayer:myLayer];

//translation1
CGPoint startPt = CGPointMake(10,10);
CGPoint endPt = CGPointMake(100,100);    
CABasicAnimation *transl1 = [CABasicAnimation animationWithKeyPath:@"position"];
transl1.removedOnCompletion = FALSE;
transl1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
transl1.fromValue = [NSValue valueWithCGPoint:startPt];
transl1.toValue = [NSValue valueWithCGPoint:endPt];
transl1.duration = 3;
transl1.fillMode = kCAFillModeForwards;
transl1.beginTime = 0;
[myLayer addAnimation: transl1 forKey:  nil];
like image 350
Beppino66 Avatar asked Oct 23 '22 23:10

Beppino66


2 Answers

The walking man example:

I have dealt with exactly the same task, but I had to do a running spider which is 6 leg walk and has 12 frames. It was actually very difficult to do and took me few months to perfect. The thing is that the the waking man example is usually done by setting an array of image frames( First leg, Last Leg) to an animationImages property of UIImageView. Then you turn the animation on and off together with moving character right and left and by this creating an illusion of walking. Now the big problem arises when you want create an illusion of acceleration. There is no way to change the animation duration DURING the animation playback and this is a major setback that is very hard to overcome.

Here is the code that I produced to overcome this issue:

Here you define an array with the walking leg frames, frame per step.

animationImagesSpider = [NSArray arrayWithObjects:
[UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], [UIImage imageNamed:@"[email protected]"], nil];   

Here you attach the array to the UIImageView:

imgViewSpider = [[UIImageView alloc] initWithFrame:CGRectMake(200,410,100,145)];
imgViewSpider.animationImages = animationImagesSpider;

Now if you simply call [imgViewSpider startAnimating]; this will start the animation at a constant speed until you stop it. To overcome this I have used a recursion that plays a short animation for each step and this allows to adjusts the duration between each steps:

- (void) spiderRun {

    imgViewSpider.animationDuration= 0.51-(accSp/3.5);
    [imgViewSpider setAnimationRepeatCount:222]; /// this is a dummy value that has no effect because animtion ends after the first frame
    [imgViewSpider startAnimating];
    [self performSelector:@selector(spiderRun) withObject:nil afterDelay: 0.5-(accSp/3.5)];

}

By constantly changing the accSp value, I can control the walk speed during the walk.

like image 196
Registered User Avatar answered Oct 30 '22 02:10

Registered User


As the other poster said, create a second animation that animates the contents property of the layer to a new image.

I would suggest putting both animations into an animation group, and adding the animation group to the layer. Then you can easily control both the duration and start time of both animations. You could make the image swap take place over part of the total duration, timed to take place in the middle of the animation.

You'd set the start of the animation using the beginTime property, and the duration with the duration property.

like image 34
Duncan C Avatar answered Oct 30 '22 03:10

Duncan C