Поделиться через


Создание градиента пути

Класс PathGradientBrush позволяет настроить способ заполнения фигуры постепенно изменяющимися цветами. Объект PathGradientBrush имеет путь границы и центральную точку. Можно указать один цвет для центральной точки и другой цвет для границы. Можно также указать отдельные цвета для каждой из нескольких точек вдоль границы.

Примечание

В GDI+ путь — это последовательность линий и кривых, поддерживаемых объектом GraphicsPath . Дополнительные сведения о путях GDI+ см. в разделах Пути и Построение и рисование путей.

 

В следующем примере мы заполним эллипс градиентной кистью пути. В качестве центрального цвета задан синий, а для цвета границ — аквамариновый.

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

На рисунке ниже показан заполненный эллипс.

Иллюстрация, показывающая эллипс с градиентной заливкой

По умолчанию кисть градиента пути не работает за пределами пути. Если вы используете кисть градиента пути для заполнения фигуры, которая выходит за пределы пути, область экрана за пределами пути не будет заполнена. На следующем рисунке показано, что произойдет, если изменить вызов Graphics::FillEllipse в предыдущем коде на graphics.FillRectangle(&pthGrBrush, 0, 10, 200, 40).

Иллюстрация, показывающая горизонтальный срез предыдущего эллипса

Указание точек на границе

В следующем примере создается градиентная кисть пути, основанная на пути в форме звезды. Код вызывает метод PathGradientBrush::SetCenterColor, чтобы задать красный цвет в центре star. Затем код вызывает метод PathGradientBrush::SetSurroundColors для указания различных цветов (хранящихся в массиве цветов ) в отдельных точках массива точек . Последняя инструкция кода заполняет контур в форме звезды с помощью кисти градиента пути.

// Put the points of a polygon in an array.
Point points[] = {Point(75, 0),    Point(100, 50), 
                  Point(150, 50),  Point(112, 75),
                  Point(150, 150), Point(75, 100), 
                  Point(0, 150),   Point(37, 75), 
                  Point(0, 50),    Point(50, 50)};

// Use the array of points to construct a path.
GraphicsPath path;
path.AddLines(points, 10);

// Use the path to construct a path gradient brush.
PathGradientBrush pthGrBrush(&path);

// Set the color at the center of the path to red.
pthGrBrush.SetCenterColor(Color(255, 255, 0, 0));

// Set the colors of the points in the array.
Color colors[] = {Color(255, 0, 0, 0),   Color(255, 0, 255, 0),
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255), 
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0), 
                  Color(255, 0, 0, 255), Color(255, 255, 255, 255),
                  Color(255, 0, 0, 0),   Color(255, 0, 255, 0)};

int count = 10;
pthGrBrush.SetSurroundColors(colors, &count);

// Fill the path with the path gradient brush.
graphics.FillPath(&pthGrBrush, &path);

На следующем рисунке показан заполненный star.

Иллюстрация, показывающая пятиконечную star, которая заполняется от красного цвета в центре до различных цветов в каждой точке star

В следующем примере создается кисть градиента пути на основе массива точек. Цвет назначается каждой из пяти точек в массиве. Если бы вы соединили пять точек прямыми линиями, вы бы получили пятистороннего многоугольника. Цвет также назначается центру (центроиду) этого многоугольника. В этом примере центру (80, 75) присваивается белый цвет. Последний оператор кода в примере заполняет прямоугольник кистью градиента пути.

Цвет, используемый для заливки прямоугольника, белый в (80, 75) и меняется постепенно по мере удаления от (80, 75) к точкам в массиве. Например, при переходе от (80, 75) к (0, 0) цвет постепенно меняется с белого на красный, а по мере перехода с (80, 75) на (160, 0) цвет постепенно меняется с белого на зеленый.

// Construct a path gradient brush based on an array of points.
PointF ptsF[] = {PointF(0.0f, 0.0f), 
                 PointF(160.0f, 0.0f), 
                 PointF(160.0f, 200.0f),
                 PointF(80.0f, 150.0f),
                 PointF(0.0f, 200.0f)};

