From b1dd609f9b20a367457b9728db166cb1801c4ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Rag=C3=A1ny-N=C3=A9meth?= Date: Thu, 14 Jul 2022 18:28:58 +0200 Subject: [PATCH] Add elevated surface colors (#20) --- .../Schemes/DarkSchemeMapper.cs | 6 ++ .../Schemes/LightSchemeMapper.cs | 6 ++ MaterialColorUtilities/Schemes/Scheme.cs | 10 ++++ MaterialColorUtilities/Utils/ColorUtils.cs | 58 +++++++++++++++++++ Playground/Playground.Maui/App.xaml | 22 +++---- Playground/Playground.Shared/AppScheme.cs | 18 +----- .../Playground.Wasm/Services/ThemeService.cs | 6 +- README.md | 20 +++---- 8 files changed, 105 insertions(+), 41 deletions(-) diff --git a/MaterialColorUtilities/Schemes/DarkSchemeMapper.cs b/MaterialColorUtilities/Schemes/DarkSchemeMapper.cs index 13d44ea..da8a664 100644 --- a/MaterialColorUtilities/Schemes/DarkSchemeMapper.cs +++ b/MaterialColorUtilities/Schemes/DarkSchemeMapper.cs @@ -1,4 +1,5 @@ using MaterialColorUtilities.Palettes; +using MaterialColorUtilities.Utils; namespace MaterialColorUtilities.Schemes { @@ -44,6 +45,11 @@ protected override void MapCore(TCorePalette corePalette, TScheme scheme) scheme.InverseSurface = corePalette.Neutral[90]; scheme.InverseOnSurface = corePalette.Neutral[20]; scheme.InversePrimary = corePalette.Primary[40]; + scheme.Surface1 = scheme.Surface.Add(scheme.Primary, .05); + scheme.Surface2 = scheme.Surface.Add(scheme.Primary, .08); + scheme.Surface3 = scheme.Surface.Add(scheme.Primary, .11); + scheme.Surface4 = scheme.Surface.Add(scheme.Primary, .12); + scheme.Surface5 = scheme.Surface.Add(scheme.Primary, .14); } } } diff --git a/MaterialColorUtilities/Schemes/LightSchemeMapper.cs b/MaterialColorUtilities/Schemes/LightSchemeMapper.cs index 70676d8..85f6903 100644 --- a/MaterialColorUtilities/Schemes/LightSchemeMapper.cs +++ b/MaterialColorUtilities/Schemes/LightSchemeMapper.cs @@ -1,4 +1,5 @@ using MaterialColorUtilities.Palettes; +using MaterialColorUtilities.Utils; namespace MaterialColorUtilities.Schemes { @@ -44,6 +45,11 @@ protected override void MapCore(TCorePalette corePalette, TScheme scheme) scheme.InverseSurface = corePalette.Neutral[20]; scheme.InverseOnSurface = corePalette.Neutral[95]; scheme.InversePrimary = corePalette.Primary[80]; + scheme.Surface1 = scheme.Surface.Add(scheme.Primary, .05); + scheme.Surface2 = scheme.Surface.Add(scheme.Primary, .08); + scheme.Surface3 = scheme.Surface.Add(scheme.Primary, .11); + scheme.Surface4 = scheme.Surface.Add(scheme.Primary, .12); + scheme.Surface5 = scheme.Surface.Add(scheme.Primary, .14); } } } diff --git a/MaterialColorUtilities/Schemes/Scheme.cs b/MaterialColorUtilities/Schemes/Scheme.cs index a6278b8..a663535 100644 --- a/MaterialColorUtilities/Schemes/Scheme.cs +++ b/MaterialColorUtilities/Schemes/Scheme.cs @@ -48,6 +48,11 @@ public class Scheme public TColor InverseSurface { get; set; } public TColor InverseOnSurface { get; set; } public TColor InversePrimary { get; set; } + public TColor Surface1 { get; set; } + public TColor Surface2 { get; set; } + public TColor Surface3 { get; set; } + public TColor Surface4 { get; set; } + public TColor Surface5 { get; set; } /// /// Converts the Scheme into a new one with a different color type. @@ -109,6 +114,11 @@ public Scheme ConvertTo(Func convert, Scheme< result.InverseSurface = convert(InverseSurface); result.InverseOnSurface = convert(InverseOnSurface); result.InversePrimary = convert(InversePrimary); + result.Surface1 = convert(Surface1); + result.Surface2 = convert(Surface2); + result.Surface3 = convert(Surface3); + result.Surface4 = convert(Surface4); + result.Surface5 = convert(Surface5); return result; } } diff --git a/MaterialColorUtilities/Utils/ColorUtils.cs b/MaterialColorUtilities/Utils/ColorUtils.cs index 2a1029e..d203488 100644 --- a/MaterialColorUtilities/Utils/ColorUtils.cs +++ b/MaterialColorUtilities/Utils/ColorUtils.cs @@ -49,6 +49,12 @@ public static int ArgbFromRgb(int red, int green, int blue) return (255 << 24) | ((red & 255) << 16) | ((green & 255) << 8) | (blue & 255); } + /// Converts a color from ARGB components to ARGB format. + public static int ArgbFromComponents(int alpha, int red, int green, int blue) + { + return ((alpha & 255) << 24) | ((red & 255) << 16) | ((green & 255) << 8) | (blue & 255); + } + /// Converts a color from linear RGB components to ARGB format. public static int ArgbFromLinrgb(double[] linrgb) { @@ -275,4 +281,56 @@ public static double LabInvf(double ft) return (116 * ft - 16) / kappa; } } + + public static int Add(this int background, int foreground, double foregroundAlpha) + { + int a = (int)(foregroundAlpha * 255); + foreground &= (a << 24) | 0x00FFFFFF; + return Add(background, foreground); + } + + public static int Add(this int background, int foreground) + { + DeconstructArgb(background, + out float bgA, + out float bgR, + out float bgG, + out float bgB); + DeconstructArgb(foreground, + out float fgA, + out float fgR, + out float fgG, + out float fgB); + + float a = fgA + (bgA * (1 - fgA)); + + float r = CompositeComponent(fgR, bgR, fgA, bgA, a); + float g = CompositeComponent(fgG, bgG, fgA, bgA, a); + float b = CompositeComponent(fgB, bgB, fgA, bgA, a); + + return ArgbFromComponents( + (int)(a * 255), + (int)(r * 255), + (int)(g * 255), + (int)(b * 255)); + } + + public static float CompositeComponent(float fgC, float bgC, float fgA, float bgA, float a) + { + if (a == 0) return 0; + return ((fgC * fgA) + (bgC * bgA * (1 - fgA))) / a; + } + + public static void DeconstructArgb( + int argb, + out float a, + out float r, + out float g, + out float b) + { + a = AlphaFromArgb(argb) / 255f; + r = RedFromArgb(argb) / 255f; + g = GreenFromArgb(argb) / 255f; + b = BlueFromArgb(argb) / 255f; + } } diff --git a/Playground/Playground.Maui/App.xaml b/Playground/Playground.Maui/App.xaml index 0a2d60e..be7b59f 100644 --- a/Playground/Playground.Maui/App.xaml +++ b/Playground/Playground.Maui/App.xaml @@ -32,11 +32,11 @@ - - - - - + + + + + @@ -64,11 +64,11 @@ - - - - - + + + + + diff --git a/Playground/Playground.Shared/AppScheme.cs b/Playground/Playground.Shared/AppScheme.cs index c32d454..9b16096 100644 --- a/Playground/Playground.Shared/AppScheme.cs +++ b/Playground/Playground.Shared/AppScheme.cs @@ -1,16 +1,10 @@ -using MaterialColorUtilities.Blend; -using MaterialColorUtilities.Palettes; +using MaterialColorUtilities.Palettes; using MaterialColorUtilities.Schemes; namespace Playground.Shared; public partial class AppScheme : Scheme { - public TColor Elevation1 { get; set; } - public TColor Elevation2 { get; set; } - public TColor Elevation3 { get; set; } - public TColor Elevation4 { get; set; } - public TColor Elevation5 { get; set; } } public class DarkAppSchemeMapper : DarkSchemeMapper> @@ -18,11 +12,6 @@ public class DarkAppSchemeMapper : DarkSchemeMapper> protected override void MapCore(CorePalette corePalette, AppScheme scheme) { base.MapCore(corePalette, scheme); - scheme.Elevation1 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .05); - scheme.Elevation2 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .08); - scheme.Elevation3 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .11); - scheme.Elevation4 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .12); - scheme.Elevation5 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .14); } } @@ -31,10 +20,5 @@ public class LightAppSchemeMapper : LightSchemeMapper scheme) { base.MapCore(corePalette, scheme); - scheme.Elevation1 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .05); - scheme.Elevation2 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .08); - scheme.Elevation3 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .11); - scheme.Elevation4 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .12); - scheme.Elevation5 = Blender.Cam16Ucs(scheme.Background, scheme.Primary, .14); } } \ No newline at end of file diff --git a/Playground/Playground.Wasm/Services/ThemeService.cs b/Playground/Playground.Wasm/Services/ThemeService.cs index a110182..870c1f0 100644 --- a/Playground/Playground.Wasm/Services/ThemeService.cs +++ b/Playground/Playground.Wasm/Services/ThemeService.cs @@ -68,10 +68,10 @@ private static Palette UpdatePalette(Palette palette, AppScheme scheme palette.Secondary = scheme.Secondary; palette.Tertiary = scheme.Tertiary; palette.Background = scheme.Background; - palette.AppbarBackground = scheme.Elevation2; + palette.AppbarBackground = scheme.Surface2; palette.AppbarText = scheme.OnBackground; - palette.DrawerBackground = scheme.Elevation1; - palette.Surface = scheme.Elevation1; + palette.DrawerBackground = scheme.Surface1; + palette.Surface = scheme.Surface1; return palette; } } diff --git a/README.md b/README.md index da5f7e0..e5deb8e 100644 --- a/README.md +++ b/README.md @@ -95,11 +95,11 @@ public static class MauiProgram + + + -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ + + + @@ -127,11 +127,11 @@ public static class MauiProgram + + + -+ -+ -+ -+ -+ ++ ++ ++ ++ ++ ```