Información general sobre las transformacionesTransforms overview

Aprende a usar las transformaciones en la API de Windows Runtime cambiando los sistemas de coordenadas relativos de los elementos de la interfaz de usuario.Learn how to use transforms in the Windows Runtime API, by changing the relative coordinate systems of elements in the UI. Esto puede servir para ajustar la apariencia de cada uno de los elementos XAML, por ejemplo, escalar, girar o transformar la posición en el espacio x-y.This can be used to adjust the appearance of individual XAML elements, such as scaling, rotating, or transforming the position in x-y space.

¿Qué es una transformación?What is a transform?

Una transformación define cómo asignar, o transformar, puntos de un espacio de coordenadas a otro espacio de coordenadas.A transform defines how to map, or transform, points from one coordinate space to another coordinate space. Cuando una transformación se aplica a los elementos de la interfaz de usuario, cambia el modo en que ese elemento de la interfaz de usuario se representa en la pantalla como parte de la interfaz de usuario.When a transform is applied to a UI element, it changes how that UI element is rendered to the screen as part of the UI.

Las transformaciones se podrían dividir en cuatro clasificaciones genéricas: traslación, giro, escalado y sesgo (o distorsión).Think of transforms in four broad classifications: translation, rotation, scaling and skew (or shear). Si la finalidad es usar las API de gráficos para cambiar la apariencia de los elementos de la interfaz de usuario, suele ser más fácil crear transformaciones que definir únicamente una operación cada vez.For the purposes of using graphics APIs to change the appearance of UI elements, it's usually easiest to create transforms that define only one operation at a time. Por este motivo, Windows Runtime define una clase diferente para cada una de estas categorías de transformaciones:So the Windows Runtime defines a discrete class for each of these transform classifications:

De todas ellas, probablemente uses TranslateTransform y ScaleTransform con mayor frecuencia en escenarios de interfaz de usuario.Of these, you're likely to use TranslateTransform and ScaleTransform most often for UI scenarios.

Las transformaciones se pueden combinar y hay dos clases de Windows Runtime que admiten esto: CompositeTransform y TransformGroup.You can combine transforms, and there are two Windows Runtime classes that support this: CompositeTransform and TransformGroup. En una CompositeTransform, las transformaciones se aplican en este orden: escalar, distorsionar, girar, trasladar.In a CompositeTransform, transforms are applied in this order: scale, skew, rotate, translate. Usa TransformGroup en lugar de CompositeTransform si quieres aplicar las transformaciones con un orden diferente.Use TransformGroup instead of CompositeTransform if you want the transforms applied in a different order. Para más información, consulta CompositeTransform.For more info, see CompositeTransform.

Transformaciones y diseñoTransforms and layout

En un diseño XAML, las transformaciones se aplican una vez finalizado el cálculo de diseño, por lo que los cálculos del espacio disponible y otras decisiones sobre el diseño ya se han realizado antes de aplicar las transformaciones.In XAML layout, transforms are applied after the layout pass is complete, so available space calculations and other layout decisions have been made before the transforms are applied. Como el diseño es lo primero que se aplica, algunas veces obtendrás resultados inesperados si los elementos transformados están en una celda de Grid o en un contenedor de diseño similar que asigna espacio durante el diseño.Because layout comes first, you'll sometimes get unexpected results if you transform elements that are in a Grid cell or similar layout container that allocates space during layout. El elemento transformado puede aparecer truncado u oscurecido porque está intentando dibujarse en un área que no calculó las dimensiones posteriores a la transformación a la hora de dividir el espacio dentro de su contenedor principal.The transformed element may appear truncated or obscured because it's trying to draw into an area that didn't calculate the post-transform dimensions when dividing space within its parent container. Quizás tengas que experimentar con los resultados de las transformaciones y ajustar algunas opciones de configuración.You may need to experiment with the transform results and adjust some settings. Por ejemplo, en vez de basarte en el diseño adaptativo y empezar con el tamaño, posiblemente tengas que cambiar las propiedades Center o declarar medidas de píxel fijas para el espacio de diseño, a fin de procurar que el elemento principal asigne espacio suficiente.For example, instead of relying on adaptive layout and star sizing, you may need to change the Center properties or declare fixed pixel measurements for layout space to make sure the parent allots enough space.

Nota sobre la migración: Windows Presentation Foundation (WPF) contaba con la propiedad LayoutTransform que aplicaba transformaciones antes de la fase de diseño.Migration note: Windows Presentation Foundation (WPF) had a LayoutTransform property that applied transforms prior to the layout pass. Sin embargo, XAML en Windows Runtime no admite propiedades LayoutTransform.But Windows Runtime XAML doesn't support a LayoutTransform property. (Microsoft Silverlight también carecía de esta propiedad).(Microsoft Silverlight didn't have this property either.)

