Compartir a través de


Visión general de las transformaciones

Obtenga información sobre cómo usar transformaciones en la API de Windows Runtime cambiando los sistemas de coordenadas relativos de los elementos de la interfaz de usuario. Esto se puede usar para ajustar la apariencia de elementos XAML individuales, como el escalado, la rotación o la transformación de la posición en el espacio x-y.

¿Qué es una transformación?

Una transformación define cómo asignar, o transformar, puntos de un espacio de coordenadas a otro espacio de coordenadas. Cuando se aplica una transformación a un elemento de interfaz de usuario, cambia cómo se representa ese elemento de interfaz de usuario en la pantalla como parte de la interfaz de usuario.

Tenga en cuenta las transformaciones en cuatro categorías principales: traslación, rotación, escala e inclinación (o sesgo). Para 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 definen solo una operación a la vez. Por lo tanto, Windows Runtime define una clase discreta para cada una de estas clasificaciones de transformación:

De estos, es probable que use TranslateTransform y ScaleTransform con más frecuencia para escenarios de interfaz de usuario.

Puedes combinar transformaciones y hay dos clases de Windows Runtime que admiten esto: CompositeTransform y TransformGroup. En una CompositeTransform, las transformaciones se aplican en este orden: escala, sesgar, rotación, traslación. Use TransformGroup en lugar de CompositeTransform si desea aplicar las transformaciones en un orden diferente. Para obtener más información, consulta CompositeTransform.

Transformaciones y diseño

En el diseño XAML, las transformaciones se aplican una vez completado el paso de diseño, por lo que se han tomado cálculos de espacio disponibles y otras decisiones de diseño antes de aplicar las transformaciones. Como el diseño tiene prioridad, a veces puede obtener resultados inesperados si transforma elementos que están en una celda de Grid o en un contenedor de diseño similar que asigna espacio durante el diseño. El elemento transformado puede aparecer truncado o oculto porque intenta dibujar en un área que no calculó las dimensiones posteriores a la transformación al dividir el espacio dentro de su contenedor primario. Es posible que tenga que experimentar con los resultados de la transformación y ajustar algunas opciones de configuración. Por ejemplo, en lugar de confiar en el diseño adaptable y el dimensionamiento proporcional, quizás necesite modificar las propiedades de Center o declarar medidas fijas en píxeles para el espacio de diseño, y así asegurarse de que el elemento principal disponga de suficiente espacio.

nota de migración: Windows Presentation Foundation (WPF) tenía una propiedad LayoutTransform que aplicaba transformaciones antes del proceso de diseño. Pero XAML de Windows Runtime no admite una propiedad LayoutTransform . (Microsoft Silverlight tampoco tenía esta propiedad).

Sugerencia

Como alternativa, el Kit de Herramientas de la Comunidad de Windows proporciona el LayoutTransformControl que aplica transformaciones de matriz en cualquier FrameworkElement de tu aplicación.

Aplicación de una transformación a un elemento de interfaz de usuario

Al aplicar una transformación a un objeto, normalmente lo hace para establecer la propiedad UIElement.RenderTransform. Establecer esta propiedad no modifica literalmente el objeto píxel a píxel. Lo que realmente hace la propiedad es aplicar la transformación dentro del espacio de coordenadas local en el que existe ese objeto. A continuación, la lógica y la operación de representación (posterior al diseño) representan los espacios de coordenadas combinados, lo que hace que parezca que el objeto ha cambiado la apariencia y también potencialmente su posición de diseño (si se aplicó TranslateTransform ).

De forma predeterminada, cada transformación de representación se centra en el origen del sistema de coordenadas local del objeto de destino, que es su (0,0). La única excepción es translateTransform, que no tiene propiedades central que establecer porque el efecto de traducción es el mismo independientemente de dónde se centre. Sin embargo, las otras transformaciones tienen propiedades que establecen los valores de CenterX y CenterY.

