Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
A maioria das aplicações WinUI e Windows App SDK que consomem capacidades da Camada Visual usam XAML para definir o conteúdo principal da interface. O WinUI oferece funcionalidades na framework XAML e na Visual Layer que facilitam a combinação destas duas tecnologias para criar experiências de utilizador impressionantes. Funcionalidades de interoperabilidade XAML e Visual Layer podem ser usadas para criar animações e efeitos avançados que não estão disponíveis apenas com APIs XAML. Isto inclui:
- Efeitos de pincel como desfoque e vidro fosco
- Efeitos de iluminação dinâmica
- Animações baseadas em scroll e paralaxe
- Animações automáticas de layout
- Sombras projetadas perfeitamente em pixel
Estes efeitos e animações podem ser aplicados a conteúdos XAML existentes, por isso não precisa de reestruturar drasticamente a sua aplicação WinUI para tirar partido da funcionalidade. Animações de layout, sombras e efeitos de desfoque estão abordados na secção de Receitas abaixo. Para um exemplo de código que implementa parallax, consulte o exemplo ParallaxingListItems. O repositório WindowsCompositionSamples também tem vários outros exemplos para implementar animações, sombras e efeitos.
A classe XamlCompositionBrushBase
Microsoft.UI.Xaml.Media.XamlCompositionBrushBase fornece uma classe base para pincéis XAML que pintam uma área com um CompositionBrush. Isto pode ser usado para aplicar facilmente efeitos de composição como desfoque ou vidro fosco a elementos da interface XAML.
Consulta a secção de Pincéis para mais informações sobre como usar pincéis com interface XAML.
Para exemplos de código, consulte a página de referência do XamlCompositionBrushBase.
A classe XamlLight
O Microsoft.UI.Xaml.Media.XamlLight fornece uma classe base para efeitos de iluminação XAML que iluminam dinamicamente uma área com um CompositionLight.
Consulte a secção de Iluminação para mais informações sobre o uso de luzes, incluindo elementos de interface XAML de iluminação.
Para exemplos de código, consulte a página de referência do XamlLight.
Trabalhar com WinUI XAML
ElementCompositionPreview é uma classe estática que fornece funcionalidades de interoperabilidade XAML e Visual Layer. Para uma visão geral da Camada Visual e da sua funcionalidade, consulte Camada Visual. A classe ElementCompositionPreview fornece os seguintes métodos de interoperabilidade WinUI:
- GetElementVisual: Obtenha um Visual para entrega que é utilizado na renderização deste elemento
- SetElementChildVisual: Define um Visual "handin" como o último filho da árvore visual deste elemento. Esta visualização irá sobrepor-se ao restante do elemento.
- GetElementChildVisual: Recuperar o conjunto visual usando SetElementChildVisual
- GetScrollViewerManipulationPropertySet: Obtenha um objeto que possa ser usado para criar animações a 60fps baseadas no deslocamento de scroll num ScrollViewer
GetElementVisual
ElementCompositionPreview.GetElementVisual devolve um Visual "handout" que é usado para renderizar o UIElement dado. Propriedades como Visual.Opacity, Visual.Offset e Visual.Size são definidas pelo framework XAML com base no estado do UIElement. Isto permite técnicas como animações de reposicionamento implícito (ver Receitas).
Note que, como o Offset e o Tamanho são definidos como resultado do layout do framework XAML, os programadores devem ter cuidado ao modificar ou animar estas propriedades. Os programadores só devem modificar ou animar o Offset quando o canto superior esquerdo do elemento tiver a mesma posição que o seu pai no layout. O tamanho geralmente não deve ser alterado, mas aceder à propriedade pode ser útil. Por exemplo, as amostras de Sombra Projetada e Vidro Fosco abaixo usam o Tamanho de um Elemento Visual num Folheto como entrada para uma animação.
Como aviso adicional, as propriedades atualizadas do Visual do folheto não serão refletidas no correspondente UIElement. Por exemplo, definir UIElement.Opacity para 0,5 irá definir a Opacidade do Visual do folheto correspondente para 0,5. No entanto, definir a propriedade de Opacidade do Visual do folheto para 0,5 fará com que o conteúdo seja exibido com uma opacidade de 50%, mas não alterará o valor da propriedade de Opacidade correspondente do UIElement.
Exemplo de animação deslocada
Incorreto
<Border>
<Image x:Name="MyImage" Margin="5" />
</Border>
// Doesn’t work because Image has a margin!
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);
Corrigir
<Border>
<Canvas Margin="5">
<Image x:Name="MyImage" />
</Canvas>
</Border>
// This works because the Canvas parent doesn’t generate a layout offset.
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);
SetElementChildVisual
ElementCompositionPreview.SetElementChildVisual permite ao programador fornecer um Visual "de entrega" que aparecerá como parte da Árvore Visual de um elemento. Isto permite aos programadores criar uma "Ilha de Composição" onde conteúdos visuais podem aparecer dentro de uma interface XAML. Os programadores devem ser conservadores na utilização desta técnica, pois o conteúdo visual não terá as mesmas garantias de acessibilidade e experiência de utilizador do conteúdo XAML. Por isso, recomenda-se geralmente que esta técnica só seja usada quando necessário para implementar efeitos personalizados, como os encontrados na secção de Receitas abaixo.
Métodos GetAlphaMask
Image, TextBlock e Shape implementam cada um um método chamado GetAlphaMask que devolve um CompositionBrush representando uma imagem em tons de cinzentos com a forma do elemento. Este CompositionBrush pode servir como entrada para um Composition DropShadow, para que a sombra possa refletir a forma do elemento em vez de um retângulo. Isto permite sombras pixelizadas baseadas em contornos para texto, imagens com alfa e formas. Veja Drop Shadow abaixo para um exemplo desta API.
Receitas
Animação de reposicionamento
Usando Animações Implícitas de Composição, um programador pode animar automaticamente alterações na disposição de um elemento em relação ao seu elemento-pai. Por exemplo, se alterar a Margem do botão abaixo, ele irá animar automaticamente para a nova posição de layout.
Visão geral da implementação
- Obtenha o material visual do elemento-alvo
- Crie uma ImplicitAnimationCollection que anime automaticamente alterações na propriedade Offset
- Associe a ImplicitAnimationCollection ao visual de fundo
<Button x:Name="RepositionTarget" Content="Click Me" />
public MainPage()
{
InitializeComponent();
InitializeRepositionAnimation(RepositionTarget);
}
private void InitializeRepositionAnimation(UIElement repositionTarget)
{
var targetVisual = ElementCompositionPreview.GetElementVisual(repositionTarget);
Compositor compositor = targetVisual.Compositor;
// Create an animation to animate targetVisual's Offset property to its final value
var repositionAnimation = compositor.CreateVector3KeyFrameAnimation();
repositionAnimation.Duration = TimeSpan.FromSeconds(0.66);
repositionAnimation.Target = "Offset";
repositionAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");
// Run this animation when the Offset Property is changed
var repositionAnimations = compositor.CreateImplicitAnimationCollection();
repositionAnimations["Offset"] = repositionAnimation;
targetVisual.ImplicitAnimations = repositionAnimations;
}
Sombra projetada
Aplique uma sombra projetada pixel-perfect a um UIElement, por exemplo, uma Elipse contendo uma imagem. Como a sombra requer um SpriteVisual criado pela aplicação, precisamos de criar um elemento "host" que contenha o SpriteVisual usando ElementCompositionPreview.SetElementChildVisual.
Visão geral da implementação
- Obtenha o folheto Visual para o elemento anfitrião
- Criar um Microsoft.UI.Composition DropShadow
- Configure o DropShadow para obter a sua forma a partir do elemento alvo através de uma máscara
- O DropShadow é retangular por defeito, por isso não é necessário se o alvo for retangular
- Anexe a sombra a um novo SpriteVisual e defina o SpriteVisual como filho do elemento anfitrião
- Associe o tamanho do SpriteVisual ao tamanho do host usando um ExpressionAnimation
<Grid Width="200" Height="200">
<Canvas x:Name="ShadowHost" />
<Ellipse x:Name="CircleImage">
<Ellipse.Fill>
<ImageBrush ImageSource="Assets/Images/2.jpg" Stretch="UniformToFill" />
</Ellipse.Fill>
</Ellipse>
</Grid>
public MainPage()
{
InitializeComponent();
InitializeDropShadow(ShadowHost, CircleImage);
}
private void InitializeDropShadow(UIElement shadowHost, Shape shadowTarget)
{
Visual hostVisual = ElementCompositionPreview.GetElementVisual(shadowHost);
Compositor compositor = hostVisual.Compositor;
// Create a drop shadow
var dropShadow = compositor.CreateDropShadow();
dropShadow.Color = Color.FromArgb(255, 75, 75, 80);
dropShadow.BlurRadius = 15.0f;
dropShadow.Offset = new Vector3(2.5f, 2.5f, 0.0f);
// Associate the shape of the shadow with the shape of the target element
dropShadow.Mask = shadowTarget.GetAlphaMask();
// Create a Visual to hold the shadow
var shadowVisual = compositor.CreateSpriteVisual();
shadowVisual.Shadow = dropShadow;
// Add the shadow as a child of the host in the visual tree
ElementCompositionPreview.SetElementChildVisual(shadowHost, shadowVisual);
// Make sure size of shadow host and shadow visual always stay in sync
var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);
shadowVisual.StartAnimation("Size", bindSizeAnimation);
}
A lista seguinte mostra o equivalente em C++/WinRT do código C# anterior usando a mesma estrutura XAML.
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Microsoft.UI.Xaml.h>
#include <winrt/Microsoft.UI.Xaml.Hosting.h>
#include <winrt/Microsoft.UI.Xaml.Shapes.h>
...
MainPage()
{
InitializeComponent();
InitializeDropShadow(ShadowHost(), CircleImage());
}
int32_t MyProperty();
void MyProperty(int32_t value);
void InitializeDropShadow(Microsoft::UI::Xaml::UIElement const& shadowHost, Microsoft::UI::Xaml::Shapes::Shape const& shadowTarget)
{
auto hostVisual{ Microsoft::UI::Xaml::Hosting::ElementCompositionPreview::GetElementVisual(shadowHost) };
auto compositor{ hostVisual.Compositor() };
// Create a drop shadow
auto dropShadow{ compositor.CreateDropShadow() };
dropShadow.Color(Microsoft::UI::ColorHelper::FromArgb(255, 75, 75, 80));
dropShadow.BlurRadius(15.0f);
dropShadow.Offset(Windows::Foundation::Numerics::float3{ 2.5f, 2.5f, 0.0f });
// Associate the shape of the shadow with the shape of the target element
dropShadow.Mask(shadowTarget.GetAlphaMask());
// Create a Visual to hold the shadow
auto shadowVisual = compositor.CreateSpriteVisual();
shadowVisual.Shadow(dropShadow);
// Add the shadow as a child of the host in the visual tree
Microsoft::UI::Xaml::Hosting::ElementCompositionPreview::SetElementChildVisual(shadowHost, shadowVisual);
// Make sure size of shadow host and shadow visual always stay in sync
auto bindSizeAnimation{ compositor.CreateExpressionAnimation(L"hostVisual.Size") };
bindSizeAnimation.SetReferenceParameter(L"hostVisual", hostVisual);
shadowVisual.StartAnimation(L"Size", bindSizeAnimation);
}
Vidro fosco
Cria um efeito que desfoque e tinga o conteúdo de fundo. Note que os programadores precisam de instalar o pacote Win2D NuGet para usar efeitos. Consulte a página inicial do Win2D para instruções de instalação.
Visão geral da implementação
- Obtenha um material Visual para o elemento host
- Crie uma árvore de efeitos de desfoque usando Win2D e CompositionEffectSourceParameter
- Crie um CompositionEffectBrush baseado na árvore de efeitos
- Defina a entrada do CompositionEffectBrush para um CompositionBackdropBrush, que permite aplicar um efeito ao conteúdo por trás de um SpriteVisual
- Defina o CompositionEffectBrush como o conteúdo de um novo SpriteVisual e defina o SpriteVisual como filho do elemento anfitrião. Podes alternativamente usar um XamlCompositionBrushBase.
- Associe o tamanho do SpriteVisual ao tamanho do host usando um ExpressionAnimation
<Grid Width="300" Height="300" Grid.Column="1">
<Image
Source="Assets/Images/2.jpg"
Width="200"
Height="200" />
<Canvas
x:Name="GlassHost"
Width="150"
Height="300"
HorizontalAlignment="Right" />
</Grid>
public MainPage()
{
InitializeComponent();
InitializeFrostedGlass(GlassHost);
}
private void InitializeFrostedGlass(UIElement glassHost)
{
Visual hostVisual = ElementCompositionPreview.GetElementVisual(glassHost);
Compositor compositor = hostVisual.Compositor;
// Create a glass effect, requires Win2D NuGet package
var glassEffect = new GaussianBlurEffect
{
BlurAmount = 15.0f,
BorderMode = EffectBorderMode.Hard,
Source = new ArithmeticCompositeEffect
{
MultiplyAmount = 0,
Source1Amount = 0.5f,
Source2Amount = 0.5f,
Source1 = new CompositionEffectSourceParameter("backdropBrush"),
Source2 = new ColorSourceEffect
{
Color = Color.FromArgb(255, 245, 245, 245)
}
}
};
// Create an instance of the effect and set its source to a CompositionBackdropBrush
var effectFactory = compositor.CreateEffectFactory(glassEffect);
var backdropBrush = compositor.CreateBackdropBrush();
var effectBrush = effectFactory.CreateBrush();
effectBrush.SetSourceParameter("backdropBrush", backdropBrush);
// Create a Visual to contain the frosted glass effect
var glassVisual = compositor.CreateSpriteVisual();
glassVisual.Brush = effectBrush;
// Add the blur as a child of the host in the visual tree
ElementCompositionPreview.SetElementChildVisual(glassHost, glassVisual);
// Make sure size of glass host and glass visual always stay in sync
var bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);
glassVisual.StartAnimation("Size", bindSizeAnimation);
}
Recursos adicionais
- Visão geral da Camada Visual
- Classe ElementCompositionPreview
- Exemplos avançados de UI e composição no GitHub WindowsCompositionSamples
- Exemplo BasicXamlInterop
- Exemplo de ParallaxingListItems
Windows developer