ios – 从圆圈或环形中绘制线段

我一直在试图找出一种方法来绘制段,如下图所示:

我想:

>绘制线段
>包括渐变
>包括阴影
>从0到n角动画绘制

我一直在尝试这样做与CGContextAddArc和类似的调用,但没有得到很远。

任何人可以帮助?

你的问题有很多部分。

获得路径

为这样的段创建路径不应该太难。有两个弧和两条直线。我已经previously explained how you can break down a path like that,所以我不会在这里做。相反,我会是花哨的,通过抚摸另一条路径创建路径。你当然可以自己读取细目并构建路径。我所说的抚摸弧是在灰色虚线最终结果内的橙色弧。

为了描绘我们首先需要的路径。基本上就是移动到起始点,并从当前角度到想要分段覆盖的角度围绕中心绘制圆弧。

CGMutablePathRef arc = CGPathCreateMutable();
CGPathMoveToPoint(arc, NULL,
                  startPoint.x, startPoint.y);
CGPathAddArc(arc, NULL,
             centerPoint.x, centerPoint.y,
             radius,
             startAngle,
             endAngle,
             YES);

然后,当你有这个路径(单弧),你可以创建新的段通过抚摸它一定的宽度。结果路径将具有两条直线和两条弧线。行程从中心发生相等的向内和向外的距离。

CGFloat lineWidth = 10.0;
CGPathRef strokedArc =
    CGPathCreateCopyByStrokingPath(arc, NULL,
                                   lineWidth,
                                   kCGLineCapButt,
                                   kCGLineJoinMiter, // the default
                                   10); // 10 is default miter limit

画画

接下来是绘图,通常有两个主要选择:绘制CoreRect中的核心图形或具有核心动画的形状图层。核心图形将给你更强大的绘图,但核心动画会给你更好的动画性能。因为路径涉及纯Cora动画将不工作。你最终会得到奇怪的文物。然而,我们可以通过绘制图层的图形上下文来使用图层和Core Graphics的组合。

填充和抚摸线段

我们已经有了基本的形状,但在我们添加渐变和阴影之前,我将做一个基本的填充和笔画(你的图像中有一个黑色的笔触)。

CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddPath(c, strokedArc);
CGContextSetFillColorWithColor(c, [UIColor lightGrayColor].CGColor);
CGContextSetStrokeColorWithColor(c, [UIColor blackColor].CGColor);
CGContextDrawPath(c, kCGPathFillStroke);

这将把这样的东西放在屏幕上

添加阴影

我要改变顺序,在渐变之前做阴影。要绘制阴影,我们需要为上下文配置阴影,并绘制填充形状以使用阴影绘制阴影。然后我们需要恢复上下文(到阴影之前),并再次敲击形状。

CGColorRef shadowColor = [UIColor colorWithWhite:0.0 alpha:0.75].CGColor;
CGContextSaveGState(c);
CGContextSetShadowWithColor(c,
                            CGSizeMake(0, 2), // Offset
                            3.0,              // Radius
                            shadowColor);
CGContextFillPath(c);
CGContextRestoreGState(c);

// Note that filling the path "consumes it" so we add it again
CGContextAddPath(c, strokedArc);
CGContextStrokePath(c);

在这一点上,结果是这样的

绘制渐变

对于渐变,我们需要一个渐变层。我在这里做一个非常简单的两个颜色渐变,但你可以自定义它所有你想要的。要创建渐变,我们需要获得颜色和合适的颜色空间。然后我们可以在填充顶部绘制渐变(但在笔画之前)。我们还需要将梯度屏蔽到与之前相同的路径。为此,我们剪切路径。

CGFloat colors [] = {
    0.75, 1.0, // light gray   (fully opaque)
    0.90, 1.0  // lighter gray (fully opaque)
};

CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceGray(); // gray colors want gray color space
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;

CGContextSaveGState(c);
CGContextAddPath(c, strokedArc);
CGContextClip(c);

CGRect boundingBox = CGPathGetBoundingBox(strokedArc);
CGPoint gradientStart = CGPointMake(0, CGRectGetMinY(boundingBox));
CGPoint gradientEnd   = CGPointMake(0, CGRectGetMaxY(boundingBox));

CGContextDrawLinearGradient(c, gradient, gradientStart, gradientEnd, 0);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(c);

这将完成绘图,因为我们目前有这个结果

动画

当涉及到形状的动画,它有all been written before: Animating Pie Slices Using a Custom CALayer.如果你尝试通过简单的动画的路径属性绘制,你会看到一些真正有趣的变形的路径在动画期间。为了说明的目的,阴影和渐变在下面的图像中保持完整。

我建议你采取我在这个答案中发布的绘图代码,并采纳它的动画代码从那篇文章。然后你应该得到你要的东西。

供参考:使用Core Animation的相同绘图

平原形状

CAShapeLayer *segment = [CAShapeLayer layer];
segment.fillColor = [UIColor lightGrayColor].CGColor;
segment.strokeColor = [UIColor blackColor].CGColor;
segment.lineWidth = 1.0;
segment.path = strokedArc;

[self.view.layer addSublayer:segment];

添加阴影

图层有一些阴影相关的属性,它是由你来自定义。无论你应该设置shadowPath属性以提高性能。

segment.shadowColor = [UIColor blackColor].CGColor;
segment.shadowOffset = CGSizeMake(0, 2);
segment.shadowOpacity = 0.75;
segment.shadowRadius = 3.0;
segment.shadowPath = segment.path; // Important for performance

绘制渐变

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.colors = @[(id)[UIColor colorWithWhite:0.75 alpha:1.0].CGColor,  // light gray
                    (id)[UIColor colorWithWhite:0.90 alpha:1.0].CGColor]; // lighter gray
gradient.frame = CGPathGetBoundingBox(segment.path);

如果我们绘制渐变现在它将在形状的顶部,而不是在它内部。不,我们不能有一个渐变填充的形状(我知道你在想它)。我们需要屏蔽渐变,使它在段外部。为此,我们创建另一个层作为该段的掩码。它必须是另一个层,文档清楚地表明,如果掩码是图层层次结构的一部分,行为是“未定义的”。由于掩模的坐标系统将与梯度的子图层的坐标系统相同,因此我们必须在设置之前平移段形状。

CAShapeLayer *mask = [CAShapeLayer layer];
CGAffineTransform translation = CGAffineTransformMakeTranslation(-CGRectGetMinX(gradient.frame),
                                                                 -CGRectGetMinY(gradient.frame));
mask.path = CGPathCreateCopyByTransformingPath(segment.path,
                                               &translation);
gradient.mask = mask;
http://stackoverflow.com/questions/15866179/draw-segments-from-a-circle-or-donut

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:ios – 从圆圈或环形中绘制线段