Animaciones basadas en relacionesRelation based animations

En este artículo se proporciona una breve introducción sobre cómo crear animaciones basadas en relaciones mediante ExpressionAnimations de composición.This article provides a brief overview of how to make relation-based animations using Composition ExpressionAnimations.

Experiencias basadas en relaciones dinámicasDynamic Relation-based Experiences

Al crear experiencias de movimiento en una aplicación, hay veces en las que el movimiento no se basa en el tiempo, sino que depende de una propiedad en otro objeto.When building out motion experiences in an app, there are times when the motion is not time-based, but rather dependent on a property on another object. KeyFrameAnimations no pueden expresar fácilmente estos tipos de experiencias de movimiento.KeyFrameAnimations are not able to express these types of motion experiences very easily. En estas instancias específicas, el movimiento ya no necesita ser discreto y predefinido.In these specific instances, motion no longer needs to be discrete and pre-defined. En su lugar, el movimiento puede adaptarse dinámicamente en función de su relación con otras propiedades del objeto.Instead, the motion can dynamically adapt based on its relationship to other object properties. Por ejemplo, puede animar la opacidad de un objeto en función de su posición horizontal.For example, you can animate the opacity of an object based on its horizontal position. Otros ejemplos incluyen experiencias de movimiento como encabezados permanentes y Parallax.Other examples include motion experiences like Sticky Headers and Parallax.

Estos tipos de experiencias de movimiento le permiten crear una interfaz de usuario que está más conectada, en lugar de sentirse singular e independiente.These types of motion experiences let you create UI that feels more connected, instead of feeling singular and independent. Para el usuario, esto da la impresión de una experiencia dinámica de IU.To the user, this gives the impression of a dynamic UI experience.

Círculo en órbita

Vista de lista con Parallax

Usar ExpressionAnimationsUsing ExpressionAnimations

Para crear experiencias de movimiento basadas en relaciones, se usa el tipo ExpressionAnimation.To create relation-based motion experiences, you use the ExpressionAnimation type. ExpressionAnimations (o Expresiones abreviadas), son un nuevo tipo de animación que permite expresar una relación matemática: una relación que el sistema utiliza para calcular el valor de una propiedad de animación en cada fotograma.ExpressionAnimations (or Expressions for short), are a new type of animation that let you express a mathematical relationship – a relationship that the system uses to calculate the value of an animating property every frame. En otras palabras, las expresiones son simplemente una ecuación matemática que define el valor deseado de una propiedad de animación por fotograma.Put another way, Expressions are simply a mathematical equation that defines the desired value of an animating property per frame. Las expresiones son un componente muy versátil que se puede usar en una amplia variedad de escenarios, entre los que se incluyen:Expressions are a very versatile component that can be used across a wide variety of scenarios, including:

Al trabajar con ExpressionAnimations, hay un par de cosas que merece la pena mencionar:When working with ExpressionAnimations, there are a couple of things worth mentioning up front:

  • Nunca termina: a diferencia de su elemento del mismo nivel KeyFrameAnimation, las expresiones no tienen una duración finita.Never Ending – unlike its KeyFrameAnimation sibling, Expressions don’t have a finite duration. Dado que las expresiones son relaciones matemáticas, son animaciones que se ejecutan constantemente.Because Expressions are mathematical relationships, they are animations that are constantly "running". Tiene la opción de detener estas animaciones si lo prefiere.You have the option to stop these animations if you choose.
  • En ejecución, pero no siempre evaluando, el rendimiento siempre es un problema con las animaciones que se están ejecutando constantemente.Running, but not always evaluating – performance is always a concern with animations that are constantly running. Sin necesidad de preocuparse, el sistema es lo suficientemente inteligente como para que la expresión se vuelva a evaluar solo si alguna de sus entradas o parámetros ha cambiado.No need to worry though, the system is smart enough that the Expression will only re-evaluate if any of its inputs or parameters have changed.
  • Resolver el tipo de objeto correcto: dado que las expresiones son relaciones matemáticas, es importante asegurarse de que la ecuación que define la expresión se resuelve en el mismo tipo de la propiedad de destino de la animación.Resolving to the right object type – Because Expressions are mathematical relationships, it is important to make sure that the equation that defines the Expression resolves to the same type of the property being targeted by the animation. Por ejemplo, si se anima el desplazamiento, la expresión se debe resolver como un tipo Vector3.For example, if animating Offset, your Expression should resolve to a Vector3 type.

Componentes de una expresiónComponents of an Expression