Como alternativa, el kit de herramientas de la Comunidad Windows proporciona el objeto LayoutTransformControl que aplica las transformaciones de matriz en cualquier objeto FrameworkElement de la aplicación.As an alternative, the Windows Community Toolkit provides the LayoutTransformControl that applies Matrix transformations on any FrameworkElement of your application.

Aplicación de una transformación a un elemento de la interfaz de usuarioApplying a transform to a UI element

Cuando una transformación se aplica a un objeto, normalmente se hace para establecer la propiedad UIElement.RenderTransform.When you apply a transform to an object, you typically do so to set the property UIElement.RenderTransform. Establecer esta propiedad no cambia literalmente el objeto píxel a píxel.Setting this property does not literally change the object pixel by pixel. Lo que hace es aplicar la transformación dentro del espacio de coordenadas local donde existe el objeto.What the property really does is apply the transform within the local coordinate space in which that object exists. Después, la lógica y la operación de representación (posterior al diseño) representarán los espacios de coordenadas combinados, dando la sensación de que la apariencia del objeto ha cambiado, así como posiblemente su posición de diseño (si se aplicó TranslateTransform).Then the rendering logic and operation (post-layout) renders the combined coordinate spaces, making it look like the object has changed appearance and also potentially its layout position (if TranslateTransform was applied).

Cada transformación de representación está centrada de forma predeterminada en el origen del sistema de coordenadas local del objeto de destino, esto es, su (0,0).By default, each render transform is centered at the origin of the target object's local coordinate system—its (0,0). La única excepción es TranslateTransform, que no tiene propiedades de centrado que establecer porque el efecto de traslación es el mismo independientemente del lugar donde esté centrado.The only exception is a TranslateTransform, which has no center properties to set because the translation effect is the same regardless of where it is centered. Todas las demás transformaciones tienen propiedades que establecen valores CenterX y CenterY.But the other transforms each have properties that set CenterX and CenterY values.

Siempre que uses transformaciones con UIElement.RenderTransform, recuerda que hay otra propiedad en UIElement que afecta al comportamiento de la transformación: RenderTransformOrigin.Whenever you use transforms with UIElement.RenderTransform, remember that there's another property on UIElement that affects how the transform behaves: RenderTransformOrigin. Lo que RenderTransformOrigin declara es si debe aplicarse toda la transformación al punto (0,0) predeterminado de un elemento o a algún otro punto de origen dentro del espacio de coordenadas relativo de dicho elemento.What RenderTransformOrigin declares is whether the whole transform should apply to the default (0,0) point of an element or to some other origin point within the relative coordinate space of that element. En los elementos típicos, (0,0) coloca la transformación en la esquina superior izquierda.For typical elements, (0,0) places the transform to the top left corner. En función del efecto que desees, quizás quieras cambiar RenderTransformOrigin en lugar de ajustar los valores CenterX y CenterY en las transformaciones.Depending on what effect you want, you might choose to change RenderTransformOrigin rather than adjusting the CenterX and CenterY values on transforms. Ten en cuenta que, si aplicas ambos valores, RenderTransformOrigin y CenterX / CenterY, los resultados podrían resultar confusos, especialmente si estás animando alguno de los valores.Note that if you apply both RenderTransformOrigin and CenterX / CenterY values, the results can be pretty confusing, especially if you're animating any of the values.

En las pruebas de acceso, un objeto al que se ha aplicado una transformación sigue respondiendo a entradas según lo previsto y en consonancia con la apariencia visual en el espacio x-y.For hit-testing purposes, an object to which a transform is applied continues to respond to input in an expected way that's consistent to its visual appearance in x-y space. Por ejemplo, si has usado TranslateTransform para mover un Rectangle 400 píxeles lateralmente en la interfaz de usuario, ese Rectangle responde a eventos PointerPressed cuando el usuario presiona el punto donde Rectangle aparece visualmente.For example, if you've used a TranslateTransform to move a Rectangle 400 pixels laterally in the UI, that Rectangle responds to PointerPressed events when the user presses the point where the Rectangle appears visually. No se obtendrán falsos eventos si el usuario presiona el área donde estaba Rectangle antes de ser trasladado.You won't get false events if the user presses the area where the Rectangle was before being translated. En cuanto a las consideraciones sobre el índice z que afectan a las pruebas de acceso, aplicar una transformación no supone ninguna diferencia; el índice z que rige qué elemento controla los eventos de entrada de un punto en el espacio x-y se sigue evaluando mediante el orden secundario declarado en un contenedor.For any z-index considerations that affect hit testing, applying a transform makes no difference; the z-index that governs which element handles input events for a point in x-y space is still evaluated using the child order as declared in a container. Ese orden suele ser el mismo orden en que se declaran los elementos en XAML, aunque en el caso de los elementos secundarios de un objeto Canvas, puedes ajustar el orden aplicando la propiedad adjunta Canvas.ZIndex a sus elementos secundarios.That order is usually the same as the order in which you declare the elements in XAML, although for child elements of a Canvas object you can adjust the order by applying the Canvas.ZIndex attached property to child elements.

