使用Core Graphics在Objective-C(IOS)中绘制角度/角度/“圆锥形”/“弧形”渐变

时间:2011-06-26 17:20:31

标签: objective-c ios core-graphics gradient quartz-2d

我正在尝试绘制一个“圆锥形”/“弧形”渐变(我不知道这是什么正确的术语)(Photoshop称之为“角度”渐变 - 你友好的邻居stackoverflow编辑)使用Objective-C(IOS),几乎与以下thread中显示的图像完全相同。

经过几天的谷歌搜索和搜索互联网无济于事,我决定在这里寻求帮助。

关于我正在尝试做什么的一点背景。我的目标是创建一个自定义UIView,它是循环进度条,基本上是一个环,有点类似于TweetBot iPhone应用程序中显示的活动指示器(当你拖动刷新时显示,可以在行动中看到{{3}大约在17-18秒内进入视频,在iphone屏幕上方)。我希望进度指示器(环的填充)是一个简单的双色渐变,可以通过编程方式设置,并且视图可以调整大小。

用“跟随”戒指弧度的渐变填充戒指形状是我卡住的地方。我从谷歌搜索获得的答案,阅读Apple的Core Graphics文档关于渐变和搜索SO是关于径向渐变或线性/轴向渐变,这不是我想要实现的。

上面链接的线程建议使用预制图像,但这不是一个选项,因为渐变的颜色应该是可设置的,视图应该可调整大小并且进度条的填充并不总是100%满显然(这将是上面线程中图片中所示的渐变状态)。

我提出的唯一解决方案是“手动”绘制渐变,因此不使用CGGradientRef,在圆形路径内剪切具有单一纯色的渐变的小切片。我不知道当条形图被动画时它的效果如何,它应该不是那么糟糕,但它可能是一个问题。

所以我的第一个问题是:

在Objective-C(IOS)中绘制锥形/弧形渐变是否比我提出的解决方案更容易/不同?

第二个问题:

如果我必须使用我想出的解决方案在我的视图中手动绘制渐变,我如何确定或计算(如果这是可能的话)每个颜色“切片”的值(HEX或RGBA) “我正在尝试绘制的渐变,如下图所示。

(无法链接图片)here

3 个答案:

答案 0 :(得分:3)

  

上面链接的线程建议使用预制图像,但这不是一个选项,因为渐变的颜色应该是可设置的,视图应该可调整大小并且进度条的填充并不总是100%满显然(这将是上面线程中图片中所示的渐变状态)。

没问题!

使用来自其他问题的非常黑白图像(如果需要,可以使用更大的版本),方式如下:

  1. 剪裁到您想要绘制渐变的任何形状。
  2. 在渐变的末尾填充颜色。
  3. Use the black-to-white gradient image as a mask.
  4. 在渐变开始处填充颜色。
  5. 您可以通过旋转蒙版图像来旋转渐变。

    这仅支持最简单的渐变情况,每个极端都有颜色;它不会缩放到三种或更多颜色,也不支持不寻常的渐变停止定位。

答案 1 :(得分:2)

在我看来像是一个像素着色器的工作。我记得看过一个模拟雷达扫描的Quartz Composer示例,它使用了一个像素着色器来产生你所描述的效果。

编辑:

找到它。这个着色器是由Peter Graffignino写的:

kernel vec4 radarSweep(sampler image, __color color1,__color color2, float angle, vec4 rect)
{
    vec4 val = sample(image, samplerCoord(image));
    vec2 locCart = destCoord();
    float theta, r, frac, angleDist;

    locCart.x = (locCart.x - rect.z/2.0) / (rect.z/2.0);
    locCart.y = (locCart.y - rect.w/2.0) / (rect.w/2.0);
    // locCart is now normalized
    theta = degrees(atan(locCart.y, locCart.x));
    theta = (theta < 0.0) ? theta + 360.0 : theta;
    r = length(locCart);
    angleDist = theta - angle;
    angleDist = (angleDist < 0.0) ? angleDist + 360.0 : angleDist;
    frac = 1.0 - angleDist/360.0;
    // sum up 3 decaying phosphors with different time constants
    val = val*exp2(-frac/.005) + (val+.1)*exp2(-frac/.25)*color1 + val*exp2(-frac/.021)*color2;
    val = r > 1.0 ? vec4(0.0, 0.0,0.0,0.0) : val; // constrain to circle
    return val;
}

答案 2 :(得分:0)

仅供参考:这里也是使用Quartz绘图创建循环进度条的好教程。

http://www.turnedondigital.com/blog/quartz-tutorial-how-to-draw-in-quartz/