Reputation: 63
In my app I want to show a variety of shades of a user defined color. I cannot find UWP methods to do that. Is it possible? I'm programming in C#.
Upvotes: 0
Views: 504
Reputation: 1236
This is not standard supported in the UWP platform, but it's easy to do just using math ;) I've created a helper class to do just that. There is also an extra class for defining the HSV structure. The trick is to get the Hue, Saturation and Brightness (or Value) of the color and then modify the Brightness (Value).
In the class below, call the GetColors
method to get a list of shades for that color.
public class ColorHelper
{
public static List<Windows.UI.Color> GetColors(Windows.UI.Color baseColor, int max)
{
// fill color shades list
List<Windows.UI.Color> colorShades = new List<Windows.UI.Color>();
HSVColor hsv = ColorHelper.RGBtoHSV(baseColor);
hsv.V = 255; // alway use highest brightness to determine collection of shades
double v = hsv.V / max;
for (int i = 0; i < max; i++)
{
hsv.V = v * i;
if (hsv.V > 255) hsv.V = 255;
colorShades.Add(ColorHelper.HSVtoRGB(hsv));
}
return colorShades;
}
public static HSVColor RGBtoHSV(Windows.UI.Color rgb)
{
double max, min, chroma;
HSVColor hsv = new HSVColor();
min = Math.Min(Math.Min(rgb.R, rgb.G), rgb.B);
max = Math.Max(Math.Max(rgb.R, rgb.G), rgb.B);
chroma = max - min;
if (chroma != 0)
{
if (rgb.R == max)
{
hsv.H = (rgb.G - rgb.B) / chroma;
if (hsv.H < 0.0) hsv.H += 6.0;
}
else if (rgb.G == max)
{
hsv.H = ((rgb.B - rgb.R) / chroma) + 2.0;
}
else
{
hsv.H = ((rgb.R - rgb.G) / chroma) + 4.0;
}
hsv.H *= 60.0;
hsv.S = chroma / max;
}
hsv.V = max;
hsv.A = rgb.A;
return hsv;
}
public static Windows.UI.Color HSVtoRGB(HSVColor hsv)
{
double min, chroma, hdash, x;
Windows.UI.Color rgb = new Windows.UI.Color();
chroma = hsv.S * hsv.V;
hdash = hsv.H / 60.0;
x = chroma * (1.0 - Math.Abs((hdash % 2.0) - 1.0));
if (hdash < 1.0)
{
rgb.R = (byte)chroma;
rgb.G = (byte)x;
}
else if (hdash < 2.0)
{
rgb.R = (byte)x;
rgb.G = (byte)chroma;
}
else if (hdash < 3.0)
{
rgb.G = (byte)chroma;
rgb.B = (byte)x;
}
else if (hdash < 4.0)
{
rgb.G = (byte)x;
rgb.B = (byte)chroma;
}
else if (hdash < 5.0)
{
rgb.R = (byte)x;
rgb.B = (byte)chroma;
}
else if (hdash < 6.0)
{
rgb.R = (byte)chroma;
rgb.B = (byte)x;
}
min = hsv.V - chroma;
rgb.R += (byte)min;
rgb.G += (byte)min;
rgb.B += (byte)min;
rgb.A = (byte)hsv.A;
return rgb;
}
}
public class HSVColor
{
public double H { get; set; }
public double S { get; set; }
public double V { get; set; }
public double A { get; set; }
public HSVColor()
{
H = S = V = A = 1.0;
}
}
Upvotes: 1
Reputation: 2361
You can use a LinearGradientBrush or a RadialGradientBrush. You should only need to add two GradientStops to show a range. Set the background of some element to be painted with the gradient brush.
<Page
x:Class="CarServiceLogger.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CarServiceLogger"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<!--{ThemeResource ApplicationPageBackgroundThemeBrush}-->
<Grid >
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="#FF0000" />
<GradientStop Offset="1" Color="#000000" />
</LinearGradientBrush>
</Grid.Background>
</Grid>
</Page>
Upvotes: 0
Reputation: 308
It is a tricky question about shades. Shade should be at least from one color to another. The simplest shade is from selected color to black. You can implement it as changing alpha-channel (transparancy) from 255
to 0
with black color below (background). See shades of blue: https://en.wikipedia.org/wiki/Tints_and_shades#/media/File:Kleurenovergang_van_zwart_naar_blauw.png
Upvotes: 0