Siempre que use transformaciones con UIElement.RenderTransform, recuerde que hay otra propiedad en UIElement que afecta al comportamiento de la transformación: RenderTransformOrigin. Lo que RenderTransformOrigin declara es si toda la transformación debe aplicarse al punto predeterminado (0,0) de un elemento o a algún otro punto de origen dentro del espacio de coordenadas relativo de ese elemento. Para los elementos típicos, (0,0) coloca la transformación en la esquina superior izquierda. Dependiendo del efecto que desee, puede optar por cambiar RenderTransformOrigin en lugar de ajustar los valores CenterX y CenterY en las transformaciones. Tenga en cuenta que si aplica tanto el RenderTransformOrigin como los valores de CenterX / CenterY, los resultados pueden resultar bastante confusos, especialmente si está animando alguno de los valores.

Con fines de pruebas de posicionamiento, un objeto al que se aplica una transformación continúa respondiendo a la entrada de una manera esperada que es coherente con su aspecto visual en el espacio x-y. Por ejemplo, si ha usado un TranslateTransform para mover un Rectángulo 400 píxeles lateralmente en la IU, ese Rectángulo responde a eventos PointerPressed cuando el usuario presiona el punto en el que el Rectángulo aparece visualmente. No se generarán eventos falsos si el usuario presiona el área donde estaba el Rectángulo antes de ser traducido. Para cualquier consideración de índice z que afecte a las pruebas de aciertos, aplicar una transformación no hace ninguna diferencia; el índice z que determina qué elemento gestiona los eventos de entrada de un punto en el espacio x-y todavía se evalúa mediante el orden de los elementos secundarios tal como se declara en un contenedor. Ese orden suele ser el mismo que el orden en el que declaras los elementos en XAML, aunque para los elementos secundarios de un objeto Canvas puedes ajustar el orden aplicando la propiedad adjunta Canvas.ZIndex a elementos secundarios.

Otras propiedades de transformación

  • Brush.Transform, Brush.RelativeTransform: influyen en cómo un Brush usa el espacio de coordenadas dentro del área al que se aplica el Brush para establecer propiedades visuales como el primer plano y los fondos. Estas transformaciones no son relevantes para los pinceles más comunes (que normalmente establecen colores sólidos con SolidColorBrush), pero pueden ser ocasionalmente útiles al pintar áreas con un ImageBrush o LinearGradientBrush.
  • Geometry.Transform: Puede usar esta propiedad para aplicar una transformación a una geometría antes de utilizar esa geometría como valor de la propiedad Path.Data.

Animar una transformación

Los objetos Transform se pueden animar. Para animar un Transformar, aplique una animación compatible al tipo de propiedad que quiera animar. Normalmente, esto significa que usas objetos DoubleAnimation o DoubleAnimationUsingKeyFrames para definir la animación, ya que todas las propiedades de transformación son de tipo Double. Las animaciones que afectan a una transformación que se usa para una UIElement.RenderTransform valor no se consideran animaciones dependientes, incluso si tienen una duración distinta de cero. Para obtener más información sobre las animaciones dependientes, consulta Animaciones con guion gráfico.

Si anima propiedades para producir un efecto similar a una transformación en términos de apariencia visual neta (por ejemplo, animando el Ancho y la Altura de un FrameworkElement en lugar de aplicar un TranslateTransform), dichas animaciones casi siempre se tratan como animaciones dependientes. Tendrías que habilitar las animaciones y podría haber problemas de rendimiento significativos con la animación, especialmente si intentas admitir la interacción del usuario mientras ese objeto se está animando. Por esa razón, es preferible usar una transformación y animarla en lugar de animar cualquier otra propiedad en la que la animación se trataría como una animación dependiente.

Para dirigir la transformación, debe existir un Transform como el valor de RenderTransform. Normalmente, colocas un elemento para el tipo de transformación adecuado en el XAML inicial, a veces sin propiedades establecidas en esa transformación.

Normalmente se usa una técnica de segmentación indirecta para aplicar animaciones a las propiedades de una transformación. Para obtener más información sobre la sintaxis de destino indirecto, consulta animaciones con guion gráfico y sintaxis de ruta de acceso de propiedades .

Los estilos predeterminados para los controles a veces definen animaciones de transformaciones como parte de su comportamiento de estado visual. Por ejemplo, los estados visuales de ProgressRing usan valores de RotateTransform animados para "girar" los puntos en el anillo.

