Skip to content

Commit

Permalink
feat: ElevatedView on Skia
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Mar 15, 2022
1 parent 487cc9e commit 2180e23
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 5 deletions.
9 changes: 8 additions & 1 deletion src/Uno.UI.Composition/Composition/Compositor.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ private void RenderVisual(SKSurface surface, SKImageInfo info, Visual visual)
{
if (visual.Opacity != 0 && visual.IsVisible)
{
surface.Canvas.Save();
if (visual.ShadowState is { } shadow)
{
surface.Canvas.SaveLayer(shadow.Paint);
}
else
{
surface.Canvas.Save();
}

var visualMatrix = surface.Canvas.TotalMatrix;

Expand Down
39 changes: 39 additions & 0 deletions src/Uno.UI.Composition/Composition/ShadowState.skia.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#nullable enable

using SkiaSharp;
using Windows.UI;

namespace Uno.UI.Composition.Composition;

/// <summary>
/// Captures the state of drop shadow for a visual.
/// </summary>
internal class ShadowState
{
private SKPaint? _paint;

public ShadowState(float dx, float dy, float sigmaX, float sigmaY, Color color)
{
Dx = dx;
Dy = dy;
SigmaX = sigmaX;
SigmaY = sigmaY;
Color = color;
}

public float Dx { get; }

public float Dy { get; }

public float SigmaX { get; }

public float SigmaY { get; }

public Color Color { get; }

public SKPaint Paint =>
_paint ??= new SKPaint()
{
ImageFilter = SKImageFilter.CreateDropShadow(Dx, Dy, SigmaX, SigmaY, Color)
};
}
6 changes: 3 additions & 3 deletions src/Uno.UI.Composition/Composition/Visual.skia.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#nullable enable

#if !__IOS__
using System.Numerics;
using System;
using SkiaSharp;
using Uno.UI.Composition.Composition;

namespace Windows.UI.Composition
{
Expand Down Expand Up @@ -49,6 +48,7 @@ internal int ZIndex
}
}
}

internal ShadowState? ShadowState { get; set; }
}
}
#endif
2 changes: 2 additions & 0 deletions src/Uno.UI.Toolkit/ElevatedView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ private void UpdateElevation()
// The elevation must be applied on the border, since
// it will get the right shape (with rounded corners)
_border.SetElevationInternal(Elevation, ShadowColor);
#elif __SKIA__
this.SetElevationInternal(Elevation, ShadowColor);
#elif NETFX_CORE || NETCOREAPP
_border.SetElevationInternal(Elevation, ShadowColor, _shadowHost as DependencyObject, CornerRadius);
#endif
Expand Down
20 changes: 19 additions & 1 deletion src/Uno.UI.Toolkit/UIElementExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Windows.UI.Xaml.Hosting;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
using Uno.UI.Composition.Composition;

#if HAS_UNO
using Uno.Extensions;
Expand Down Expand Up @@ -142,6 +143,23 @@ internal static void SetElevationInternal(this DependencyObject element, double
uiElement.UnsetCssClasses("noclip");
}
}
#elif __SKIA__
if (element is UIElement uiElement)
{
var visual = uiElement.Visual;

const float SHADOW_SIGMA_X_MODIFIER = 1f / 3.5f;
const float SHADOW_SIGMA_Y_MODIFIER = 1f / 3.5f;
float x = 0.3f;
float y = 0.92f * 0.5f;

var dx = (float)elevation * x;
var dy = (float)elevation * y;
var sigmaX = (float)elevation * SHADOW_SIGMA_X_MODIFIER;
var sigmaY = (float)elevation * SHADOW_SIGMA_Y_MODIFIER;
var shadow = new ShadowState(dx, dy, sigmaX, sigmaY, shadowColor);
visual.ShadowState = shadow;
}
#elif NETFX_CORE || NETCOREAPP
if (element is UIElement uiElement)
{
Expand Down Expand Up @@ -213,7 +231,7 @@ internal static void SetElevationInternal(this DependencyObject element, double
ElementCompositionPreview.SetElementChildVisual(uiHost, spriteVisual);
}
#endif
}
}

#endregion

Expand Down
11 changes: 11 additions & 0 deletions src/Uno.UWP/UI/Color.skia.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using SkiaSharp;

namespace Windows.UI;

public partial struct Color : IFormattable
{
public static implicit operator SKColor(Color color) => new SKColor(color.R, color.G, color.B, color.A);

public static implicit operator Color(SKColor color) => FromArgb(color.Alpha, color.Red, color.Green, color.Blue);
}

0 comments on commit 2180e23

Please sign in to comment.