Otras propiedades de las transformacionesOther transform properties

  • Brush.Transform, Brush.RelativeTransform: influyen en la manera en que un elemento Brush usa el espacio de coordenadas dentro del área a la que Brush se aplica para establecer propiedades visuales como primeros planos y fondos.Brush.Transform, Brush.RelativeTransform: These influence how a Brush uses coordinate space within the area that the Brush is applied to set visual properties such as foregrounds and backgrounds. Estas transformaciones no tienen relevancia en la mayoría de los pinceles (que suelen establecer colores sólidos con SolidColorBrush), pero pueden ser de utilidad en un momento dado cuando se pintan áreas con ImageBrush o con LinearGradientBrush.These transforms aren't relevant for the most common brushes (which are typically setting solid colors with SolidColorBrush) but might be occasionally useful when painting areas with an ImageBrush or LinearGradientBrush.
  • Geometry.Transform: esta propiedad se podría usar para aplicar una transformación a una geometría, antes de usar dicha geometría para un valor de propiedad Path.Data.Geometry.Transform: You might use this property to apply a transform to a geometry prior to using that geometry for a Path.Data property value.

Animación de una transformaciónAnimating a transform

Los objetos Transform se pueden animar.Transform objects can be animated. Para animar un objeto Transform, aplica una animación de un tipo compatible a la propiedad que quieras animar.To animate a Transform, apply an animation of a compatible type to the property you want to animate. Esto suele significar que estás usando objetos DoubleAnimation o DoubleAnimationUsingKeyFrames para definir la animación, porque todas las propiedades de transformación son del tipo Double.This typically means you're using DoubleAnimation or DoubleAnimationUsingKeyFrames objects to define the animation, because all of the transform properties are of type Double. Las animaciones que afectan a una transformación que se usa para un valor UIElement.RenderTransform no se consideran animaciones dependientes, aunque tengan una duración distinta de cero.Animations that affect a transform that's used for a UIElement.RenderTransform value are not considered to be dependent animations, even if they have a nonzero duration. Para más información sobre animaciones dependientes, consulta Animaciones con guion gráfico.For more info about dependent animations, see Storyboarded animations.

Si animas propiedades para lograr un efecto similar en una transformación en cuanto a la apariencia visual neta como, por ejemplo, animando las propiedades Width y Height de una clase FrameworkElement en lugar de aplicar una clase TranslateTransform, dichas animaciones siempre se tratarán como animaciones dependientes.If you animate properties to produce an effect similar to a transform in terms of the net visual appearance—for example, animating the Width and Height of a FrameworkElement rather than applying a TranslateTransform—such animations are almost always treated as dependent animations. Tendrías que habilitar las animaciones y la animación podría producir problemas de rendimiento importantes, especialmente si estás tratando de permitir las interacciones del usuario mientras ese objeto está animado.You'd have to enable the animations and there could be significant performance issues with the animation, especially if you're trying to support user interaction while that object is being animated. Por ese motivo, es preferible usar una transformación y animarla en lugar de animar otras propiedades que harían que la animación se trate como una animación dependiente.For that reason it's preferable to use a transform and animate it rather than animating any other property where the animation would be treated as a dependent animation.

Para seleccionar el destino de la transformación, debe existir una Transform como valor de RenderTransform.To target the transform, there must be an existing Transform as the value for RenderTransform. Normalmente, se pone un elemento para el tipo de transformación apropiado en el XAML inicial, a veces sin establecer propiedades para dicha transformación.You typically put an element for the appropriate transform type in the initial XAML, sometimes with no properties set on that transform.

Para aplicar las animaciones a las propiedades de una transformación, se suele usar una técnica de selección de destino indirecta.You typically use an indirect targeting technique to apply animations to the properties of a transform. Para más información sobre la sintaxis de la selección de destino indirecta, consulta Animaciones con guion gráfico y Sintaxis de la ruta de una propiedad.For more info about indirect targeting syntax, see Storyboarded animations and Property-path syntax.

