Search code examples
iosobjective-canimationcore-graphicscore-animation

gradient under UIBezierPath animation


I need help with core animation on iOS

I have the following view

enter image description here

I need to animate curve appearance from left to right. This step was achieved by animationWithKeyPath:@"strokeEnd", it works and all is fine.

Also I need to animate the gradient appearance under the curve, which goes from left to right along with the curve appearance

Here is the cut from reference video about the appearance I need to achieve source video gif cut

How can I achieve this?

Layers and paths I have:

(1) gradient curve line - uishapelayer colored gradient - cagradient layer having (1) as mask

(2) closed path layer - path along the (1) curve, but with [path closePath]; gray gradient - cagradient having (2) as mask

(3) animationLayer - layer, added as [self.layer addSublayer:animationLayer] (3) has colored gradien and gray gradient as sublayers

initWithFrame:

    _animationLayer = [CALayer new];
    _animationLayer.frame = frame;
    _animationLayer.masksToBounds = YES;
    [self.layer addSublayer:_animationLayer];

    _path = [self characteristicsGraph:frame];

    _pathLayer = [CAShapeLayer new];
    _pathLayer.frame = frame;
    _pathLayer.path = _path.CGPath;
    _pathLayer.strokeColor = [color CGColor];
    _pathLayer.fillColor = nil;
    _pathLayer.lineWidth = lineW;


    _fillPathLayer = [CAShapeLayer new];
    _fillPathLayer.frame = frame;
    _fillPathLayer.path = [self closePath:_path].CGPath;
    _fillPathLayer.strokeColor = [color CGColor];
    _fillPathLayer.fillColor = [color CGColor];
    _fillPathLayer.masksToBounds = YES;


    _fillGradient = [self gradient:frame];
    _fillGradient.frame = frame;
    _fillGradient.mask = _fillPathLayer;

    _lineGradient = [self lineGradient:frame];
    _lineGradient.frame = frame;
    _lineGradient.mask = _pathLayer;

    [_animationLayer addSublayer:_fillGradient];
    [_animationLayer addSublayer:_lineGradient];

pathLayer animation (animates colored gradient appearance):

self.currentAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
self.currentAnimation.fromValue = @(0);
self.currentAnimation.toValue = @(1);
self.currentAnimation.duration = .5;
[self.pathLayer addAnimation:self.currentAnimation forKey:animationKey];

Gray gradient is static, can't animate it. Will be grateful for help


Solution

  • You could make a mask layer for the gradient layer - just make it a rectangle that expands as the line animates.

    The other problem I noticed if you want to be 100% true to the video is that your gradient will need to be angled along the trend of the chart - notice their chart trends up, and the gradient angle matches.