Один из способов решения проблемы - указать внутренние PathGradientBrush
FocusScales , чтобы ограничить спад цвета без ущерба для смешения цветов.
К сожалению 1 Документы на самом деле не описывают, для чего используется это свойство.
Вы можете прочитать более подробное описание здесь: Как: создать градиент пути
К сожалению 2 , код, который должен реализовать , описание отсутствует.
Отклонение можно регулировать по цветным позициям. Поскольку вы указали:
Positions = new float[] { 0.0f, 0.1f, 1.0f }
цветовые спады могут быть установлены на:
brush.FocusScales = new PointF(0.1f, 1.0f);
Горизонтальная шкала может быть скорректирована, но в пределах половины общего измерения, в противном случае смешивание цветов будет нарушено: вы не увидите сглаживание прозрачности на краях фигуры.
Лучший результат достигается также при установке PixelOffsetMode на PixelOffsetMode.Half
.
К сожалению, 3 , описание Документов здесь неверно, обратитесь к документации C ++ об этом параметре .
Общая реализация (с использованием Panel как canvas ):
(Вы можете включить рисование только на событии MouseDown
)
mousePosition
- расположение указателя мыши. Может быть установлен на событие MouseDown
.
private Point mousePosition = Point.Empty;
private float lineSize = 100.0f;
private int shadowDistance = 16;
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
using (var path = new GraphicsPath(FillMode.Winding))
{
PointF[] arrowPoints = new PointF[] {
mousePosition,
new PointF (mousePosition.X - 20f, mousePosition.Y + 10f),
new PointF (mousePosition.X - 20f, mousePosition.Y + 3f),
new PointF (mousePosition.X - lineSize, mousePosition.Y + 3f),
new PointF (mousePosition.X - lineSize, mousePosition.Y - 3f),
new PointF (mousePosition.X - 20f, mousePosition.Y - 3f),
new PointF (mousePosition.X - 20f, mousePosition.Y - 10f)
};
path.AddLines(arrowPoints);
using (var brush = new PathGradientBrush(path.PathPoints, WrapMode.Clamp))
{
var blend = new ColorBlend()
{
Colors = new Color[] { Color.Transparent,
Color.FromArgb(180, Color.DimGray),
Color.FromArgb(180, Color.DimGray) },
Positions = new float[] { 0.0f, 0.2f, 1.0f }
};
brush.FocusScales = new PointF(0.2f, 1.0f);
brush.InterpolationColors = blend;
e.Graphics.FillPath(brush, path);
}
using (var mx = new Matrix())
{
mx.Translate(-shadowDistance, -shadowDistance);
e.Graphics.Transform = mx;
e.Graphics.FillPath(Brushes.Red, path);
}
}
}