En ocasiones, los estilos predeterminados de los controles definen animaciones de transformaciones como parte del comportamiento de su estado visual.Default styles for controls sometimes define animations of transforms as part of their visual-state behavior. Por ejemplo, los estados visuales de ProgressRing usan valores de RotateTransform animados para "hacer girar" los puntos del anillo.For example, the visual states for ProgressRing use animated RotateTransform values to "spin" the dots in the ring.

Este es un ejemplo sencillo de cómo animar una transformación.Here's a simple example of how to animate a transform. En este caso, se trata de la animación del Angle de una RotateTransform para hacer girar un Rectangle sobre sí mismo alrededor de su centro visual.In this case, it's animating the Angle of a RotateTransform to spin a Rectangle in place around its visual center. En este ejemplo, se asigna un nombre a RotateTransform, por lo que no es necesario seleccionar indirectamente el destino de la animación, pero podrías dejar la transformación sin nombre, asignar un nombre al elemento al que se aplica la transformación y usar la selección indirecta de destino como (UIElement.RenderTransform).(RotateTransform.Angle).This example names the RotateTransform so doesn't need indirect animation targeting, but you could alternatively leave the transform unnamed, name the element that the transform's applied to, and use indirect targeting such as (UIElement.RenderTransform).(RotateTransform.Angle).

<StackPanel Margin="15">
  <StackPanel.Resources>
    <Storyboard x:Name="myStoryboard">
      <DoubleAnimation
       Storyboard.TargetName="myTransform"
       Storyboard.TargetProperty="Angle"
       From="0" To="360" Duration="0:0:5" 
       RepeatBehavior="Forever" />
    </Storyboard>
  </StackPanel.Resources>
  <Rectangle Width="50" Height="50" Fill="RoyalBlue"
   PointerPressed="StartAnimation">
    <Rectangle.RenderTransform>
      <RotateTransform x:Name="myTransform" Angle="45" CenterX="25" CenterY="25" />
    </Rectangle.RenderTransform>
  </Rectangle>
</StackPanel>
void StartAnimation (object sender, RoutedEventArgs e) {
    myStoryboard.Begin();
}

Explicación de los marcos de coordenadas de referencia en el tiempo de ejecuciónAccounting for coordinate frames of reference at run time

UIElement tiene un método denominado TransformToVisual, que puede generar una clase Transform que se correlaciona con los marcos de coordenadas de referencia de dos elementos de la interfaz de usuario.UIElement has a method named TransformToVisual, which can generate a Transform that correlates the coordinate frames of reference for two UI elements. Puedes usarlo para comparar un elemento con el marco de coordenadas de referencia predeterminado de la aplicación si pasas el objeto visual raíz como primer parámetro.You can use this to compare an element to the app's default coordinate frame of reference if you pass the root visual as the first parameter. Esto puede resultar útil si has capturado un evento de entrada de un elemento diferente o si estás intentando predecir el comportamiento del diseño sin solicitar realmente un pase de diseño.This can be useful if you've captured an input event from a different element, or if you are trying to predict layout behavior without actually requesting a layout pass.

Los datos de evento obtenidos a partir de eventos de puntero proporcionan acceso a un método GetCurrentPoint, en el que puedes especificar un parámetro relativeTo para cambiar el marco de coordenadas de referencia por un elemento específico en lugar del predeterminado de la aplicación.Event data obtained from pointer events provides access to a GetCurrentPoint method, where you can specify a relativeTo parameter to change the coordinate frame of reference to a specific element rather than the app default. Lo que este método hace es, simplemente, aplicar internamente una transformación de traslación y transformar los datos de las coordenadas x-y automáticamente cuando crea el objeto PointerPoint devuelto.This approach simply applies a translate transform internally and transforms the x-y coordinate data for you when it creates the returned PointerPoint object.

Descripción matemática de una transformaciónDescribing a transform mathematically

Una transformación se puede describir en términos de una matriz de transformación.A transform can be described in terms of a transformation matrix. Para describir las transformaciones en un plano x-y bidimensional se usa una matriz de 3x3.A 3×3 matrix is used to describe the transformations in a two-dimensional, x-y plane. Las matrices de transformación afín se pueden multiplicar para formar cualquier número de transformaciones lineales, como rotación y distorsión (sesgado), seguidas de una traslación.Affine transformation matrices can be multiplied to form any number of linear transformations, such as rotation and skew (shear), followed by translation. La última columna de una matriz de transformación afín equivale a (0, 0, 1), por lo que solo tienes que especificar los miembros de las dos primeras columnas en la descripción matemática.The final column of an affine transformation matrix is equal to (0, 0, 1), so you need to specify only the members of the first two columns in the mathematical description.

