21

Core Graphics を使用して iOS 5 で簡単なパスを描画しています。

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(   path, NULL, center.x   , topMargin   );
CGPathAddLineToPoint(path, NULL, center.x+20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x   , topMargin+40);
CGPathAddLineToPoint(path, NULL, center.x-20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x   , topMargin   );

今、次のようにオーバーレイモードで塗りつぶしたいと思います:

[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4] setFill];
CGContextAddPath(context, path);
CGContextSetBlendMode (context, kCGBlendModeOverlay);
CGContextFillPath(context);

これにより、まさに期待される結果が得られます。しかし、次はエンボス効果を作りたいと思います。この効果を実現するために、白と黒のドロップ シャドウを次のように使用することを考えました。

[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

問題は、アルファが 0 に設定されている場合、影が描画されないことです
。ここで質問:塗りつぶしの色を使用せずに完全なアルファで影のみを描画する方法はありますか? どうにかパスの内側が描画されないようにすることはできますか? それとも、1 つのパスに 2 つの影を描く簡単な方法はありますか?

4

1 に答える 1

23

コンテキストのクリッピングパスをシェイプのパスの逆に設定し、シャドウを構成して、シェイプを通常どおり完全に不透明に塗りつぶすことをお勧めします。クリッピングパスは塗りつぶしの色をマスクし、影だけが残ります。

CGContextSaveGState(context);
CGRect boundingRect = CGContextGetClipBoundingBox(context);
CGContextAddRect(context, boundingRect);
CGContextAddPath(context, path);
CGContextEOClip(context);

[[UIColor blackColor] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

CGContextRestoreGState(context);

トリックは、元のパスでカバーされていないCGContextEOClipものにクリッピング領域を設定するために、追加の長方形サブパスを使用することです。これは、自己交差していないすべてのパスで機​​能します。

于 2011-11-17T17:31:14.197 に答える