Al generar la relación matemática de una expresión, hay varios componentes principales:When building the mathematical relationship of an Expression, there are several core components:

  • Parámetros: valores que representan valores constantes o referencias a otros objetos de composición.Parameters – values representing constant values or references to other Composition objects.
  • Operadores matemáticos: los operadores matemáticos más (+), menos (-), multiplicación (*), división (/) que se combinan con los parámetros para formar una ecuación.Mathematical Operators – the typical mathematical operators plus(+), minus(-), multiply(*), divide(/) that join together parameters to form an equation. También se incluyen operadores condicionales como mayor que (>), igual (= =), operador ternario (condición?Also included are conditional operators such as greater than(>), equal(==), ternary operator (condition ? ifTrue: ifFalse), etc.ifTrue : ifFalse), etc.
  • Funciones matemáticas: funciones o accesos directos basados en System. Numerics.Mathematical Functions – mathematical functions/shortcuts based on System.Numerics. Para obtener una lista completa de las funciones admitidas, vea ExpressionAnimation.For a full list of supported functions, see ExpressionAnimation.

Las expresiones también admiten un conjunto de palabras clave: frases especiales que tienen un significado distinto solo dentro del sistema ExpressionAnimation.Expressions also support a set of keywords – special phrases that have distinct meaning only within the ExpressionAnimation system. Estos se enumeran (junto con la lista completa de funciones matemáticas) en la documentación de ExpressionAnimation .These are listed (along with the full list of math functions) in the ExpressionAnimation documentation.

Crear expresiones con ExpressionBuilderCreating Expressions with ExpressionBuilder

Hay dos opciones para compilar expresiones en la aplicación para UWP:There are two options for building Expressions in your UWP app:

  1. Cree la ecuación como una cadena a través de la API pública oficial.Build the equation as a string via the official, public API.
  2. Cree la ecuación en un modelo de objetos con seguridad de tipos a través de la herramienta ExpressionBuilder incluida en el kit de herramientas de la comunidad de Windows.Build the equation in a type-safe object model via the ExpressionBuilder tool included with the Windows Community Toolkit.

En este documento, se definirán las expresiones mediante ExpressionBuilder.For the sake of this document, we will define our Expressions using ExpressionBuilder.

ParámetrosParameters

Los parámetros componen el núcleo de una expresión.Parameters make up the core of an Expression. Hay dos tipos de parámetros:There are two types of parameters:

  • Constantes: son parámetros que representan variables System. Numeric con tipo.Constants: these are parameters representing typed System.Numeric variables. Estos parámetros obtienen sus valores asignados una vez cuando se inicia la animación.These parameters get their values assigned once when the animation is started.
  • Referencias: son parámetros que representan referencias a CompositionObjects: estos parámetros obtienen continuamente sus valores actualizados después de que se inicie una animación.References: these are parameters representing references to CompositionObjects – these parameters continuously get their values updated after an animation is started.

En general, las referencias son el aspecto principal del modo en que la salida de una expresión puede cambiar dinámicamente.In general, References are the main aspect for how an Expression’s output can dynamically change. A medida que estas referencias cambian, el resultado de la expresión cambia como resultado.As these references change, the output of the Expression changes as a result. Si crea la expresión con cadenas o las usa en un escenario de plantillas (mediante la expresión para tener como destino varios CompositionObjects), deberá asignar un nombre y establecer los valores de los parámetros.If you create your Expression with Strings or use them in a templating scenario (using your Expression to target multiple CompositionObjects), you will need to name and set the values of your parameters. Consulta la sección Ejemplos para obtener más información.See the Example section for more info.

Trabajar con KeyFrameAnimationsWorking with KeyFrameAnimations

Las expresiones también se pueden utilizar con KeyFrameAnimations.Expressions can also be used with KeyFrameAnimations. En estos casos, desea utilizar una expresión para definir el valor de un fotograma clave en un momento dado: estos tipos fotogramas clave se denominan ExpressionKeyFrames.In these instances, you want to use an Expression to define the value of a KeyFrame at a time spot – these types KeyFrames are called ExpressionKeyFrames.

KeyFrameAnimation.InsertExpressionKeyFrame(Single, String)
KeyFrameAnimation.InsertExpressionKeyFrame(Single, ExpressionNode)