La descripción matemática de una transformación podría resultarte útil si tienes conocimientos matemáticos o estás familiarizado con las técnicas de programación de gráficos que también usan matrices para describir las transformaciones del espacio de coordenadas.The mathematical description of a transform might be useful to you if you have a mathematical background or a familiarity with graphics-programming techniques that also use matrices to describe transformations of coordinate space. Hay una clase derivada de Transform que te permite expresar una transformación directamente en términos de su matriz de 3x3: MatrixTransform.There's a Transform-derived class that enables you to express a transformation directly in terms of its 3×3 matrix: MatrixTransform. MatrixTransform tiene una propiedad Matrix que contiene una estructura con seis propiedades: M11, M12, M21, M22, OffsetX y OffsetY.MatrixTransform has a Matrix property, which holds a structure that has six properties: M11, M12, M21, M22, OffsetX and OffsetY. Cada propiedad Matrix usa un valor Double y se corresponde con los seis valores pertinentes (columnas 1 y 2) de una matriz de transformación afín.Each Matrix property uses a Double value and corresponds to the six relevant values (columns 1 and 2) of an affine transformation matrix.

M11M11 M12M12 00
M21M21 M22M22 00
OffsetXOffsetX OffsetYOffsetY 11

Cualquier transformación que puedas describir con un objeto TranslateTransform, ScaleTransform, RotateTransform o SkewTransform podría describirse igualmente mediante una MatrixTransform con un valor Matrix.Any transform that you could describe with a TranslateTransform, ScaleTransform, RotateTransform, or SkewTransform object could be described equally by a MatrixTransform with a Matrix value. Sin embargo, lo normal es usar solamente TranslateTransform y las demás, porque conceptualizar las propiedades de estas clases de transformaciones es más fácil que establecer los componentes vectoriales de una Matrix.But you typically just use TranslateTransform and the others because the properties on those transform classes are easier to conceptualize than setting the vector components in a Matrix. También es más fácil animar las diferentes propiedades de las transformaciones; una Matrix es en realidad una estructura y no un DependencyObject y, por lo tanto, no admite valores individuales animados.It's also easier to animate the discrete properties of transforms; a Matrix is actually a structure and not a DependencyObject, so it can't support animated individual values.

Algunas herramientas de diseño XAML que permiten aplicar operaciones de transformación serializarán los resultados como una MatrixTransform.Some XAML design tools that enable you to apply transformation operations will serialize the results as a MatrixTransform. En este caso, quizás sea mejor usar de nuevo la misma herramienta de diseño para cambiar el efecto de la transformación y volver a serializar el código XAML, en lugar de intentar manipular tú mismo los valores de Matrix directamente en el código XAML.In this case it may be best to use the same design tool again to change the transformation effect and serialize the XAML again, rather than trying to manipulate the Matrix values yourself directly in the XAML.

Transformaciones 3D3-D transforms

En Windows 10, XAML ha introducido una nueva propiedad, UIElement.Transform3D, que puede usarse para crear efectos 3D con la interfaz de usuario.In Windows 10, XAML introduced a new property, UIElement.Transform3D, that can be used to create 3D effects with UI. Para ello, usa PerspectiveTransform3D para agregar a la escena una perspectiva 3D o "cámara" compartida y, a continuación, emplea CompositeTransform3D para transformar un elemento en el espacio 3D, igual que si utilizaras CompositeTransform.To do this, use PerspectiveTransform3D to add a shared 3D perspective or "camera" to your scene, and then use CompositeTransform3D to transform an element in 3D space, like you would use CompositeTransform. Consulta UIElement.Transform3D para obtener una explicación de cómo implementar transformaciones 3D.See UIElement.Transform3D for a discussion of how to implement 3D transforms.

Para realizar efectos 3D más simples que se apliquen a un solo objeto, se puede usar la propiedad UIElement.Projection.For simpler 3D effects that only apply to a single object, the UIElement.Projection property can be used. Usar una PlaneProjection como el valor de esta propiedad equivale a aplicar al elemento una transformación de perspectiva fija y una o más transformaciones 3D.Using a PlaneProjection as the value for this property is equivalent to applying a fixed perspective transform and one or more 3D transforms to the element. Este tipo de transformación se describe en mayor profundidad en Efectos de perspectiva 3D para interfaces de usuario XAML.This type of transform is described in more detail in 3-D perspective effects for XAML UI.

Temas relacionadosRelated topics