Juanma Santoyo

En ocasiones me llaman friki

Animar transformaciones en WPF con el método BeginAnimation

| 9 Comentarios

Me preguntaron hace poco cómo animar elementos en Microsoft Surface. En esencia se haría como en cualquier entorno basado en WPF.

Hay varias formas de animar, pero quizás una de las más sencilla y potente sea la animación de transformaciones con el método BeginAnimation.

Las transformaciones.

En WPF existen varios tipos de transformaciones:

Animar transformaciones.

La idea es simple: Una animación consiste en modificar progresivamente el valor de una propiedad durante un periodo de tiempo. En principio, se puede animar cualquier propiedad de dependencia del API de WPF.

Concretamente, las transformaciones usan propiedades de dependencia para modificar el aspecto del elemento en el que se aplican; así que si aplicamos una animación sobre una propiedad de una transformación de cualquier tipo, el resultado será una animación sobre el elemento.

El código para aplicar una transformación es sencillo. Se puede aplicar desde XAML o desde C#, pero en lo personal prefiero hacerlo en XAML:

	<Image x:Name="MyImage" Source="images/myimage.png" Width="100" Height="100">
		<Image.RenderTransform>
			<TransformGroup>
				<TranslateTransform x:Name="Translacion" X="85" />
				<RotateTransform x:Name="Rotacion" Angle="0" CenterX="15" CenterY="15" />
			</TransformGroup>
		</Image.RenderTransform>
	</Image>

Fijaos que al usar el nodo “TransformGroup” podemos aplicar más de una transformación. De no usarlo sólo podríamos aplicar una, ya que el nodo “Image.RenderTransform” sólo admite un nodo hijo. Notad también que las transformaciones se aplican desde la última a la primera. No es lo mismo mover y rotar, que rotar y mover.

Las animaciones y el método BeginAnimation.

A nivel práctico, una animación es un objeto con una serie de propiedades configuradas, como por ejemplo la duración de la animación, la aceleración, el valor inicial y final de la propiedad, etc. Dependiendo del tipo de dato que queramos animar, el objeto de animación cambia. No es lo mismo animar un color (ColorAnimation) que una orientación (DoubleAnimation). Se pueden ver todos los tipos de animación posible en la especificación de la clase madre: AnimationTimeLine.

Para aplicar una animación sobre una transformación, contamos con un potente aliado: el método BeginAnimation, presente en todas las transformaciones. Al método BeginAnimation se le pasan dos parámetros: la propiedad de dependencia a animar, y la animación. La animación deberemos construirla en base a lo que queremos animar, la propiedad de dependencia es una propiedad estática de la clase a la que pertenece el elemento que queremos animar. Por ejemplo, si queremos animar el ángulo de un RotateTransform, tendremos una propiedad estática “RotateTransform.AngleProperty“. Más fácil con un poco de código C#:

	DoubleAnimation animacion = new DoubleAnimation();

	animacion.To = 180;
	animacion.Duration = new Duration(TimeSpan.FromMilliseconds(1000));

	Rotacion.BeginAnimation(RotateTransform.AngleProperty, animacion);

Es todo por el momento.

Y en realidad no hay mucho más que decir sobre animaciones. Sólo destacar que, como imagináis, el objeto animación tiene eventos que informarán del estado del proceso, y que no son bloqueantes (es decir, mientras una animación se ejecuta, el flujo del programa no se detiene, por lo que necesitan una gestión asíncrona). También destacar que la animación se iniciará en el instante en que se ejecute el método BeginAnimation.

Si queréis aprender sobre animaciones más complejas, os recomiendo que miréis el objeto StoryBoard.

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone

9 Comments

  1. Hola de nuevo! gracias por la entrada, me ayudo mucho… aunque me falta pulir algunas cosas 😛

    Sabes de conectar con la base de datos? te explico un poco, es un proyecto personal para el surface y quiero tener en un deslizable credenciales, que solo se vea el nombre de X persoa y su foto, y a la hora de seleccionarla que en otra pantalla aparezcan sus datos, ya solo me falta la coneccion, que no puedo con ella, si tubieras info de donde me pueda ayudar, te lo agradeceria mucho

    ten buen dia!!!

    Saludos

  2. Pues yo diría que conectarse a una base de datos es exáctamente igual en cualquier aplicación WPF (incluyendo aplucaciones para surface).

    Lo que necesitas básicamente es saber cómo vas a acceder a la base de datos, y la cadena de conexión.

    Básicamente, lo que necesitas es el Entity Framework:
    http://msdn.microsoft.com/en-us/library/aa697427%28VS.80%29.aspx

    Un saludo.

  3. hola muy buen aporte bueno llevo dias y no he podido hacer una animacion de un objeto de tipo Container que creo desde codigo y necesito que gire sobre su propio eje dependiendo del movimiento del mouse … en pocas palabras quiero que la cara de mi contendor gire con el mouse

  4. Pues nunca he usado ese objeto Container. ¿Te refieres a este?:

    http://msdn.microsoft.com/en-us/library/bxa2xz9d.aspx

    Si es este el objeto Container que dices, deberías considerar cambiarlo por otro, por que parece que no puede ser animado (no tiene la propiedad ‘RenderTransform’, ni propiedades de dependencia para der animado).

    Un saludo.

  5. Hola de nuevo

    Felicidades por el proyecto, en el video se va interesante, ya pondre el proyecto en el que trabajo, aunque no es tan complejo.

    me podrias ayudar en algo mas???

    Estoy haciendo credenciales para empleados, claro, se muestran en el surface, no fisicamente, pero no se como acomodarlas en el grid donde las estoy poniendo, que se acomoden automaticamnte por el nombre que tienen en el SurfaceextBox, sabesde donde me podria basar o ayudar para hacerlo, gracias :)

    • Hola Patrunks.

      Para serte sincero, no acabo de entender tu pregunta. Pero si el problema está en posicionar elementos en un Grid, es sencillo:

      Como sabrás, los grids se dividen en filas y en columnas. Lo primero que debes tener claro es cuantas filas y columnas tiene tu Grid. Para especificar las filas y columnas de tu Grid, debes usar los nodos Grid.RowDefinitions, y Grid.ColumDefinitions. Por ejemplo, supongamos que quieres hacer un grid de dos filas y dos columnas:

      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height="100" />
              <RowDefinition Height="100" />
          </Grid.RowDefinitions>
          
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="100" />
              <ColumnDefinition Width="100" />
          </Grid.ColumnDefinitions>
      </Grid>

      Por otra parte, para ubicar un elemento en una fila y una columna concretas del Grid, puedes usar las propiedades Grid.Row y Grid.Column en los nodos de dichos elementos. Por ejemplo, siendo un sistema de credenciales básico de usuario y contraseña:

      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height="100" />
              <RowDefinition Height="100" />
          </Grid.RowDefinitions>
          
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="100" />
              <ColumnDefinition Width="100" />
          </Grid.ColumnDefinitions>

          <Label Grid.Column="0" Grid.Row="0">Usuario</Label>
          <Label Grid.Column="0" Grid.Row="1">Contraseña</Label>

          <TextBox x:Name="Username" Grid.Column="1" Grid.Row="0" />
          <TextBox x:Name="Password" Grid.Column="1" Grid.Row="1" />
      </Grid>

      No se si es esto lo que me preguntabas, espero que te sirva de ayuda. Si no, coméntame.

      Un saludo.

  6. Hola :)

    eso si ya lo estudie jeje, ya lo domino bien :), haber deja metrato de explicar mejor

    Tengo credenciales de los empleados de mi empresa, con datos personales (nombre, apellido, numero de empleado, ext, etc) tengo una grid dividida en 2 columnas, en grid.column=0 tengo scatterviews, que tienen solo 2 cosas de los empleados, el nombre y una imagen de el empleado, al presionarlas, se leen los datos del empleado que seleccionaste desde una tabla de SQL (que aun no lo perfecciono bien jeje) y en grid.column=1, muestra los datos completos del empleado (nombre, apellido, numero de empleado, ext, etc), ahora, acomodar los scatterview no es complicado, pero deseo que se acomoden automaticamente (que lo acomode conforme a codigo), esto conforme al nombre del empleado, asi cuando se agregue uno nuevo, se genera en automatico el scaterview del nuevo empleado y se acomode en el lugar qu le corresponde

    espero haberme explicado mejor jeje

    de antemano mil gracias 😀

    • Veamos, ¿entonces tu problema consiste en que no ves claro como posicionar los objetos dentro de un ScatterView?

      Si ese es el caso, deberías tener en cuenta dos cosas:
      – Cualquier cosa que metas en un ScatterView, tiene que estar a su vez dentro de un ScatterViewItem. El objeto ScatterViewItem es al que le tienes que aplicar las propiedades de posicionamiento.
      – Posicionar un ScatterViewItem se basa en las propiedades “Center” (un objeto Point con las coordenadas X e Y) y la propiedad Orientation (un double que determina la rotación).

      Estoy acabando un artículo que inicié hace bastante tiempo sobre el manejo de ScatterViewItem con C#, quizás cuando lo publique (en un dia o dos) pueda aclararte algo.

  7. Pingback: Juanma Santoyo » Blog Archive » Reaccionar a los objetos etiquetados en Microsoft Surface: el control TagVisualization.

Deja un comentario

Los campos obligatorios están marcados con *.