简体   繁体   English

CAShapeLayer填充另一个CAShapeLayer作为遮罩

[英]CAShapeLayer filling with another CAShapeLayer as a mask

My question is about filling animation one CAShapeLayer with another CAShapeLayer . 我的问题是关于用另一个CAShapeLayer填充一个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] //我们的结果是下一个]

在此处输入图片说明

So, let's animate it. 因此,让我们对其进行动画处理。 I just transform the layer to fill the whole "_shapeLayer". 我只是变换图层以填充整个“ _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. 所以,我只是不知道该怎么做。

在此处输入图片说明

If you suggest using: 如果您建议使用:

[_shapeLayer addSublayer:layer];

it won't work as there will be not only square but different paths and clipToBounds is not an option. 这将不起作用,因为不仅会有正方形,而且会有不同的路径,并且clipToBounds不是一个选择。

Thank you for any help! 感谢您的任何帮助!

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];

}

Mask Layer: 遮罩层:

- (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 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: 因此,产生了动画: 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM