7

Below i have attached image,I want to achieve the below animation.I have tried water wave animation but don't know how to control the animation like the above.

I have CAShapeLayer in which i have to achieve this animation.

enter image description here

Init Code

UIBezierPath *leftPath = [UIBezierPath bezierPath];
// Set the starting point of the shape.
[leftPath moveToPoint:CGPointMake(0,self.bounds.size.height/2)];
// Draw the lines.


[leftPath addLineToPoint:CGPointMake(0,self.bounds.size.height/2)];
[leftPath addLineToPoint:CGPointMake(self.bounds.size.width,self.bounds.size.height/2)];


leftLayer.path = leftPath.CGPath;
leftLayer.strokeColor = [[UIColor whiteColor] CGColor];
leftLayer.fillColor = nil;
leftLayer.borderWidth = 3.0f;
leftLayer.lineCap = kCALineCapRound;
leftLayer.lineJoin = kCALineJoinRound;

leftLayer.borderColor=[UIColor blackColor].CGColor;
[self.layer addSublayer:leftLayer];

Animation Code

-(void)animateCureve{

CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.duration = 3.5;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue = (id)leftLayer.path;
pathAnimation.toValue = (id)[self wavePath].CGPath;
pathAnimation.removedOnCompletion=NO;
[leftLayer addAnimation:pathAnimation forKey:@"path"];
}

The Curve Path

- (UIBezierPath *)wavePath {
//set start and end accordingly

UIBezierPath *startPath = [UIBezierPath bezierPath];
[startPath moveToPoint:CGPointMake(0, self.bounds.size.height/2)];
[startPath addCurveToPoint:CGPointMake(self.bounds.size.width, self.bounds.size.height/2) controlPoint1:CGPointMake(50, self.bounds.size.height/2+0)  controlPoint2:CGPointMake(self.bounds.size.width/2, 20) ];



return startPath;
}
Mukesh
  • 3,680
  • 1
  • 15
  • 32

1 Answers1

2

Taking a closer look at the frames, it looks like a shallow quadratic curve moving along the path. What you could try is define a range for the beginning and ending of the curve, say start and end, and then add the control point in the middle. Then just add the straight lines at both ends afterwards. Something I quickly wrote:

CGFloat start;
CGFloat end;
CGFloat heightOfQuad;
CGFloat mid = (start + end)/2;

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(start, 0)];
[path addQuadCurveToPoint:CGPointMake(end, 0) controlPoint:CGPointMake(mid, heightOfQuad)];

UIBezierPath *startPath = [UIBezierPath bezierPath];
[startPath moveToPoint:CGPointMake(0, 0)];
[startPath addLineToPoint:CGPointMake(start, 0)];

UIBezierPath *endPath = [UIBezierPath bezierPath];
[endPath moveToPoint:CGPointMake(end, 0)];
[endPath addLineToPoint:CGPointMake(lengthOfViewHere, 0)];

[startPath appendPath:path];
[startPath appendPath:endPath];

*I haven't tested this out yet, but you can give it a go

UPDATE:

- (UIBezierPath *)wavePath {

    CGFloat mid = (self.start + self.end)/2;
    CGFloat y = self.frame.size.height;

    UIBezierPath *curvePath = [UIBezierPath bezierPath];
    [curvePath moveToPoint:CGPointMake(self.start, y)];
    [curvePath addQuadCurveToPoint:CGPointMake(self.end, y) controlPoint:CGPointMake(mid, y - waveHeight)];

    UIBezierPath *startPath = [UIBezierPath bezierPath];
    [startPath moveToPoint:CGPointMake(0, y)];
    [startPath addLineToPoint:CGPointMake(self.start, y)];

    UIBezierPath *endPath = [UIBezierPath bezierPath];
    [endPath moveToPoint:CGPointMake(self.end, y)];
    [endPath addLineToPoint:CGPointMake(self.frame.size.width, y)];

    [startPath appendPath:curvePath];
    [startPath appendPath:endPath];

    return startPath;
}
- (void)setWavePosition:(CGFloat)wavePosition {

    //from 0.0 to 1.0
    _wavePosition = wavePosition;

    //set start and end accordingly
    CGFloat waveCoordinate = wavePosition * self.frame.size.width;
    self.start = waveCoordinate - waveWidth/2;
    self.end = waveCoordinate + waveWidth/2;

    self.path = [self wavePath].CGPath;
    [self setNeedsDisplay];
}

After playing around some, the code above generates this with position at 0.5, waveHeight at 5.0, and waveWidth of 150.0 in a view width of 200.0: enter image description here

All you should need to do is set wavePosition, and then wavePath will give back the new path.

David Cao
  • 525
  • 3
  • 11
  • Could you tell us what's happening? Where did you put this code? – David Cao Jul 21 '15 at 13:19
  • i cretaed the CAShapeLayer and used CABasicAnimation to animate from and to value path property.I from it was straight path and in topath i used ur path – Mukesh Jul 21 '15 at 13:19
  • I wrote this thinking you had subclassed CAShapeLayer. I was thinking something of more like you had a property keeping track of the wave, and you would set that in the animation property. – David Cao Jul 21 '15 at 13:29
  • Oh, wow, dumb mistake on my part, I've updated the answer. I'm also testing something out on my end, I'll post another update soon – David Cao Jul 21 '15 at 14:09
  • Thnks @DavidCao, i will also try at ma end – Mukesh Jul 21 '15 at 14:51
  • The curve u made is perfect ,but when u animate it doesn't work as shown in image.I have posted the code – Mukesh Jul 23 '15 at 14:11