PathGradientBrush pBrush(ptsF, 5);

// An array of five points was used to construct the path gradient
// brush. Set the color of each point in that array.
Color colors[] = {Color(255, 255, 0, 0),  // (0, 0) red
                  Color(255, 0, 255, 0),  // (160, 0) green
                  Color(255, 0, 255, 0),  // (160, 200) green
                  Color(255, 0, 0, 255),  // (80, 150) blue
                  Color(255, 255, 0, 0)}; // (0, 200) red

int count = 5;
pBrush.SetSurroundColors(colors, &count);

// Set the center color to white.
pBrush.SetCenterColor(Color(255, 255, 255, 255));

// Use the path gradient brush to fill a rectangle.
graphics.FillRectangle(&pBrush, Rect(0, 0, 180, 220));

Обратите внимание, что в приведенном выше коде нет объекта GraphicsPath . Конкретный конструктор PathGradientBrush в примере получает указатель на массив точек, но не требует объекта GraphicsPath . Кроме того, обратите внимание, что кисть градиента пути используется для заполнения прямоугольника, а не пути. Прямоугольник больше, чем путь, используемый для определения кисти, поэтому часть прямоугольника не закрашивается кистью. На следующем рисунке показан прямоугольник (пунктирная линия) и часть прямоугольника, закрашенная кистью градиента пути.

Иллюстрация, показывающая прямоугольник, ограниченный пунктирной линией, частично окрашенный многоцветным градиентом

Настройка градиента пути

Одним из способов настройки кисти градиента пути является установка масштабов фокуса. Масштаб фокуса определяет внутренний путь, находящийся внутри основного пути. Цвет для центра отображается везде внутри данного внутреннего пути, а не только в центральной точке. Чтобы задать масштабы фокуса кисти градиента пути, вызовите метод PathGradientBrush::SetFocusScales .

В следующем примере создается кисть градиента пути на основе пути в форме эллипса. Код задает цвет границы синим, цвет центра — аквамариновым, а затем использует кисть градиента пути для заполнения пути в форме эллипса.

Затем код задает масштабы фокуса кисти градиента пути. Для шкалы фокуса x задано значение 0,3, а для y — 0,8. Код вызывает метод Graphics::TranslateTransform объекта Graphics , чтобы последующий вызов Graphics::FillPath заполнял эллипс справа от первого эллипса.

Чтобы понять как работает масштабирование фокуса, представьте себе небольшой эллипс, центр которого совпадает с центром основного эллипса. Малый (внутренний) эллипс масштабируется (примерно по центру) горизонтально на коэффициент 0,3 и вертикально на коэффициент 0,8 от размеров главного эллипса. При переходе от границы внешнего эллипса к границе внутреннего цвет постепенно меняется от синего до аквамаринового. При переходе от границы внутреннего эллипса к общему центру цвет остается аквамариновым.

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 200, 100);

// Create a path gradient brush based on the elliptical path.
PathGradientBrush pthGrBrush(&path);
pthGrBrush.SetGammaCorrection(TRUE);

// Set the color along the entire boundary to blue.
Color color(Color(255, 0, 0, 255));
INT num = 1;
pthGrBrush.SetSurroundColors(&color, &num);

// Set the center color to aqua.
pthGrBrush.SetCenterColor(Color(255, 0, 255, 255));
 
// Use the path gradient brush to fill the ellipse. 
graphics.FillPath(&pthGrBrush, &path);

// Set the focus scales for the path gradient brush.
pthGrBrush.SetFocusScales(0.3f, 0.8f);

// Use the path gradient brush to fill the ellipse again.
// Show this filled ellipse to the right of the first filled ellipse.
graphics.TranslateTransform(220.0f, 0.0f);
graphics.FillPath(&pthGrBrush, &path);

На следующем рисунке показаны выходные данные предыдущего кода. Эллипс слева окрашен аквамариновым цветом только в центральной точке. Эллипс справа окрашен аквамариновым везде внутри внутреннего пути.

иллюстрация, показывающая два эллипса, которые оттеняют от воды до синего: первый имеет очень мало воды; второй имеет гораздо больше