Sin embargo, a diferencia de ExpressionAnimations, ExpressionKeyFrames solo se evalúa una vez cuando se inicia KeyFrameAnimation.However, unlike ExpressionAnimations, ExpressionKeyFrames are evaluated only once when the KeyFrameAnimation is started. Tenga en cuenta que no pasa un ExpressionAnimation como valor del fotograma clave, en lugar de una cadena (o un ExpressionNode, si está usando ExpressionBuilder).Keep in mind, you do not pass in an ExpressionAnimation as the value of the KeyFrame, rather a string (or an ExpressionNode, if you're using ExpressionBuilder).

EjemploExample

Ahora veremos un ejemplo del uso de expresiones, específicamente el ejemplo PropertySet de la galería de ejemplos de la interfaz de usuario de Windows.Let's now walk through an example of using Expressions, specifically the PropertySet sample from the Windows UI Sample Gallery. Veremos la expresión que administra el comportamiento de movimiento de órbita de la bola azul.We'll look at the Expression managing the orbit motion behavior of the blue ball.

Círculo en órbita

Hay tres componentes en juego para la experiencia total:There are three components at play for the total experience:

  1. KeyFrameAnimation, que anima el desplazamiento Y de la bola roja.A KeyFrameAnimation, animating the Y Offset of the red ball.
  2. PropertySet con una propiedad de giro que ayuda a que se impulsa la órbita, animada por otro KeyFrameAnimation.A PropertySet with a Rotation property that helps drives the orbit, animated by another KeyFrameAnimation.
  3. ExpressionAnimation que controla el desplazamiento de la bola azul que hace referencia al desplazamiento de esfera rojo y la propiedad Rotation para mantener una órbita perfecta.An ExpressionAnimation that drives the Offset of the blue ball referencing the Red Ball Offset and the Rotation property to maintain a perfect orbit.

Nos centraremos en el ExpressionAnimation definido en #3.We’ll be focusing on the ExpressionAnimation defined in #3. También usaremos las clases ExpressionBuilder para construir esta expresión.We will also be using the ExpressionBuilder classes to construct this Expression. Al final se muestra una copia del código que se usa para generar esta experiencia a través de cadenas.A copy of the code used to build this experience via Strings is listed at the end.

En esta ecuación, hay dos propiedades a las que debe hacer referencia desde el PropertySet; uno es un desplazamiento CenterPoint y el otro es la rotación.In this equation, there are two properties you need to reference from the PropertySet; one is a centerpoint offset and the other is the rotation.

var propSetCenterPoint =
_propertySet.GetReference().GetVector3Property("CenterPointOffset");

// This rotation value will animate via KFA from 0 -> 360 degrees
var propSetRotation = _propertySet.GetReference().GetScalarProperty("Rotation");

A continuación, debe definir el componente Vector3 que tiene en cuenta la rotación en órbita real.Next, you need to define the Vector3 component that accounts for the actual orbiting rotation.

var orbitRotation = EF.Vector3(
    EF.Cos(EF.ToRadians(propSetRotation)) * 150,
    EF.Sin(EF.ToRadians(propSetRotation)) * 75, 0);

Nota

EF es una notación abreviada de "uso" para definir ExpressionFunctions.EF is a shorthand "using" notation to define ExpressionFunctions.

using EF = Microsoft.Toolkit.Uwp.UI.Animations.Expressions.ExpressionFunctions;

Por último, combine estos componentes juntos y haga referencia a la posición de la bola roja para definir la relación matemática.Finally, combine these components together and reference the position of the Red Ball to define the mathematical relationship.

var orbitExpression = redSprite.GetReference().Offset + propSetCenterPoint + orbitRotation;
blueSprite.StartAnimation("Offset", orbitExpression);

En una situación hipotética, ¿qué ocurre si quiere usar esta misma expresión pero con otros dos objetos visuales, lo que significa 2 conjuntos de círculos en órbitas.In a hypothetical situation, what if you wanted to use this same Expression but with two other Visuals, meaning 2 sets of orbiting circles. Con CompositionAnimations, puede volver a usar la animación y seleccionar varios CompositionObjects de destino.With CompositionAnimations, you can re-use the animation and target multiple CompositionObjects. Lo único que debe cambiar al usar esta expresión para el caso de órbita adicional es la referencia al elemento visual.The only thing you need to change when you use this Expression for the additional orbit case is the reference to the Visual. Llamamos a esta plantilla.We call this templating.

En este caso, debe modificar la expresión generada anteriormente.In this case, you modify the Expression you built earlier. En lugar de "obtener" una referencia a CompositionObject, se crea una referencia con un nombre y, a continuación, se asignan valores diferentes:Rather than "getting" a reference to the CompositionObject, you create a reference with a name and then assign different values:

var orbitExpression = ExpressionValues.Reference.CreateVisualReference("orbitRoundVisual");
orbitExpression.SetReferenceParameter("orbitRoundVisual", redSprite);
blueSprite.StartAnimation("Offset", orbitExpression);
// Later on … use same Expression to assign to another orbiting Visual
orbitExpression.SetReferenceParameter("orbitRoundVisual", yellowSprite);
greenSprite.StartAnimation("Offset", orbitExpression);

Este es el código si definió la expresión con cadenas a través de la API pública.Here is the code if you defined your Expression with Strings via the public API.

ExpressionAnimation expressionAnimation =
compositor.CreateExpressionAnimation("visual.Offset + " +
"propertySet.CenterPointOffset + " +
"Vector3(cos(ToRadians(propertySet.Rotation)) * 150," + "sin(ToRadians(propertySet.Rotation)) * 75, 0)");
 var propSetCenterPoint = _propertySet.GetReference().GetVector3Property("CenterPointOffset");
 var propSetRotation = _propertySet.GetReference().GetScalarProperty("Rotation");
expressionAnimation.SetReferenceParameter("propertySet", _propertySet);
expressionAnimation.SetReferenceParameter("visual", redSprite);