Style Color Methods for Blazor

ו[יעקב] עשה לו [ליוסף] כתונת פסים. (פרשת וישב)

And [Jacob] made him [Joseph] a striped shirt.

I would wager that the best known reference to color in the Torah is found in Genesis 37:3. The King James translation describes Jacob's gift as a coat of many colors, yet the Hebrew phrase may not actually carry that meaning. In Modern Hebrew, the word passim refers to stripes. Some commentators over the centuries have described the coat (or tunic, or robe) as having multicolored stripes, but there is no universal agreement on the translation. In any event, this phrase provides a great title for the musical adaptation of Joseph's life by Andrew Lloyd Weber and Tim Rice.

While working on a new Razor component, I wanted to create a class to store CSS style values that I could pass as a parameter. I incorporate CSS variables in my stylesheets so that I can modify the appearance of components by constructing inline-style strings.

In one case, I wanted to select a base color, and be able to quickly derive both a lighter and darker variant of the color programmatically. Using some simple calculations, I can avoid having to define every single color I employ in my component; I just choose the base color and the variants are generated on the fly. It turns out that this is pretty easy to do if you work with RGB colors. To create a darker shade of a specified color, you can use the following method:


public static Color Shade(this Color color, double percentage = 0.25)
{
	return Color.FromArgb(Round(color.R * percentage), Round(color.G * percentage), Round(color.B * percentage));
}

private static int Round(double d)
{
	return d < 0 ? (int)(d - 0.5) : (int)(d + 0.5);
}

By specifying a percentage (any value between 0.0 and 1.0 - I use 25% or 0.25 as a default), you can generate a darker shade quickly. Note that I've provided a simple rounding method that converts double values to integers. The built-in Math.Round() method didn't quite work as I expected it to, so I whipped up this simple alternative method.

Generating a lighter tint is equally simple. The code for that is:


public static Color Tint(this Color color, double percentage = 0.25)
{
	return Color.FromArgb(Round(color.R + percentage * (255 - color.R)),
    	Round(color.G + percentage * (255 - color.G)), Round(color.B + percentage * (255 - color.B)));
}

Since I'm ultimately passing the colors I generate as hexadecimal string values to the style attribute of my components, I use a simple helper method to convert Color structs to hexadecimal strings:


public static string ToHexString(this Color color)
{
	return $"{color.R:X2}{color.G:X2}{color.B:X2}";
}

Remember to prepend a hash character (#) to the hexadecimal string before passing the color value to the style attribute, otherwise the browser won't know how to interpret it.

A couple of other helper methods that are useful if your base color is expressed as one of the many named colors, or a hexadecimal string:

public static Color NameToColor(string colorName)
{
	var value = Color.FromName(colorName);
    return value.IsNamedColor ? value : default;
}

public static Color HexStringToColor(string hex)
{
	var match = Regex.Match(hex);
    if (match.Success)
    {
    	var hexString = match.Groups[1].Value;
        var intValue = int.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
        return Color.FromArgb(intValue);
	}
    return default;
}

private static readonly Regex Regex = HexRegex();

[GeneratedRegex("^#?([A-Fa-f\\d]{2}[A-Fa-f\\d]{2}[A-Fa-f\\d]{2})$", RegexOptions.Compiled)]
private static partial Regex HexRegex();


No comments:

Post a Comment