diff --git a/src/Avalonia.Visuals/Media/ExperimentalAcrylicBrush.cs b/src/Avalonia.Visuals/Media/ExperimentalAcrylicBrush.cs index 99c680ce8b..cda4c1c5a2 100644 --- a/src/Avalonia.Visuals/Media/ExperimentalAcrylicBrush.cs +++ b/src/Avalonia.Visuals/Media/ExperimentalAcrylicBrush.cs @@ -4,6 +4,8 @@ namespace Avalonia.Media { public class ExperimentalAcrylicBrush : Brush, IExperimentalAcrylicBrush { + private Color _effectiveTintColor; + static ExperimentalAcrylicBrush() { AffectsRender( @@ -11,6 +13,16 @@ namespace Avalonia.Media BackgroundSourceProperty, TintOpacityProperty, TintLuminosityOpacityProperty); + + TintColorProperty.Changed.AddClassHandler((b, e) => + { + b._effectiveTintColor = GetEffectiveTintColor(b.TintColor, b.TintOpacity); + }); + + TintOpacityProperty.Changed.AddClassHandler((b, e) => + { + b._effectiveTintColor = GetEffectiveTintColor(b.TintColor, b.TintOpacity); + }); } /// @@ -43,6 +55,8 @@ namespace Avalonia.Media set => SetValue(TintColorProperty, value); } + Color IExperimentalAcrylicBrush.TintColor => _effectiveTintColor; + public double TintOpacity { get => GetValue(TintOpacityProperty); @@ -114,11 +128,8 @@ namespace Avalonia.Media return new HsvColor { Hue = h, Saturation = s, Value = v }; } - public Color GetEffectiveTintColor() + private static Color GetEffectiveTintColor(Color tintColor, double tintOpacity) { - var tintColor = TintColor; - double tintOpacity = TintOpacity; - // Update tintColor's alpha with the combined opacity value double tintOpacityModifier = GetTintOpacityModifier(tintColor); @@ -134,7 +145,7 @@ namespace Avalonia.Media return tintColor; } - double GetTintOpacityModifier(Color tintColor) + private static double GetTintOpacityModifier(Color tintColor) { // This method supresses 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 diff --git a/src/Avalonia.Visuals/Media/IExperimentalAcrylicBrush.cs b/src/Avalonia.Visuals/Media/IExperimentalAcrylicBrush.cs index 3e66d5c863..fdcf6148fe 100644 --- a/src/Avalonia.Visuals/Media/IExperimentalAcrylicBrush.cs +++ b/src/Avalonia.Visuals/Media/IExperimentalAcrylicBrush.cs @@ -11,7 +11,5 @@ namespace Avalonia.Media double TintOpacity { get; } Color FallbackColor { get; } - - Color GetEffectiveTintColor(); } } diff --git a/src/Avalonia.Visuals/Media/ImmutableExperimentalAcrylicBrush.cs b/src/Avalonia.Visuals/Media/ImmutableExperimentalAcrylicBrush.cs index 6765ecae79..ed3f532035 100644 --- a/src/Avalonia.Visuals/Media/ImmutableExperimentalAcrylicBrush.cs +++ b/src/Avalonia.Visuals/Media/ImmutableExperimentalAcrylicBrush.cs @@ -7,7 +7,7 @@ namespace Avalonia.Media public ImmutableExperimentalAcrylicBrush(IExperimentalAcrylicBrush brush) { BackgroundSource = brush.BackgroundSource; - TintColor = brush.GetEffectiveTintColor(); + TintColor = brush.TintColor; TintOpacity = brush.TintOpacity; FallbackColor = brush.FallbackColor; Opacity = brush.Opacity; diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 2c47edbc48..039213aecc 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -705,34 +705,35 @@ namespace Avalonia.Skia return paintWrapper; } - if(brush is IExperimentalAcrylicBrush acrylicBrush) + if (brush is IExperimentalAcrylicBrush acrylicBrush) { - var tintOpacity = - acrylicBrush.BackgroundSource == AcrylicBackgroundSource.Digger ? + var tintOpacity = + acrylicBrush.BackgroundSource == AcrylicBackgroundSource.Digger ? acrylicBrush.TintOpacity : 1; var noiseOpcity = 0.04 * brush.Opacity; - var tintColor = acrylicBrush.GetEffectiveTintColor(); + var tintColor = acrylicBrush.TintColor; var excl = new SKColor(255, 255, 255, (byte)(255 * 0.1)); - var tint = new SKColor(tintColor.R, tintColor.G, tintColor.B, (byte)(255 * ((tintColor.A /255.0) * acrylicBrush.Opacity))); + var tint = new SKColor(tintColor.R, tintColor.G, tintColor.B, (byte)(255 * ((tintColor.A / 255.0) * acrylicBrush.Opacity))); tint = SimpleColorBurn(excl, tint); - var tintShader = SKShader.CreateColor(tint); - var noiseShader = + using (var tintShader = SKShader.CreateColor(tint)) + using (var noiseShader = SKShader.CreatePerlinNoiseTurbulence(15.876f, 15.876f, 2, 0.76829314f) - .WithColorFilter(CreateAlphaColorFilter(noiseOpcity)); + .WithColorFilter(CreateAlphaColorFilter(noiseOpcity))) + using (var compose = SKShader.CreateCompose(tintShader, noiseShader)) + { + paint.Shader = compose; - var compose = SKShader.CreateCompose(tintShader, noiseShader); - paint.Shader = compose; + if (acrylicBrush.BackgroundSource == AcrylicBackgroundSource.Digger) + { + paint.BlendMode = SKBlendMode.Src; + } - if (acrylicBrush.BackgroundSource == AcrylicBackgroundSource.Digger) - { - paint.BlendMode = SKBlendMode.Src; + return paintWrapper; } - - return paintWrapper; } paint.Color = new SKColor(255, 255, 255, (byte) (255 * opacity));