Еще один способ настроить кисть градиента пути — указать массив предустановленных цветов и массив позиций интерполяции.

В следующем примере создается кисть градиента пути на основе пути в форме треугольника. Код вызывает метод PathGradientBrush::SetInterpolationColors кисти градиента пути, чтобы указать массив цветов интерполяции (темно-зеленый, синий, синий) и массив позиций интерполяции (0, 0,25, 1). При переходе от границы треугольника к центральной точке цвет постепенно переходит от темно-зеленого к аквамариновому, а затем от аквамаринового к синему. Изменение с темно-зеленого на аквамариновый происходит на расстоянии, составляющем 25 процентов расстояния от темно-зеленого до синего.

// Vertices of the triangle
Point points[] = {Point(100, 0), 
                  Point(200, 200), 
                  Point(0, 200)};

// No GraphicsPath object is created. The PathGradient
// brush is constructed directly from the array of points.
PathGradientBrush pthGrBrush(points, 3);

Color presetColors[] = {
   Color(255, 0, 128, 0),    // Dark green
   Color(255, 0, 255, 255),  // Aqua
   Color(255, 0, 0, 255)};   // Blue

REAL interpPositions[] = {
   0.0f,   // Dark green is at the boundary of the triangle.
   0.25f,  // Aqua is 25 percent of the way from the boundary
           // to the center point.
   1.0f};  // Blue is at the center point.
                  
pthGrBrush.SetInterpolationColors(presetColors, interpPositions, 3);

// Fill a rectangle that is larger than the triangle
// specified in the Point array. The portion of the
// rectangle outside the triangle will not be painted.
graphics.FillRectangle(&pthGrBrush, 0, 0, 200, 200);

На следующем рисунке показаны выходные данные предыдущего кода.

Иллюстрация, показывающая треугольник, который оттеняется от синего в центре, до воды, до зеленого по краям

Установка центральной точки

По умолчанию центральная точка кисти градиента пути находится в центроиде пути, используемом для создания кисти. Вы можете изменить расположение центральной точки, вызвав метод PathGradientBrush::SetCenterPoint класса PathGradientBrush .

В следующем примере создается кисть градиента пути на основе пути в форме эллипса. Центр эллипса находится в точке (70, 35), но центральная точка кисти градиента пути находится в координатах (120, 40).

// Create a path that consists of a single ellipse.
GraphicsPath path;
path.AddEllipse(0, 0, 140, 70);

// Use the path to construct a brush.
PathGradientBrush pthGrBrush(&path);

// Set the center point to a location that is not the centroid of the path.
pthGrBrush.SetCenterPoint(Point(120, 40));

// Set the color at the center point to blue.
pthGrBrush.SetCenterColor(Color(255, 0, 0, 255));

// Set the color along the entire boundary of the path to aqua.
Color colors[] = {Color(255, 0, 255, 255)};
int count = 1;
pthGrBrush.SetSurroundColors(colors, &count);

graphics.FillEllipse(&pthGrBrush, 0, 0, 140, 70);

На следующем рисунке показан заполненный эллипс и центральная точка кисти градиента пути.

Иллюстрация, показывающая эллипс, который заполняется от синего до воды из центральной точки рядом с одним концом

Центральную точку кисти градиента пути можно установить в координаты за пределами пути, используемого для создания кисти. В приведенном выше коде, если вы замените вызов PathGradientBrush::SetCenterPoint на pthGrBrush.SetCenterPoint(Point(145, 35)), вы получите следующий результат.

Иллюстрация, показывающая эллипс, который заполняется от красного до желтого от центральной точки, которая находится за пределами края эллипса

На предыдущем рисунке точки в крайнем правом углу эллипса не окрашены чистым синим цветом (хотя выглядят очень близко к нему). Цвета в градиенте расположены так, как если бы заливке было разрешено достичь точки (145, 35), цвет достиг бы чисто синего цвета (0, 0, 255). Но заливка никогда не достигает (145, 35), потому что градиентная кисть пути красит только внутри ее пути.