Artur
Artur

Reputation: 1183

Elastic Animation - the math behind it

I want to make an elastic popup animation (in the iphone google maps app, kind of like the popup)

Does anybody have an idea of what the math formula would look like to make an elastic animation? i tried but couldn't think of formula or how to do that.

Here's whats i had in mind: (a control, or something) starts growing, faster,faster, when it reaches the right size it stops growing but wiggles around, elastically, then stops.

Any ideas, suggestion, it doesn't have to be specifically that way. Thanks a lot!

Upvotes: 2

Views: 1322

Answers (2)

Brad Larson
Brad Larson

Reputation: 170309

It's a pop-in animation that you are seeing, although I've yet to replicate it exactly. The closest I've come to this using a CAKeyframeAnimation is the following:

CAKeyframeAnimation *boundsOvershootAnimation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"];
CGSize startingSize = CGSizeZero;
CGSize overshootSize = CGSizeMake(targetSize.width * (1.0f + POPINOVERSHOOTPERCENTAGE), targetSize.height * (1.0f + POPINOVERSHOOTPERCENTAGE));
CGSize undershootSize = CGSizeMake(targetSize.width * (1.0f - POPINOVERSHOOTPERCENTAGE), targetSize.height * (1.0f - POPINOVERSHOOTPERCENTAGE));
NSArray *boundsValues = [NSArray arrayWithObjects:[NSValue valueWithCGSize:startingSize],
                         [NSValue valueWithCGSize:overshootSize],
                         [NSValue valueWithCGSize:undershootSize],
                         [NSValue valueWithCGSize:targetSize], nil];
[boundsOvershootAnimation setValues:boundsValues];

NSArray *times = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0f],
                  [NSNumber numberWithFloat:0.5f],
                  [NSNumber numberWithFloat:0.9f],
                  [NSNumber numberWithFloat:1.0f], nil];    
[boundsOvershootAnimation setKeyTimes:times];


NSArray *timingFunctions = [NSArray arrayWithObjects:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], 
                            [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                            [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                            nil];
[boundsOvershootAnimation setTimingFunctions:timingFunctions];
boundsOvershootAnimation.fillMode = kCAFillModeForwards;
boundsOvershootAnimation.removedOnCompletion = NO;

[layer addAnimation:boundsOvershootAnimation forKey:@"boundsOvershoot"];

where POPINOVERSHOOTPERCENTAGE is around 0.1.

This zooms in a layer (which could be a UIView's backing layer), overshoots by a percentage, reduces and undershoots by a little, and then ends up at the final size.

It's close to what the Google map annotations do, but not exactly the same. I think a few slight tweaks to the timing would probably do it.

Upvotes: 5

Jasarien
Jasarien

Reputation: 58448

This would be easy to accomplish using Core Animation, and no maths required - well, nothing beyond addition, subtraction or division for sizing an position.

You could create a CAKeyFrameAnimation that increases the size from 0 (or whatever) to a size somewhat larger than it should be, then scales back down to a big smaller than it should be and then finally scales to its intended size.

That would give you the zoom in, out and to actual size effect.

Upvotes: 2

Related Questions