Browse Source

Switch ExperimentalAcrylicMaterial to using new HsvColor

pull/7893/head
robloo 4 years ago
parent
commit
a06d287fb9
  1. 62
      src/Avalonia.Visuals/Media/ExperimentalAcrylicMaterial.cs

62
src/Avalonia.Visuals/Media/ExperimentalAcrylicMaterial.cs

@ -142,52 +142,6 @@ namespace Avalonia.Media
Color IExperimentalAcrylicMaterial.TintColor => _effectiveTintColor;
private struct HsvColor
{
public float Hue { get; set; }
public float Saturation { get; set; }
public float Value { get; set; }
}
private static HsvColor RgbToHsv(Color color)
{
var r = color.R / 255.0f;
var g = color.G / 255.0f;
var b = color.B / 255.0f;
var max = Math.Max(r, Math.Max(g, b));
var min = Math.Min(r, Math.Min(g, b));
float h, s, v;
h = v = max;
var d = max - min;
s = max == 0 ? 0 : d / max;
if (max == min)
{
h = 0; // achromatic
}
else
{
if (max == r)
{
h = (g - b) / d + (g < b ? 6 : 0);
}
else if (max == g)
{
h = (b - r) / d + 2;
}
else if (max == b)
{
h = (r - g) / d + 4;
}
h /= 6;
}
return new HsvColor { Hue = h, Saturation = s, Value = v };
}
private static Color GetEffectiveTintColor(Color tintColor, double tintOpacity)
{
// Update tintColor's alpha with the combined opacity value
@ -198,7 +152,7 @@ namespace Avalonia.Media
private static double GetTintOpacityModifier(Color tintColor)
{
// This method supresses the maximum allowable tint opacity depending on the luminosity and saturation of a color by
// This method suppresses the maximum allowable tint opacity depending on the luminosity and saturation of a color by
// compressing the range of allowable values - for example, a user-defined value of 100% will be mapped to 45% for pure
// white (100% luminosity), 85% for pure black (0% luminosity), and 90% for pure gray (50% luminosity). The intensity of
// the effect increases linearly as luminosity deviates from 50%. After this effect is calculated, we cancel it out
@ -210,22 +164,22 @@ namespace Avalonia.Media
const double midPointMaxOpacity = 0.45; // 50% luminosity
const double blackMaxOpacity = 0.45; // 0% luminosity
var hsv = RgbToHsv(tintColor);
var hsv = tintColor.ToHsv();
double opacityModifier = midPointMaxOpacity;
if (hsv.Value != midPoint)
if (hsv.V != midPoint)
{
// Determine maximum suppression amount
double lowestMaxOpacity = midPointMaxOpacity;
double maxDeviation = midPoint;
if (hsv.Value > midPoint)
if (hsv.V > midPoint)
{
lowestMaxOpacity = whiteMaxOpacity; // At white (100% hsvV)
maxDeviation = 1 - maxDeviation;
}
else if (hsv.Value < midPoint)
else if (hsv.V < midPoint)
{
lowestMaxOpacity = blackMaxOpacity; // At black (0% hsvV)
}
@ -233,14 +187,14 @@ namespace Avalonia.Media
double maxOpacitySuppression = midPointMaxOpacity - lowestMaxOpacity;
// Determine normalized deviation from the midpoint
double deviation = Math.Abs(hsv.Value - midPoint);
double deviation = Math.Abs(hsv.V - midPoint);
double normalizedDeviation = deviation / maxDeviation;
// If we have saturation, reduce opacity suppression to allow that color to come through more
if (hsv.Saturation > 0)
if (hsv.S > 0)
{
// Dampen opacity suppression based on how much saturation there is
maxOpacitySuppression *= Math.Max(1 - (hsv.Saturation * 2), 0.0);
maxOpacitySuppression *= Math.Max(1 - (hsv.S * 2), 0.0);
}
double opacitySuppression = maxOpacitySuppression * normalizedDeviation;

Loading…
Cancel
Save