CAShapeLayer animation with wave animation

Below I have added an image, I want to achieve the animation below. I tried animation of a water wave, but I do not know how to control the animation, as shown above.

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

enter image description here

Initiation 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"]; } 

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; } 
+7
ios animation uibezierpath cashapelayer
source share
1 answer

Looking at the frames, it looks like a shallow quadratic curve moving along the path. What you could try is to define a range for the beginning and end of the curve, such as the beginning and end, and then add a breakpoint in the middle. Then just add straight lines at both ends. 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 have not tested this yet, but you can give it 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 some of them, the code above generates this with a position of 0.5, waveHeight at 5.0 and waveWidth 150.0 with a viewing width of 200.0: enter image description here

All you have to do is set wavePosition and then wavePath will return a new path.

+2
source share

All Articles