CAShapeLayer填充另一个CAShapeLayer作为掩码 [英] CAShapeLayer filling with another CAShapeLayer as a mask

查看:105
本文介绍了CAShapeLayer填充另一个CAShapeLayer作为掩码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是用另一个 CAShapeLayer 填充动画一个 CAShapeLayer 。所以,我编写了一些几乎达到我目标的代码。

My question is about filling animation one CAShapeLayer with another CAShapeLayer. So, I wrote some code that almost achieves my goal.

我创建了一个基础层并用另一个填充它。代码如下:

I created a based layer and fill it with another. Code below:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _shapeLayer = [CAShapeLayer layer];
    [self drawBackgroundLayer];
}
// my main/backgound layer
- (void)drawBackgroundLayer {
    _shapeLayer.frame = CGRectMake(0, 0, 250, 250);
    _shapeLayer.lineWidth = 3;
    _shapeLayer.strokeColor = [UIColor blackColor].CGColor;
    _shapeLayer.fillColor = UIColor.whiteColor.CGColor;
    _shapeLayer.path = [UIBezierPath bezierPathWithRect:_shapeLayer.bounds].CGPath;

    [self.view.layer addSublayer:_shapeLayer];

    [self createCircleLayer];

}

创建一个带圆圈的遮罩层进行填充:

Create a circled mask layer for filling:

- (void)createCircleLayer {

    _shapeLayer.fillColor = UIColor.greenColor.CGColor;

    CAShapeLayer *layer = [CAShapeLayer layer];

    CGFloat radius = _shapeLayer.bounds.size.width*sqrt(2)/2;

    layer.bounds = CGRectMake(0, 0, 2*radius, 2*radius);

    layer.position = CGPointMake(_shapeLayer.bounds.size.width/2, _shapeLayer.bounds.size.height/2);

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:radius];
    layer.path = path.CGPath;

    layer.transform = CATransform3DMakeScale(0.1, 0.1, 1);
    _shapeLayer.mask = layer;

}

//我们的结果是下一个]

// our result is next]

所以,让我们为它设置动画。我只是转换图层以填充整个_shapeLayer。

So, let's animate it. I just transform the layer to fill the whole "_shapeLayer".

- (void)animateMaskLayer:(CAShapeLayer *)maskLayer {

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];

    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1, 1, 1.0)];
    animation.duration = 1;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [newLayer addAnimation:animation forKey:@"transform"];
}

现在,我想对这个绿色层做同样的事情(用红色填充)。
但是当我使用面具时,我有红色圆圈和白色背景显然是什么。
我的目标是拥有红色圆圈和绿色背景。像正常填充另一种颜色。
通过使用反向掩码也无济于事。
所以,我只是不知道如何做到这一点。

Now, I want to do the same with this green layer (fill it with red color). But when I use the mask I have red circle and the white background what is obviously. My goal here is to have red circle and green background. Like normal filling with another color. By using inverse mask won't help neither. So, I just have no ideas how to do it.

如果您建议使用:

[_shapeLayer addSublayer:layer];

它不会起作用,因为不仅会有方形但不同的路径而且clipToBounds不是一个选项。

it won't work as there will be not only square but different paths and clipToBounds is not an option.

感谢您的帮助!

推荐答案

所以,解决方案很简单。我只使用两层和一个遮罩层。

So, the solution is simple. I just use two layers and one mask layer.

第一层:红色层我想填充绿色层;

First layer: Red layer I want to fill with green layer;

- (void)drawBackgroundLayer {
    _shapeLayer.frame = CGRectMake(20, 20, 250, 250);
    _shapeLayer.lineWidth = 3;
    _shapeLayer.strokeColor = [UIColor blackColor].CGColor;
    _shapeLayer.lineWidth = 3;
    _shapeLayer.fillColor = UIColor.redColor.CGColor;
    _shapeLayer.path = [UIBezierPath bezierPathWithRect:_shapeLayer.bounds].CGPath;

    [self.view.layer addSublayer:_shapeLayer];
    [self drawUpperLayer];
}

第二层:我用于填充的绿层。

Second Layer: Green Layer I use for filling.

- (void)drawUpperLayer {

    _upperLayer = [CAShapeLayer layer];
    _upperLayer.frame = _shapeLayer.frame;
    _upperLayer.lineWidth = 3;
    _upperLayer.strokeColor = [UIColor blackColor].CGColor;
    _upperLayer.fillColor = UIColor.greenColor.CGColor;
    _upperLayer.path = [UIBezierPath bezierPathWithRect:_shapeLayer.bounds].CGPath;

    [_shapeLayer.superlayer addSublayer:_upperLayer];

}

蒙版图层:

- (void)createMaskLayer {

    CAShapeLayer *layer = [CAShapeLayer layer];
    CGFloat radius = _upperLayer.bounds.size.width*sqrt(2)/2;

    layer.bounds = CGRectMake(0, 0, 2*radius, 2*radius);
    layer.fillColor = UIColor.blackColor.CGColor;

    layer.position = CGPointMake(_upperLayer.bounds.size.width/2, _upperLayer.bounds.size.height/2);

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:radius];
    layer.path = path.CGPath;

    layer.transform = CATransform3DMakeScale(0.1, 0.1, 1);

    _upperLayer.mask = layer;
}

Animate遮罩层:

Animate mask layer:

- (void)animateMaskLayer:(CAShapeLayer *)maskLayer {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1, 1, 1.0)];
    animation.duration = 2;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [maskLayer addAnimation:animation forKey:@"transform"];
}

因此,结果动画:

So, resulted animation:

这篇关于CAShapeLayer填充另一个CAShapeLayer作为掩码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