Este es un ejemplo sencillo de cómo animar una transformación. En este caso, anima el Angle de un RotateTransform, haciendo girar un Rectángulo en su lugar alrededor de su centro visual. En este ejemplo se nombra el RotateTransform, por lo que no necesita usar destinos indirectos para la animación, pero alternativamente podría dejar la transformación sin nombre, nombrar el elemento al que se aplica la transformación y usar destinos indirectos, como (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();
}

Gestión de los marcos de referencia de coordenadas en tiempo de ejecución

UIElement tiene un método denominado TransformToVisual, que puede generar un Transform de que correlaciona los marcos de coordenadas de referencia para dos elementos de la UI. Puede usarlo para comparar un elemento con el marco de coordenada predeterminado de la aplicación si pasa el objeto visual raíz como primer parámetro. Esto puede ser útil si ha capturado un evento de entrada de un elemento diferente o si está intentando predecir el comportamiento de diseño sin solicitar realmente un pase de diseño.

Nota:

(UWP) Los datos de eventos obtenidos a partir de eventos de puntero proporcionan acceso a un método GetCurrentPoint , donde puede especificar un parámetro relativeTo para cambiar el marco de coordenada de referencia a un elemento específico en lugar del valor predeterminado de la aplicación. Este enfoque simplemente aplica una transformación de traslación internamente y transforma para ti los datos de coordenadas x-y cuando crea el objeto PointerPoint devuelto de .

Describir una transformación matemáticamente

Una transformación se puede describir en términos de una matriz de transformación. Se usa una matriz 3×3 para describir las transformaciones en un plano x-y bidimensional. Las matrices de transformación afines se pueden multiplicar para formar cualquier número de transformaciones lineales, que incluyen rotación e inclinación (cizalladura), seguidas de la traslación. La columna final de una matriz de transformación affine es igual a (0, 0, 1), por lo que solo debe especificar los miembros de las dos primeras columnas de la descripción matemática.

La descripción matemática de una transformación puede ser útil si tiene un fondo matemático o una familiaridad con las técnicas de programación de gráficos que también usan matrices para describir las transformaciones del espacio de coordenadas. Hay una clase derivada de transformaciónque te permite expresar una transformación directamente en términos de su matriz 3×3: MatrixTransform. MatrixTransform tiene una propiedad Matrix, que alberga una estructura con seis propiedades: M11, M12, M21, M22, OffsetX y OffsetY. Cada propiedad Matrix utiliza un valor Double y corresponde a los seis valores relevantes (columnas 1 y 2) de una matriz de transformación afín.

Columna 1 Columna 2 Columna 3
M11 M12 0
M21 M22 0
OffsetX desplazamientoY 1

Cualquier transformación que pueda describir con un TranslateTransform, ScaleTransform, RotateTransformo SkewTransform objeto, podría describirse igualmente por un MatrixTransform con un valor Matrix. Pero normalmente solo usa TranslateTransform y los demás porque las propiedades de esas clases de transformación son más fáciles de conceptualizar que establecer los componentes vectoriales en una matriz. También es más fácil animar las propiedades discretas de las transformaciones; Una matriz es realmente una estructura y no un DependencyObject, por lo que no puede admitir valores individuales animados.

Algunas herramientas de diseño XAML que te permiten aplicar operaciones de transformación serializarán los resultados como MatrixTransform. En este caso, puede ser mejor volver a usar la misma herramienta de diseño para cambiar el efecto de transformación y serializar el XAML de nuevo, en lugar de intentar manipular los valores de Matriz directamente en el XAML.

Transformaciones 3-D

En Windows 10, XAML introdujo una nueva propiedad, UIElement.Transform3D, que se puede usar para crear efectos 3D con la interfaz de usuario. Para ello, use PerspectiveTransform3D para agregar una perspectiva 3D compartida o "cámara" a la escena y, a continuación, use CompositeTransform3D para transformar un elemento en espacio 3D, como usaría CompositeTransform. Consulte UIElement.Transform3D para obtener una explicación sobre cómo implementar transformaciones 3D.

Para efectos 3D más sencillos que solo se aplican a un solo objeto, se puede usar la propiedad UIElement.Projection . El uso de planeProjection como valor para esta propiedad es equivalente a aplicar una transformación de perspectiva fija y una o varias transformaciones 3D al elemento. Este tipo de transformación se describe con más detalle en efectos de perspectiva 3D para la interfaz de usuario XAML.