首页 文章

使用来自UIBezierPath的CAShapeLayer屏蔽CAGradientLayer时的意外输出

提问于
浏览
0

我正在使用来自Palimondothis sample code:这是学习如何将CAGradientLayer屏蔽到CAShapeLayers上的精彩代码 . 输出如下:

enter image description here

现在我正在尝试创建此图像:

enter image description here

使用PaintCode,我能够获取所有UIBezierPath和渐变颜色并停止并将它们放入多个数组中,并基本上遍历每个数组,将其添加到新的CAShapeLayer和CAGradientLayer中:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self blackPaths];
    [self setupGradients];
    int count = 0;
    for (CAGradientLayer *gradientLayerItem in _individualGradientArrays) {

        CAShapeLayer *gradientMask = [CAShapeLayer layer];
        gradientMask.fillColor = [[UIColor clearColor] CGColor];
        gradientMask.strokeColor = [[UIColor blackColor] CGColor];
        gradientMask.lineWidth = 4;
        gradientMask.frame = CGRectMake(0, 0, _testView.bounds.size.width, _testView.bounds.size.height);
        //
        //    CGMutablePathRef t = CGPathCreateMutable();
        //    CGPathMoveToPoint(t, NULL, 0, 0);
        //    CGPathAddLineToPoint(t, NULL, _testView.bounds.size.width, _testView.bounds.size.height);

        gradientMask.path = [[_UIBezierPathsArray objectAtIndex:count]CGPath];


        CAGradientLayer *gradientLayer = [CAGradientLayer layer];
        gradientLayer.locations = gradientLayerItem.locations;
        gradientLayer.startPoint = CGPointMake(0.5,1.0);
        gradientLayer.endPoint = CGPointMake(1.0,0.5);
        gradientLayer.frame = CGRectMake(0, 0, _testView.bounds.size.width, _testView.bounds.size.height);
        //    NSMutableArray *colors = [NSMutableArray array];
        //    for (int i = 0; i < 3; i++) {
        //        [colors addObject:(id)[[UIColor colorWithHue:(0.2 * i) saturation:1 brightness:.8 alpha:1] CGColor]];
        //    }
        gradientLayer.colors = gradientLayerItem.colors;

        [gradientLayer setMask:gradientMask];
        [_testView.layer addSublayer:gradientLayer];
        count++;
    }

[_testView setNeedsDisplay];

我的目标是拥有16个单独的CAGradientLayer,我可以使用CoreAnimation创建一种“旋转”效果(我可以将PaintCode的输出放入drawRect,它可以工作,问题是我被告知我会通过CoreGraphics制作颜色或渐变的动画要困难得多,而不是将它们放在图层中 .

然后,这是输出:

The 70's dance party version...

在100次迭代之后,在此之前,我尝试将 [UIColor clearColor] 替换为 whiteColor (这不是示例代码所需的)并输出:

almost there...

你可以看到只有几个渐变,我相信 whiteColor 正在干扰CAGradientLayer .

我知道我必须遗漏一些非常微妙的东西,但我似乎无法看到它 .

为什么在示例代码中,我们能够使用 clearColor 并且适当地显示渐变,但是使用带有我的UIBezierPath 's attached to my CAShapeLayer'的 clearColor 渐变会破坏?

一位朋友提到另一个解决方案是拥有3个渐变圆圈,并且基本上将它们同心地旋转在蒙面形状上,从而产生幻觉,但是我不知道如何能够做到这一点 .

1 回答

  • 1

    从这里到底发生了什么事情很难说 . 在第三张图片中(基于您的代码),您在遮罩的清晰填充周围绘制不透明的黑色笔触,因此当您将其用作遮罩时,只有您抚摸的区域才会从渐变层“可见”(这些只是笔画的提示是你可以看到中风的韵律) . 当您将clearColor更改为whiteColor(不透明)时,路径中的区域也会从渐变层变为可见(提示这是由于笔划沿着路径中间运行,线条看起来更胖)因此,“填充”填充物 . 此外,因为它们被填充物堵塞,所以不再可以看到中风杆 . )

    在遮罩层中,颜色无关紧要 - 重要的是alpha通道(不透明度) . 这就是为什么whiteColor与blackColor没有区别 . 它们的alpha值均为1.0,而clearColor的alpha值为0.0 . 从 Headers :

    /* A layer whose alpha channel is used as a mask to select between the
     * layer's background and the result of compositing the layer's
     * contents with its filtered background. Defaults to nil. When used as
     * a mask the layer's `compositingFilter' and `backgroundFilters'
     * properties are ignored. When setting the mask to a new layer, the
     * new layer must have a nil superlayer, otherwise the behavior is
     * undefined. */
    
    @property(retain) CALayer *mask;
    

    这就是为什么你不再在第四张图片中看到笔画效果的原因 - 它们被掩盖只看到alpha通道并且不管色调(即白色或黑色)它们都用alpha绘制的事实所隐藏1.0 .

    再说一次,目前还不清楚你到底想要做什么,但你对whiteColor的使用感觉就像红鲱鱼 . 如果您的目标看起来像第二个图像,您可能希望您的遮罩层没有笔触和不透明填充,如:

    gradientMask.fillColor = [[UIColor blackColor] CGColor];
    gradientMask.strokeColor = [[UIColor clearColor] CGColor];
    

相关问题