Sombras de composição

A classe DropShadow fornece meios para criar uma sombra configurável que pode ser aplicada a um SpriteVisual ou LayerVisual (subárvore dos Visuais). Como é habitual para objetos na Camada Visual, todas as propriedades do DropShadow podem ser animadas usando CompositionAnimations.

Sombra básica

Para criar uma sombra básica, basta criar uma nova DropShadow e associá-la ao seu visual. A sombra é retangular por defeito. Existe um conjunto padrão de propriedades para ajustar o aspeto e a sensação da sua sombra.

var basicRectVisual = _compositor.CreateSpriteVisual();
basicRectVisual.Brush = _compositor.CreateColorBrush(Colors.Blue);
basicRectVisual.Offset = new Vector3(100, 100, 20);
basicRectVisual.Size = new Vector2(300, 300);

var basicShadow = _compositor.CreateDropShadow();
basicShadow.BlurRadius = 25f;
basicShadow.Offset = new Vector3(20, 20, 20);

basicRectVisual.Shadow = basicShadow;

Visual Retangular com Sombra Projetada Básica

Moldando a sombra

Existem algumas formas de definir a forma do seu DropShadow:

  • Use o padrão - Por predefinição, a forma DropShadow é definida pelo modo 'Default' no CompositionDropShadowSourcePolicy. Para o SpriteVisual, o padrão é Retangular, a menos que seja fornecida uma máscara. Para o LayerVisual, o padrão é herdar a máscara usando o alfa do pincel do visual.
  • Defina uma máscara – Pode definir a propriedade Máscara para definir uma máscara de opacidade para a sombra.
  • Especifique para usar máscara herdada – Defina a propriedade SourcePolicy para usar CompositionDropShadowSourcePolicy. InheritFromVisualContent para usar a máscara gerada a partir do alfa do pincel do visual.

Mascarar para corresponder ao seu conteúdo

Se quiseres que a tua sombra corresponda ao conteúdo do Visual, podes usar o pincel do Visual para a tua propriedade de máscara de sombra, ou definir a sombra para herdar automaticamente a máscara do conteúdo. Se usar um LayerVisual, a sombra herdará a máscara por defeito.

var imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/myImage.png"));
var imageBrush = _compositor.CreateSurfaceBrush(imageSurface);

var imageSpriteVisual = _compositor.CreateSpriteVisual();
imageSpriteVisual.Size = new Vector2(400,400);
imageSpriteVisual.Offset = new Vector3(100, 500, 20);
imageSpriteVisual.Brush = imageBrush;

var shadow = _compositor.CreateDropShadow();
shadow.Mask = imageBrush;
// or use shadow.SourcePolicy = CompositionDropShadowSourcePolicy.InheritFromVisualContent;
shadow.BlurRadius = 25f;
shadow.Offset = new Vector3(20, 20, 20);

imageSpriteVisual.Shadow = shadow;

Imagem web ligada com sombra oculta mascarada

Utilização de uma máscara alternativa

Em alguns casos, pode querer moldar a sombra de forma a que não corresponda ao conteúdo do seu Visual. Para conseguir este efeito, terás de definir explicitamente a propriedade Máscara usando um pincel com alfa.

No exemplo abaixo, carregamos duas superfícies - uma para o conteúdo visual e outra para a máscara de sombra:

var imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/myImage.png"));
var imageBrush = _compositor.CreateSurfaceBrush(imageSurface);

var circleSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/myCircleImage.png"));
var customMask = _compositor.CreateSurfaceBrush(circleSurface);

var imageSpriteVisual = _compositor.CreateSpriteVisual();
imageSpriteVisual.Size = new Vector2(400,400);
imageSpriteVisual.Offset = new Vector3(100, 500, 20);
imageSpriteVisual.Brush = imageBrush;

var shadow = _compositor.CreateDropShadow();
shadow.Mask = customMask;
shadow.BlurRadius = 25f;
shadow.Offset = new Vector3(20, 20, 20);

imageSpriteVisual.Shadow = shadow;

Imagem web conectada com sombra projetada mascarada em círculo

Animação

Como é padrão na Camada Visual, as propriedades do DropShadow podem ser animadas usando Animações de Composição. Abaixo, ajustamos o código do exemplo de sprinkles acima para animar o raio de desfoque da sombra.

ScalarKeyFrameAnimation blurAnimation = _compositor.CreateScalarKeyFrameAnimation();
blurAnimation.InsertKeyFrame(0.0f, 25.0f);
blurAnimation.InsertKeyFrame(0.7f, 50.0f);
blurAnimation.InsertKeyFrame(1.0f, 25.0f);
blurAnimation.Duration = TimeSpan.FromSeconds(4);
blurAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
shadow.StartAnimation("BlurRadius", blurAnimation);

Sombras no WinUI XAML

Se quiseres adicionar uma sombra a elementos mais complexos do framework, há algumas formas de interoperar com sombras entre o WinUI XAML e o Composition:

  1. Utilize o AttachedCardShadow disponível no pacote CommunityToolkit.WinUI.Media .
  2. Crie um Visual para usar como hospedeiro de sombra e ligue-o ao Visual de transferência em XAML.
  3. Utilize o controlo de "CompositionShadow" da Galeria de Exemplos de Composições SamplesCommon. Veja o exemplo aqui para uso.

Desempenho

Embora a Camada Visual tenha muitas otimizações para tornar os efeitos eficientes e utilizáveis, gerar sombras pode ser uma operação relativamente dispendiosa dependendo das opções definidas. Abaixo estão os 'custos' de nível elevado relativos a diferentes tipos de sombras. Note que, embora certas sombras possam ser caras, podem ainda ser apropriadas para usar com moderação em determinados cenários.

Características das sombras Custo
Retangular Low
Shadow.Mask Alto
ComposiçãoSombraProjetoPolítica.HerdarDaVisualizaçãoConteúdo Alto
Raio de Desfoque Estático Low
Animação do Raio de Desfoque Alto

Recursos adicionais