0

Palimondoのこのサンプル コードを使用しています。これは、CAGradientLayer を CAShapeLayers にマスクする方法を学習する素晴らしいコードです。出力は次のとおりです。

ここに画像の説明を入力

今、私はこのイメージを作成しようとしています:

ここに画像の説明を入力

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

目標は、CoreAnimation を使用してアニメーション化できる 16 個の個別の CAGradientLayer を用意して、一種の「渦巻き」効果を作成することです (PaintCode からの出力を drawRect に配置するだけで機能しますが、問題は、色またはグラデーションをレイヤーに配置するよりも、CoreGraphics を介してアニメーション化する方がはるかに困難です)。

そして、これが出力されます:

70年代のダンスパーティーバージョン…

[UIColor clearColor]数百回の反復の後、この時点の前に、 for を交換しようとしましたwhiteColor(これはサンプル コードが必要とするものではありません)。これが出力されます。

ほとんどそこに...

グラデーションが 2 つしかないことがわかりますが、それがwhiteColorCAGradientLayer に干渉していると私は信じています。

非常に微妙な何かを見逃しているに違いないことはわかっていますが、それが見えないようです。

サンプル コードではclearColor、グラデーションを適切に使用clearColorして表示できるのに、CAShapeLayer にアタッチされた UIBezierPath を使用するとグラデーションが壊れるのはなぜですか?

友人は、別の解決策は、グラデーションの 3 つの円を持ち、基本的にそれらをマスクされた形状上で同心円状に回転させて錯覚を作成することだと言いましたが、どうすればそれができるのか途方に暮れています。

4

1 に答える 1

1

ここにあるものから正確に何が起こっているのかを言うのは難しい. 3 番目の図 (コードに基づく) では、透明な塗りつぶしの周りに不透明な黒いストロークをマスクに描画しているため、それをマスクとして使用すると、ストロークした領域のみがグラデーション レイヤーから "表示" されます (これらがストロークのみであるというヒントは、ストローク留め継ぎが見えることです)。clearColor を whiteColor (不透明) に変更すると、パスの内側の領域もグラデーション レイヤーから見えるようになります (これのヒントは、ストロークがパスの中央に沿って走っているため、線が太く見えることです。したがって、塗りつぶしを「太く」します。また、塗りつぶしによって遮られているため、ストローク留め継ぎも表示されなくなります。)

マスク レイヤーでは、色は関係ありません。重要なのはアルファ チャネル (不透明度) です。これが、whiteColor と blackColor に違いがない理由です。どちらも 1.0 のアルファ値を持ちますが、clearColor のアルファ値は 0.0 です。ヘッダーから:

/* 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;

これが、4 番目の画像でストローク マイターが表示されなくなった理由です。マスクはアルファ チャネルのみを見て、色相 (つまり、白または黒) に関係なく、両方ともアルファでペイントするという事実によって隠されています。 1.0の。

繰り返しますが、ここで最終的に何をしようとしているのかは明確ではありませんが、whiteColor の使用は赤いニシンのように感じます。目的が 2 番目の画像のように見えるものである場合は、次のように、マスク レイヤーにストロークと不透明な塗りつぶしを含めないことをお勧めします。

gradientMask.fillColor = [[UIColor blackColor] CGColor];
gradientMask.strokeColor = [[UIColor clearColor] CGColor];
于 2013-07-30T13:17:42.487 に答える