Рисование угла / угла / «конического» / «дугообразного» градиента в Objective-C (IOS) с использованием Core Graphics - PullRequest
4 голосов
/ 26 июня 2011

Я пытаюсь нарисовать «конический» / «дугообразный» градиент (я не знаю, каков будет правильный термин для этого) (Фотошоп называет это «угловым» градиентом - ваш дружественный соседский стекопоток редактор) с использованием Objective-C (IOS), почти так же, как изображение, показанное в следующем потоке .

После нескольких дней поиска и поиска в интернете безрезультатно, я решил обратиться за помощью сюда.

Небольшая предыстория того, что я пытаюсь сделать. Моя цель состоит в том, чтобы создать пользовательский UIView, который представляет собой круговую диаграмму выполнения, в основном кольцо, несколько похожее на индикатор активности, как видно в приложении iPhone TweetBot (отображается при перетаскивании для обновления, что можно увидеть в действии здесь , около 17-18 секунд видео, в верхней части экрана iphone). Я хочу, чтобы индикатор прогресса (заливка кольца) представлял собой простой двухцветный градиент, который можно установить программным способом, а размер представления можно изменить.

Заполнение формы кольца градиентом, который «следует» за дугой кольца, - вот где я застрял. Ответы, которые я получаю от поиска в Google, прочтения документации Apple Core Graphics по градиентам и поиска по SO, касаются либо радиальных градиентов, либо линейных / осевых градиентов, чего я не пытаюсь достичь.

В приведенной выше ветке предлагается использовать готовые изображения, но это не вариант, потому что цвета градиента должны быть настраиваемыми, вид должен быть изменяемого размера и заполнение индикатора выполнения не всегда заполнено на 100%. очевидно (что будет состояние градиента, как показано на рисунке в теме выше).

Единственное решение, которое я придумала, - это нарисовать градиент «вручную», поэтому без использования CGGradientRef, обрезая небольшие кусочки градиента с помощью однотонных заливок в круговой траектории. Я не знаю точно, насколько хорошо это будет работать, когда панель анимируется, хотя это не должно быть так плохо, но это может быть проблемой.

Итак, мой первый вопрос:

Есть ли более простое / отличное решение для рисования конического / дугового градиента в Objective-C (IOS), чем решение, которое я придумал?

Второй вопрос:

Если мне нужно нарисовать градиент вручную в моем виде, используя решение, которое я придумала, как я могу определить или рассчитать (если это вообще возможно) значение (HEX или RGBA) каждого среза цвета " «градиента, который я пытаюсь нарисовать, как показано на рисунке ниже.

(Невозможно связать изображение) Иллюстрация среза градиента

Ответы [ 3 ]

3 голосов
/ 27 июня 2011

В указанной выше ветке предлагается использовать готовые изображения, но это не вариант, потому что цвета градиента должны быть настраиваемыми, размер представления должен быть изменяемым, а заполнение индикатора выполнения не всегда заполнено на 100%. очевидно (что будет состояние градиента, как показано на рисунке в теме выше).

Не проблема!

Используйте очень черно-белое изображение из другого вопроса (или более крупную версию, если она вам нужна) следующим образом:

  1. Клип на любую фигуру, в которой вы хотите нарисовать градиент.
  2. Заполните цветом в конце градиента.
  3. Используйте черно-белое градиентное изображение в качестве маски.
  4. Заполните цветом в начале градиента.

Вы можете вращать градиент, поворачивая изображение маски.

Это поддерживает только самый простой случай градиента с цветом на каждом крайнем конце; он не масштабируется до трех или более цветов и не поддерживает необычное позиционирование с градиентом.

2 голосов
/ 26 июня 2011

Выглядит для меня как работа для пиксельного шейдера. Я помню, как видел пример Quartz Composer, который имитировал развертку радара и использовал пиксельный шейдер для создания эффекта, который вы описываете.

Редактировать:

Нашел это. Этот шейдер был написан Питером Граффиньино:

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;
}
0 голосов
/ 17 октября 2011

К вашему сведению: вот также хороший урок для создания круглого индикатора выполнения с использованием рисования Кварц.

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

...