|
|
While we fix that problem with the generated stroke, maybe you can use a filled path like this:
<Canvas HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Data="M90.000001,0 C139.70563,0 180,40.294373 180,90 L160,90
C160,51.340069 128.65993,20 90.000001,19.999998 51.34007,20 20.000001,51.340069 19.999997,90
L0,90 C7.4505806E-07,40.294373 40.294373,0 90.000001,0 z"
Fill="Red" Height="90" Canvas.Left="-90" Stretch="Fill" Canvas.Top="-90" Width="180"/>
<Path Data="M0,0 L19.999997,0 C20.000001,38.659927 51.34007,70 90.000001,70 128.65993,70 160,38.659927 160,0
L180,0 C180,49.705627 139.70563,90 90.000001,90 40.294373,90 7.4505806E-07,49.705627 0,0 z"
Fill="Green" Height="90" Canvas.Left="-90" Stretch="Fill" Width="180"/>
</Canvas>
|
|
|
Thanks!
The issue is, I also want anti-aliasing. I ended up "simulating" AA by using linear gradient in code. Took me few days (would be nice if it "just works" like in WPF"
Here's what I ended up with that looks proper:
<Ellipse x:Name="ellipsePickerColor" IsHitTestVisible="False" Tag="HT">
<Ellipse.Stroke>
<LinearGradientBrush x:Name="ellipsePickerColorBrush" EndPoint="0.5,1" StartPoint="0.5,0" />
</Ellipse.Stroke>
</Ellipse>
<Ellipse x:Name="ellipsePicker" IsHitTestVisible="False" Tag="HT">
<Ellipse.Stroke>
<RadialGradientBrush x:Name="pickerColor"/>
</Ellipse.Stroke>
</Ellipse>
Code:
float totalWidth = 160f;
float colorWidth = 18f;
float borderWidth = 2f;
SetupColorPicker(ellipsePicker, pickerColor,
ellipsePickerColor, ellipsePickerColorBrush,
totalWidth, colorWidth, borderWidth, Globals.AntiAliasSize);
/// <summary>
/// Creates a color picker with anti-aliased borders from an ellipse and radialgradientbrush attached to it.
/// </summary>
/// <param name="picker">ellipse to init color picker at</param>
/// <param name="brush">radial brush attached to ellipse</param>
/// <param name="pickerColorUnderneath"></param>
/// <param name="pickerColorUnderBrush"></param>
/// <param name="totalWidthEpx">total width of color picker</param>
/// <param name="colorWidthEpx">width of color part</param>
/// <param name="borderWidthEpx">width of two borders around color</param>
/// <param name="aaSize">anti-alias area width</param>
private static void SetupColorPicker(Ellipse picker,
RadialGradientBrush brush,
Ellipse pickerColorUnderneath,
LinearGradientBrush pickerColorUnderBrush,
float totalWidthEpx,
float colorWidthEpx,
float borderWidthEpx,
float aaSize)
{
borderWidthEpx -= aaSize; // remove half the AA (not aaSize * 2) because aa is assumed to add width only through half of itself
if (borderWidthEpx < 0)
{
borderWidthEpx = 0;
}
float radius = totalWidthEpx / 2;
brush.GradientStops = new GradientStopCollection();
GradientStopCollection stops = brush.GradientStops;
float colorStartEpx = aaSize + borderWidthEpx + aaSize + colorWidthEpx;
picker.Width = totalWidthEpx;
picker.Height = totalWidthEpx;
picker.RenderTransform = new TranslateTransform(-radius, -radius);
picker.StrokeThickness = (colorWidthEpx + borderWidthEpx * 2 + aaSize * 4) + 1;
stops.Add(new GradientStop { Offset = 1f - (colorStartEpx + aaSize + borderWidthEpx + aaSize + aaSize) / radius }); // AA
stops.Add(new GradientStop { Offset = 1f - (colorStartEpx + aaSize + borderWidthEpx + aaSize) / radius, Color = Colors.White }); // border
stops.Add(new GradientStop { Offset = 1f - (colorStartEpx + aaSize + aaSize) / radius, Color = Colors.White }); // AA
stops.Add(new GradientStop { Offset = 1f - (colorStartEpx + aaSize) / radius, Color = Color.FromRgb(40, 40, 40) }); // dark border
stops.Add(new GradientStop { Offset = 1f - colorStartEpx / radius }); // picked color
stops.Add(new GradientStop { Offset = 1f - (aaSize + borderWidthEpx + aaSize + aaSize) / radius }); // picked color + AA
stops.Add(new GradientStop { Offset = 1f - (aaSize + borderWidthEpx + aaSize) / radius, Color = Color.FromRgb(40, 40, 40) }); // dark border
stops.Add(new GradientStop { Offset = 1f - (aaSize + borderWidthEpx) / radius, Color = Colors.White }); // border
stops.Add(new GradientStop { Offset = 1f - aaSize / radius, Color = Colors.White }); // AA
stops.Add(new GradientStop { Offset = 1f });
// setup lower ellipse - a linear gradient used to effectively draw 2 arcs
// needed due to Noesis issue:
// "Cannot draw Path to meet two Arc-s: rendering artifacts (WPF OK)" https://www.noesisengine.com/bugs/view.php?id=1404
// At the end lower ellipse will look like:
// <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
// <GradientStop Color="Red" Offset="0"/>
// <GradientStop Color="Red" Offset="0.5"/>
// <GradientStop Color="Green" Offset="0.5"/>
// <GradientStop Color="Green" Offset="1"/>
// </LinearGradientBrush>
pickerColorUnderneath.StrokeThickness = colorWidthEpx + aaSize * 2;
float thicknessDelta = picker.StrokeThickness - pickerColorUnderneath.StrokeThickness;
float colorEllipseSize = totalWidthEpx - thicknessDelta; // this will center stroke
pickerColorUnderneath.Width = colorEllipseSize;
pickerColorUnderneath.Height = colorEllipseSize;
pickerColorUnderneath.RenderTransform = new TranslateTransform(-radius, -radius);
pickerColorUnderBrush.GradientStops = new GradientStopCollection();
GradientStopCollection underStops = pickerColorUnderBrush.GradientStops;
underStops.Add(new GradientStop() { Offset = 0 });
underStops.Add(new GradientStop() { Offset = 0.5f });
underStops.Add(new GradientStop() { Offset = 0.5f });
underStops.Add(new GradientStop() { Offset = 1 });
}
A lot of code to work around AA and the above issue. Pasting it here for information to hopefully influence further Noesis improvements and help others who may be facing similar issue.
Again thank you for the fast response! |