As in the title stated, I want to to animate some bubbles that travel along a sine curve from the bottom to the top within an UIView using CG/CA or even OpenGL if necessary.
Here is my CA code snippet that works fine, but it's a straight line which is animated. How can I build in the sine curve behaviour ?
- (void)animateBubble:(UIImageView *)imgView {
[UIView beginAnimations:[NSString stringWithFormat:@"%i",imgView.tag] context:nil];
[UIView setAnimationDuration:6];
[UIView setAnimationDelegate:self];
imgView.frame = CGRectMake(imgView.frame.origin.x, 0, imgView.frame.size.width, imgView.frame.size.height);
[UIView commitAnimations];
}
I've already achieved the wanted result with SpriteKit (have a look: http://youtu.be/Gnj3UAD3gQI). The bubbles travel along a sine curve from bottom to the top where the amplitude is within a random range. Moreover, I use the gyroscope sensors to additionally influence the path.
Is this behaviour somehow reproducible with UIKit, CG, CA (if absolutely necessary also with OpenGL) ? Code samples would be wonderful, but any other ideas are also highly appreciated.
To animate along a path, you first need to define that path. If you really need a true sine curve, we can show you how to do that, but it's probably easiest to define something that approximates a sine curve using two quadratic bezier curves:
CGFloat width = ...
CGFloat height = ...
CGPoint startPoint = ...
CGPoint point = startPoint;
CGPoint controlPoint = CGPointMake(point.x + width / 4.0, point.y - height / 4.0);
CGPoint nextPoint = CGPointMake(point.x + width / 2.0, point.y);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:point];
[path addQuadCurveToPoint:nextPoint controlPoint:controlPoint];
point = nextPoint;
controlPoint = CGPointMake(point.x + width / 4.0, point.y + height / 4.0);
nextPoint = CGPointMake(point.x + width / 2.0, point.y);
[path addQuadCurveToPoint:nextPoint controlPoint:controlPoint];
That renders path like so:
Obviously, change startPoint
, width
, and height
to be whatever you want. Or repeat that process of adding more bezier paths if you need more iterations.
Anyway, having defined a path, rather than rendering the path itself, you can create a CAKeyframeAnimation
that animates the position
of the UIView
along that path:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.duration = 1.0;
animation.path = path.CGPath;
[view.layer addAnimation:animation forKey:@"myPathAnimation"];