private static RgbColour ContrastColours2(RgbColour colour, RgbColour dark, RgbColour light) { var ratioForLightOnColour = GetContrastRatio(colour, light); var ratioForDarkOnColour = GetContrastRatio(colour, dark); return(ratioForDarkOnColour >= ratioForLightOnColour ? dark : light); }
public void CheckContrastRatioFailsWcag() { RgbColour c1 = new RgbColour(0x80, 0x00, 0x80); RgbColour c2 = new RgbColour(0x66, 0x33, 0x99); GetContrastRatio(c1, c2).ShouldBe(1.12d, 0.01d); }
public void CheckContrastRatioPassesWcag() { RgbColour c1 = new RgbColour(0, 255, 0); RgbColour c2 = new RgbColour(0, 0, 0); GetContrastRatio(c1, c2).ShouldBe(15.3d, 0.01d); }
public static void Main(string[] args) { for (byte r = 0; r <= 254; r++) { for (byte g = 0; g <= 254; g++) { for (byte b = 0; b <= 254; b++) { var brandColourToCheck = new RgbColour(r, g, b); var secondary = GetSecondaryNavFromBrandColour(brandColourToCheck); var contrastRatio = GetContrastRatio(secondary.Item1, secondary.Item2); if (!PassesAA(contrastRatio, true)) { Console.WriteLine( $"Fail at large/bold size! Ratio {contrastRatio:F} for brand colour {PrintColour(brandColourToCheck)}"); } else if (!PassesAA(contrastRatio, false)) { Console.WriteLine( $"Fail at small size! Ratio {contrastRatio:F} for brand colour {PrintColour(brandColourToCheck)}"); } } } } }
public static RgbColour ScreenColours(RgbColour c1, RgbColour c2) { var c1I = Invert(c1); var c2I = Invert(c2); var product = MultiplyColours(c1I, c2I); return(Invert(product)); }
public void ToString_Should_Be_Correct_Format(RgbColour colour) { // Arrange var expected = $"rgb({colour.Red}, {colour.Green}, {colour.Blue})"; // Act & Assert colour.ToString().Should().Be(expected); }
public void ExampleBadColour() { var c1 = new RgbColour(0x02, 0x63, 0x7D); var secondaryColours = GetSecondaryNavFromBrandColour(c1); Console.WriteLine(PrintColour(c1)); Console.WriteLine(PrintColour(secondaryColours.Item1)); Console.WriteLine(PrintColour(secondaryColours.Item2)); }
/// <summary> /// Returns secondary BG colour (Item1) and contrast/text colour (Item2) /// </summary> /// <param name="c">Brand colour</param> /// <returns>Tuple of 2 colours</returns> public static Tuple <RgbColour, RgbColour> GetSecondaryNavFromBrandColour(RgbColour c) { var secondaryColour = ScreenColours(c, GetRgbFromHls(AdjustLightness(Black, 0.3))); //var textColour = new RgbColour(0x38, 0x38, 0x38); var textColour = new RgbColour(0, 0, 0); var secondaryContrastColour = ContrastColours(secondaryColour, textColour, GetRgbFromHls(White), 0.5); return(new Tuple <RgbColour, RgbColour>(secondaryColour, secondaryContrastColour)); }
public void Two_Objects_Given_Same_Constructor_Args_Should_Be_Equal(RgbValue red, RgbValue green, RgbValue blue) { // Arrange & Act var a = new RgbColour(red, green, blue); var b = new RgbColour(red, green, blue); // Assert a.Should().Be(b); }
public void Constructor_Given_Args_Sets_Properties(RgbValue red, RgbValue green, RgbValue blue) { // Arrange & Act var actual = new RgbColour(red, green, blue); // Assert actual.Red.Should().Be(red); actual.Green.Should().Be(green); actual.Blue.Should().Be(blue); }
public void CheckMultiplyColours() { // multiply(#ff6600, #00ff00) = #006600 RgbColour c1 = new RgbColour(0xff, 0x66, 0x00); RgbColour c2 = new RgbColour(0x00, 0xff, 0x00); var result = MultiplyColours(c1, c2); result.R.ShouldBe((byte)0); result.G.ShouldBe((byte)0x66); result.B.ShouldBe((byte)0); }
public void CheckScreenColours() { // screen(#ff6600, #999999) = #ffc299 RgbColour c1 = new RgbColour(0xff, 0x66, 0x00); RgbColour c2 = new RgbColour(0x99, 0x99, 0x99); var result = ScreenColours(c1, c2); result.R.ShouldBe((byte)0xff); result.G.ShouldBe((byte)0xc2); result.B.ShouldBe((byte)0x99); }
public static double GetContrastRatio(RgbColour c1, RgbColour c2) { var luma2 = GetRelativeLuminance(c2); var luma1 = GetRelativeLuminance(c1); if (luma1 < luma2) { var temp = luma1; luma1 = luma2; luma2 = temp; } return((luma1 + 0.05) / (luma2 + 0.05)); }
public void CheckRgbToHsl() { var rgb = new RgbColour(170, 0, 255); var hslFromRgb = GetHslFromRgb(rgb); hslFromRgb.H.ShouldBe((short)280); hslFromRgb.S.ShouldBe(1.0, 0.1); hslFromRgb.L.ShouldBe(0.5, 0.1); var rgb2 = GetRgbFromHls(hslFromRgb); rgb2.R.ShouldBe(rgb.R); rgb2.G.ShouldBe(rgb.G); rgb2.B.ShouldBe(rgb.B); }
public void TestSbTwo8861CommentFromSara() { var brandColour = new RgbColour(0x2E, 0xAF, 0xDF); var secondaryColourExpected = new RgbColour(0x6D, 0xC7, 0xE9); var computed = GetSecondaryNavFromBrandColour(brandColour); computed.Item1.R.ShouldBe(secondaryColourExpected.R); computed.Item1.G.ShouldBe(secondaryColourExpected.G); computed.Item1.B.ShouldBe(secondaryColourExpected.B); var matchesCodepenBehaviour = computed.Item2.R == 255 && computed.Item2.G == 255 && computed.Item2.B == 255; matchesCodepenBehaviour.ShouldBeFalse(); computed.Item2.R.ShouldBe(computed.Item2.G); computed.Item2.B.ShouldBe(computed.Item2.G); }
private static RgbColour ContrastColours(RgbColour colour, RgbColour dark, RgbColour light, double bias) { double relativeLumaColour = GetRelativeLuminance(colour); double relativeLumaDark = GetRelativeLuminance(dark); double relativeLumaLight = GetRelativeLuminance(light); if (relativeLumaDark > relativeLumaLight) { var temp = dark; dark = light; light = temp; } if (relativeLumaColour < bias) { return(light); } return(dark); }
public void TestExistingSitesFromJsonImport() { var file = "brand.csv"; var csvLines = File.ReadAllLines(file).ToList(); var jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore }); var results = csvLines.Skip(1).Select(line => { var indexOfFirstComma = line.IndexOf(",", StringComparison.Ordinal); var json = line.Substring(indexOfFirstComma + 2).TrimEnd('"').Replace("\"\"", "\""); var site = line.Substring(0, indexOfFirstComma).Trim('"'); var jsonReader = new JsonTextReader(new StringReader(json)); var settings = jsonSerializer.Deserialize <SitebuilderSiteSettings>(jsonReader); if (!string.IsNullOrWhiteSpace(settings.BrandColour)) { settings.BrandColour = settings.BrandColour.TrimStart('#'); var r = byte.Parse(settings.BrandColour.Substring(0, 2), NumberStyles.HexNumber); var g = byte.Parse(settings.BrandColour.Substring(2, 2), NumberStyles.HexNumber); var b = byte.Parse(settings.BrandColour.Substring(4, 2), NumberStyles.HexNumber); var brandColourToCheck = new RgbColour(r, g, b); var secondary = GetSecondaryNavFromBrandColour(brandColourToCheck); var contrastRatio = GetContrastRatio(secondary.Item1, secondary.Item2); //Console.WriteLine(site+"\t#"+settings.BrandColour.ToUpper()+"\t"+secondary.Item1+"\t"+secondary.Item2+"\t"+contrastRatio); return(new Tuple <string, bool>(site, PassesAA(contrastRatio, false))); } return(null); }).Where(t => t != null).Where(r => !r.Item2).ToList(); foreach (var result in results) { Console.WriteLine($"{result.Item1} = {(result.Item2 ? "true" : "false")}"); } }
public void CheckId7SecondaryNavCalculation() { RgbColour brandRgbColour = new RgbColour(0x15, 0x62, 0x94); var tuple = GetSecondaryNavFromBrandColour(brandRgbColour); RgbColour secondaryRgbColour = tuple.Item1; secondaryRgbColour.R.ShouldBe((byte)0x5b); secondaryRgbColour.G.ShouldBe((byte)0x91); secondaryRgbColour.B.ShouldBe((byte)0xb4); var textColour = tuple.Item2; textColour.R.ShouldBe((byte)0x38); textColour.G.ShouldBe((byte)0x38); textColour.B.ShouldBe((byte)0x38); var contrast = GetContrastRatio(secondaryRgbColour, textColour); contrast.ShouldBe(3.4362, 0.01); PassesAA(contrast, isLargeOrBold: false).ShouldBe(false); PassesAA(contrast, isLargeOrBold: true).ShouldBe(true); // size >= 18pt or size >= 15 pt & bold }
public void TestAllPossibleColours() { for (byte r = 0; r <= 254; r++) { for (byte g = 0; r <= 254; r++) { for (byte b = 0; r <= 254; r++) { var brandColourToCheck = new RgbColour(r, g, b); var secondary = GetSecondaryNavFromBrandColour(brandColourToCheck); var contrastRatio = GetContrastRatio(secondary.Item1, secondary.Item2); if (!PassesAA(contrastRatio, false)) { Console.WriteLine("Fail at small size! " + contrastRatio + " for brand colour " + PrintColour(brandColourToCheck)); } else if (!PassesAA(contrastRatio, true)) { Console.WriteLine("Fail at large/bold size! " + contrastRatio + " for brand colour " + PrintColour(brandColourToCheck)); } } } } }
private static RgbColour Invert(RgbColour c1) { return(new RgbColour((byte)(255 - c1.R), (byte)(255 - c1.G), (byte)(255 - c1.B))); }
public static string PrintColour(RgbColour brandColourToCheck) { return($"#{brandColourToCheck.R:X2}{brandColourToCheck.G:X2}{brandColourToCheck.B:X2}"); }
public static RgbColour MultiplyColours(RgbColour c1, RgbColour c2) { return(new RgbColour((byte)(c1.R * c2.R / 255), (byte)(c1.G * c2.G / 255), (byte)(c1.B * c2.B / 255))); }
// http://james-ramsden.com/convert-from-hsl-to-rgb-colour-codes-in-c/ public static HslColour GetHslFromRgb(RgbColour c) { // Convert RGB to a 0.0 to 1.0 range. double doubleR = c.R / 255.0; double doubleG = c.G / 255.0; double doubleB = c.B / 255.0; // Get the maximum and minimum RGB components. double max = doubleR; if (max < doubleG) { max = doubleG; } if (max < doubleB) { max = doubleB; } double min = doubleR; if (min > doubleG) { min = doubleG; } if (min > doubleB) { min = doubleB; } double diff = max - min; double l = (max + min) / 2; double doubleH = 0; double s; if (Math.Abs(diff) < 0.00001) { s = 0; doubleH = 0; // H is really undefined. } else { if (l <= 0.5) { s = diff / (max + min); } else { s = diff / (2 - max - min); } double r_dist = (max - doubleR) / diff; double g_dist = (max - doubleG) / diff; double b_dist = (max - doubleB) / diff; if (doubleR == max) { doubleH = (b_dist - g_dist); } else if (doubleG == max) { doubleH = (2 + r_dist - b_dist); } else { doubleH = (4 + g_dist - r_dist); } doubleH = (doubleH * 60); if (doubleH < 0) { doubleH += 360; } } return(new HslColour((short)doubleH, s, l)); }
public static double GetRelativeLuminance(RgbColour c) { return(GetRelativeLuminance(c.R, c.G, c.B)); }