Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create a wiggle animation similar to iphone deletion animation

We are currently developing an application that contains a series of icons. We want the icons to wiggle like the app deletion animations when pressed. What would be the best way to code this animation sequence?

like image 528
user446718 Avatar asked Sep 13 '10 19:09

user446718


3 Answers

The answer by Vinzius is very cool. However the wobble only rotates from 0 Radians to 0.08. Thus the wobble can look a little unbalanced. If you get this same issue then you may want to add both a negative and a positive rotation by using a CAKeyframeAnimation rather than a CABasicRotation:

- (CAAnimation*)getShakeAnimation  {     CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];      CGFloat wobbleAngle = 0.06f;      NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];     NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];     animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil];      animation.autoreverses = YES;       animation.duration = 0.125;     animation.repeatCount = HUGE_VALF;        return animation;     } 

You can use this animation method for your view or button like this.

[self.yourbutton.layer addAnimation:[self getShakeAnimation] forKey:@""]; 
like image 176
paiego Avatar answered Sep 21 '22 04:09

paiego


Looking at the iOS implementation a bit closer, there are two things that make theirs a bit more realistic than the code mentioned here:

  • The icons appear to have a bounce as well as a rotation
  • Every icon has its own timing -- they are not all synchronized

I based myself on the answers here (and with some help from this answer) to add the rotation, the bounce and a bit of randomness to the duration of each animation.

#define kWiggleBounceY 4.0f
#define kWiggleBounceDuration 0.12
#define kWiggleBounceDurationVariance 0.025

#define kWiggleRotateAngle 0.06f
#define kWiggleRotateDuration 0.1
#define kWiggleRotateDurationVariance 0.025

-(void)startWiggling {
    [UIView animateWithDuration:0
                     animations:^{
                         [self.layer addAnimation:[self rotationAnimation] forKey:@"rotation"];
                         [self.layer addAnimation:[self bounceAnimation] forKey:@"bounce"];
                         self.transform = CGAffineTransformIdentity;
                     }];
}

-(CAAnimation*)rotationAnimation {
    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.values = @[@(-kWiggleRotateAngle), @(kWiggleRotateAngle)];

    animation.autoreverses = YES;
    animation.duration = [self randomizeInterval:kWiggleRotateDuration
                                    withVariance:kWiggleRotateDurationVariance];
    animation.repeatCount = HUGE_VALF;

    return animation;
}

-(CAAnimation*)bounceAnimation {
    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    animation.values = @[@(kWiggleBounceY), @(0.0)];

    animation.autoreverses = YES;
    animation.duration = [self randomizeInterval:kWiggleBounceDuration
                                    withVariance:kWiggleBounceDurationVariance];
    animation.repeatCount = HUGE_VALF;

    return animation;
}

-(NSTimeInterval)randomizeInterval:(NSTimeInterval)interval withVariance:(double)variance {
    double random = (arc4random_uniform(1000) - 500.0) / 500.0;
    return interval + variance * random;
}

I implemented this code on a UICollectionView which had 30 items bouncing and the performance was flawless on an iPad 2.

like image 28
Sebastien Martin Avatar answered Sep 17 '22 04:09

Sebastien Martin


SWIFT :-

let transformAnim  = CAKeyframeAnimation(keyPath:"transform")
transformAnim.values  = [NSValue(CATransform3D: CATransform3DMakeRotation(0.04, 0.0, 0.0, 1.0)),NSValue(CATransform3D: CATransform3DMakeRotation(-0.04 , 0, 0, 1))]
transformAnim.autoreverses = true
transformAnim.duration  = (Double(indexPath.row)%2) == 0 ?   0.115 : 0.105
transformAnim.repeatCount = Float.infinity
self.layer.addAnimation(transformAnim, forKey: "transform")

Objective C :-

-(CAKeyframeAnimation *)wiggleView
{
    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];

    CGFloat wobbleAngle = 0.04f;

    NSValue* valLeft = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];
    NSValue* valRight = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];
    animation.values = [NSArray arrayWithObjects:valLeft, valRight, nil];

    animation.autoreverses = YES;
    animation.duration = 0.125;
    animation.repeatCount = HUGE_VALF;

    return animation;
}
like image 30
Mitul Marsoniya Avatar answered Sep 20 '22 04:09

Mitul Marsoniya