Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La mayoría de las aplicaciones de WinUI y Windows App SDK que consumen funcionalidades de capa visual usarán XAML para definir el contenido principal de la interfaz de usuario. WinUI proporciona características en el marco XAML y la capa visual que facilitan la combinación de estas dos tecnologías para crear experiencias de usuario impresionantes. La funcionalidad de interoperabilidad xaml y de capa visual se puede usar para crear animaciones avanzadas y efectos no disponibles solo con las API XAML. Esto incluye:
- Efectos de pincel como desenfoque y vidrio escarchado
- Efectos de iluminación dinámica
- Animaciones controladas por desplazamiento y parallax
- Animaciones de diseño automático
- Sombras paralelas de precisión píxel-perfecta
Estos efectos y animaciones se pueden aplicar al contenido XAML existente, por lo que no tienes que reestructurar drásticamente tu aplicación WinUI para aprovechar la funcionalidad. Las animaciones de diseño, las sombras y los efectos de desenfoque se tratan en la sección Recetas a continuación. Para obtener un ejemplo de código que implemente parallax, vea el ejemplo ParallaxingListItems. El repositorio WindowsCompositionSamples también tiene otros ejemplos para implementar animaciones, sombras y efectos.
La clase XamlCompositionBrushBase
Microsoft.UI.Xaml.Media.XamlCompositionBrushBase proporciona una clase base para pinceles XAML que pintan un área con un CompositionBrush. Esto se puede usar para aplicar fácilmente efectos de composición como desenfoque o vidrio escarchado a elementos de la interfaz de usuario XAML.
Consulta la sección Pinceles para obtener más información sobre el uso de pinceles con la interfaz de usuario XAML.
Para obtener ejemplos de código, consulta la página de referencia de XamlCompositionBrushBase.
La clase XamlLight
Microsoft.UI.Xaml.Media.XamlLight proporciona una clase base para efectos de iluminación XAML que iluminan dinámicamente un área con compositionLight.
Consulta la sección Iluminación para obtener más información sobre el uso de luces, incluidos los elementos de la interfaz de usuario XAML de iluminación.
Para obtener ejemplos de código, consulta la página de referencia de XamlLight.
Trabajando con WinUI XAML
ElementCompositionPreview es una clase estática que proporciona funcionalidad de interoperabilidad xaml y de capa visual. Para obtener información general sobre la capa visual y su funcionalidad, consulte Capa visual. La clase ElementCompositionPreview proporciona los siguientes métodos de interoperabilidad de WinUI:
- GetElementVisual: obtener un objeto visual "handout" que se usa para renderizar este elemento
- SetElementChildVisual: establece un objeto visual "handin" como último elemento secundario del árbol visual de este elemento. Este elemento visual se dibujará sobre el resto del elemento.
- GetElementChildVisual: recuperar el conjunto visual mediante SetElementChildVisual
- GetScrollViewerManipulationPropertySet: obtener un objeto que se puede usar para crear animaciones de 60fps basadas en el desplazamiento del scroll en un ScrollViewer
GetElementVisual
ElementCompositionPreview.GetElementVisual devuelve un objeto visual "handout" que se usa para representar el uiElement especificado. El marco XAML establece propiedades como Visual.Opacity, Visual.Offset y Visual.Size según el estado de UIElement. Esto permite técnicas como animaciones de reposición implícitas (consulte Recetas).
Tenga en cuenta que, dado que Offset y Size se establecen como resultado del diseño del marco XAML, los desarrolladores deben tener cuidado al modificar o animar estas propiedades. Los desarrolladores solo deben modificar o animar Offset cuando la esquina superior izquierda del elemento tenga la misma posición que la de su elemento primario en el diseño. Por lo general, el tamaño no se debe modificar, pero el acceso a la propiedad puede ser útil. Por ejemplo, los ejemplos Drop Shadow y Frosted Glass que se encuentran a continuación utilizan Size of a handout Visual como entrada para una animación.
Como advertencia adicional, las propiedades actualizadas del Visual de folleto no se reflejarán en el UIElement correspondiente. Por ejemplo, si se establece UIElement.Opacity en 0.5, se establecerá la opacidad del Visual del handout correspondiente en 0.5. Sin embargo, establecer la Opacity del Visual del documento en 0.5 hará que el contenido aparezca con un 50% de opacidad, pero no cambiará el valor de la propiedad Opacity del UIElement correspondiente.
Ejemplo de animación offset
Incorrecto
<Border>
<Image x:Name="MyImage" Margin="5" />
</Border>
// Doesn’t work because Image has a margin!
ElementCompositionPreview.GetElementVisual(MyImage).StartAnimation("Offset", parallaxAnimation);
Corregir
<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 al desarrollador proporcionar un Visual denominado "handin" que aparecerá como parte del árbol visual de un elemento. Esto permite a los desarrolladores crear una "Isla de composición" donde el contenido basado en objetos visuales puede aparecer dentro de una interfaz de usuario XAML. Los desarrolladores deben ser conservadores sobre el uso de esta técnica, ya que el contenido basado en objetos visuales no tendrá las mismas garantías de accesibilidad y experiencia del usuario de contenido XAML. Por lo tanto, se recomienda generalmente que esta técnica solo se use cuando sea necesario para implementar efectos personalizados como los que se encuentran en la sección Recetas a continuación.
Métodos GetAlphaMask
Image, TextBlock y Shape implementan un método denominado GetAlphaMask que devuelve un CompositionBrush que representa una imagen de escala de grises con la forma del elemento. Este CompositionBrush puede servir como entrada para una Composición DropShadow, para que la sombra refleje la forma del elemento en lugar de un rectángulo. Esto permite sombras perfectas y basadas en contorno de píxeles para texto, imágenes con alfa y formas. Vea Drop Shadow más abajo para obtener un ejemplo de esta API.
Recetas
Cambiar la posición de la animación
Con animaciones implícitas de composición, un desarrollador puede animar automáticamente los cambios en el diseño de un elemento en relación con su elemento primario. Por ejemplo, si cambia el margen del botón siguiente, se animará automáticamente a su nueva posición de diseño.
Información general sobre la implementación
- Obtener el documento Visual para el elemento de destino.
- Crear una ImplicitAnimationCollection que anima automáticamente los cambios en la propiedad Offset
- Asociar ImplicitAnimationCollection con el objeto visual de respaldo
<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;
}
Colocar sombra
Aplique una sombra proyectada perfecta en píxeles a un UIElement; por ejemplo, una Elipse que contiene una imagen. Dado que la sombra requiere un SpriteVisual creado por la aplicación, es necesario crear un elemento "host", que contendrá SpriteVisual mediante ElementCompositionPreview.SetElementChildVisual.
Información general sobre la implementación
- Obtener el documento Visual para el elemento host.
- Creación de una dropShadow de Microsoft.UI.Composition
- Configurar DropShadow para obtener su forma del elemento de destino a través de una máscara
- DropShadow es rectangular de forma predeterminada, por lo que no es necesario si el destino es rectangular.
- Adjunte sombra a un nuevo SpriteVisual y establezca SpriteVisual como elemento secundario del elemento host.
- Vincular el tamaño de SpriteVisual al tamaño del host mediante 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);
}
En la lista siguiente se muestra el equivalente de C++/WinRT del código de C# anterior con la misma estructura 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);
}
Vidrio escarchado
Crea un efecto que desenfoque y tintiza el contenido de fondo. Tenga en cuenta que los desarrolladores deben instalar el paquete NuGet Win2D para usar efectos. Consulte la página principal de Win2D para obtener instrucciones de instalación.
Información general sobre la implementación
- Obtener el Visual para el elemento anfitrión
- Creación de un árbol de efectos de desenfoque mediante Win2D y CompositionEffectSourceParameter
- Creación de un compositionEffectBrush basado en el árbol de efectos
- Establezca la entrada de CompositionEffectBrush en compositionBackdropBrush, lo que permite aplicar un efecto al contenido detrás de spriteVisual.
- Establezca CompositionEffectBrush como el contenido de un nuevo SpriteVisual y establezca SpriteVisual como elemento secundario del elemento host. Como alternativa, también puedes usar XamlCompositionBrushBase.
- Vincular el tamaño de SpriteVisual al tamaño del host usando 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 adicionales
- Introducción a la capa visual
- Clase ElementCompositionPreview
- Ejemplos avanzados de interfaz de usuario y composición en GitHub WindowsCompositionSamples
- Ejemplo de BasicXamlInterop
- Ejemplo parallaxingListItems