Animazioni basate su relazioniRelation based animations

Questo articolo fornisce una breve panoramica su come creare animazioni basate su relazioni usando la composizione ExpressionAnimations.This article provides a brief overview of how to make relation-based animations using Composition ExpressionAnimations.

Esperienze dinamiche basate su relazioniDynamic Relation-based Experiences

Quando si compilano esperienze di movimento in un'app, in alcuni casi il movimento non è basato sul tempo, ma piuttosto dipende da una proprietà in un altro oggetto.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 non sono in grado di esprimere molto facilmente questi tipi di esperienze di movimento.KeyFrameAnimations are not able to express these types of motion experiences very easily. In queste istanze specifiche, l'azione non deve più essere discreta e predefinita.In these specific instances, motion no longer needs to be discrete and pre-defined. Il movimento può invece adattarsi dinamicamente in base alla relazione con altre proprietà dell'oggetto.Instead, the motion can dynamically adapt based on its relationship to other object properties. Ad esempio, è possibile animare l'opacità di un oggetto in base alla relativa posizione orizzontale.For example, you can animate the opacity of an object based on its horizontal position. Altri esempi includono le esperienze di movimento come le intestazioni permanenti e Parallax.Other examples include motion experiences like Sticky Headers and Parallax.

Questi tipi di esperienze di movimento consentono di creare un'interfaccia utente che risulta più connessa, anziché sentirsi singolari e indipendenti.These types of motion experiences let you create UI that feels more connected, instead of feeling singular and independent. Per l'utente, questo dà l'impressione di un'esperienza dinamica dell'interfaccia utente.To the user, this gives the impression of a dynamic UI experience.

Cerchio in orbita

Visualizzazione elenco con parallasse

Uso di ExpressionAnimationsUsing ExpressionAnimations

Per creare esperienze di movimento basate su relazioni, usare il tipo ExpressionAnimation.To create relation-based motion experiences, you use the ExpressionAnimation type. ExpressionAnimations (o le espressioni per Short) sono un nuovo tipo di animazione che consente di esprimere una relazione matematica, ovvero una relazione che il sistema usa per calcolare il valore di una proprietà di animazione ogni frame.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. In altre parole, le espressioni sono semplicemente un'equazione matematica che definisce il valore desiderato di una proprietà di animazione per fotogramma.Put another way, Expressions are simply a mathematical equation that defines the desired value of an animating property per frame. Le espressioni sono un componente molto versatile che può essere usato in un'ampia gamma di scenari, tra cui:Expressions are a very versatile component that can be used across a wide variety of scenarios, including:

Quando si lavora con ExpressionAnimations, è opportuno citare un paio di aspetti:When working with ExpressionAnimations, there are a couple of things worth mentioning up front:

  • Senza terminazione: a differenza del relativo KeyFrameAnimation di pari livello, le espressioni non hanno una durata finita.Never Ending – unlike its KeyFrameAnimation sibling, Expressions don’t have a finite duration. Poiché le espressioni sono relazioni matematiche, si tratta di animazioni costantemente "in esecuzione".Because Expressions are mathematical relationships, they are animations that are constantly "running". È possibile scegliere di arrestare queste animazioni.You have the option to stop these animations if you choose.
  • In esecuzione, ma non sempre valutando, le prestazioni sono sempre un problema con le animazioni costantemente in esecuzione.Running, but not always evaluating – performance is always a concern with animations that are constantly running. Non è necessario preoccuparsi, tuttavia, il sistema è sufficientemente intelligente da consentire all'espressione di rivalutare solo se uno qualsiasi dei relativi input o parametri è stato modificato.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.
  • Risoluzione nel tipo di oggetto corretto: poiché le espressioni sono relazioni matematiche, è importante assicurarsi che l'equazione che definisce l'espressione venga risolta nello stesso tipo della proprietà di destinazione dell'animazione.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. Se ad esempio si aggiunge un'animazione all'offset, l'espressione deve essere risolta in un tipo Vector3.For example, if animating Offset, your Expression should resolve to a Vector3 type.

Componenti di un'espressioneComponents of an Expression

Quando si compila la relazione matematica di un'espressione, sono disponibili diversi componenti di base:When building the mathematical relationship of an Expression, there are several core components:

  • Parameters: valori che rappresentano valori costanti o riferimenti ad altri oggetti di composizione.Parameters – values representing constant values or references to other Composition objects.
  • Operatori matematici: operatori matematici tipici più (+), meno (-), moltiplicazione (*), divisione (/) che uniscono i parametri per formare un'equazione.Mathematical Operators – the typical mathematical operators plus(+), minus(-), multiply(*), divide(/) that join together parameters to form an equation. Sono inclusi anche operatori condizionali, ad esempio maggiore di (>), uguale (= =), operatore ternario (condizione?Also included are conditional operators such as greater than(>), equal(==), ternary operator (condition ? ifTrue: ifFalse) e così via.ifTrue : ifFalse), etc.
  • Funzioni matematiche-funzioni matematiche/tasti di scelta rapida basati su System. Numerics.Mathematical Functions – mathematical functions/shortcuts based on System.Numerics. Per un elenco completo delle funzioni supportate, vedere ExpressionAnimation.For a full list of supported functions, see ExpressionAnimation.

Le espressioni supportano anche un set di parole chiave, ovvero frasi speciali che hanno un significato distinto solo all'interno del sistema ExpressionAnimation.Expressions also support a set of keywords – special phrases that have distinct meaning only within the ExpressionAnimation system. Questi sono elencati (insieme all'elenco completo delle funzioni matematiche) nella documentazione di ExpressionAnimation .These are listed (along with the full list of math functions) in the ExpressionAnimation documentation.

Creazione di espressioni con ExpressionBuilderCreating Expressions with ExpressionBuilder

Sono disponibili due opzioni per la compilazione di espressioni nell'app UWP:There are two options for building Expressions in your UWP app:

  1. Compilare l'equazione come stringa tramite l'API pubblica ufficiale.Build the equation as a string via the official, public API.
  2. Compilare l'equazione in un modello a oggetti indipendente dai tipi tramite lo strumento ExpressionBuilder incluso in Windows community Toolkit.Build the equation in a type-safe object model via the ExpressionBuilder tool included with the Windows Community Toolkit.

Ai fini di questo documento, si definiranno le espressioni con ExpressionBuilder.For the sake of this document, we will define our Expressions using ExpressionBuilder.

ParametriParameters

I parametri costituiscono il nucleo di un'espressione.Parameters make up the core of an Expression. Esistono due tipi di parametri:There are two types of parameters:

  • Costanti: si tratta di parametri che rappresentano variabili tipizzate System. Numeric.Constants: these are parameters representing typed System.Numeric variables. Questi parametri ottengono i valori assegnati una volta all'avvio dell'animazione.These parameters get their values assigned once when the animation is started.
  • Riferimenti: si tratta di parametri che rappresentano i riferimenti a CompositionObjects. questi parametri ottengono continuamente i valori aggiornati dopo l'avvio di un'animazione.References: these are parameters representing references to CompositionObjects – these parameters continuously get their values updated after an animation is started.

In generale, i riferimenti sono l'aspetto principale per il modo in cui l'output di un'espressione può essere modificato dinamicamente.In general, References are the main aspect for how an Expression’s output can dynamically change. Quando questi riferimenti cambiano, l'output dell'espressione viene modificato di conseguenza.As these references change, the output of the Expression changes as a result. Se si crea un'espressione con stringhe o la si usa in uno scenario di modello (usando l'espressione per la destinazione di più CompositionObjects), sarà necessario assegnare un nome e impostare i valori dei parametri.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. Per altre informazioni, vedi la sezione Esempi.See the Example section for more info.

Uso di KeyFrameAnimationsWorking with KeyFrameAnimations

Le espressioni possono essere usate anche con KeyFrameAnimations.Expressions can also be used with KeyFrameAnimations. In queste istanze si vuole usare un'espressione per definire il valore di un fotogramma chiave in un momento specifico. questi tipi di fotogrammi chiave sono denominati 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)

Tuttavia, a differenza di ExpressionAnimations, ExpressionKeyFrames vengono valutati solo una volta all'avvio del KeyFrameAnimation.However, unlike ExpressionAnimations, ExpressionKeyFrames are evaluated only once when the KeyFrameAnimation is started. Tenere presente che non viene passato un ExpressionAnimation come valore del fotogramma chiave, invece una stringa (o un ExpressionNode se si usa 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).

EsempioExample

Esaminiamo ora un esempio di utilizzo delle espressioni, in particolare l'esempio PropertySet della raccolta di esempi dell'interfaccia utente di Windows.Let's now walk through an example of using Expressions, specifically the PropertySet sample from the Windows UI Sample Gallery. Si esaminerà l'espressione che gestisce il comportamento di movimento dell'orbita della palla blu.We'll look at the Expression managing the orbit motion behavior of the blue ball.

Cerchio in orbita

Per l'esperienza totale sono disponibili tre componenti:There are three components at play for the total experience:

  1. Oggetto KeyFrameAnimation, che anima l'offset Y della palla rossa.A KeyFrameAnimation, animating the Y Offset of the red ball.
  2. PropertySet con una proprietà Rotation che consente di guidare l'orbita, animata da un altro KeyFrameAnimation.A PropertySet with a Rotation property that helps drives the orbit, animated by another KeyFrameAnimation.
  3. Oggetto ExpressionAnimation che determina l'offset della palla blu che fa riferimento all'offset della pallina rossa e alla proprietà Rotation per mantenere un'orbita perfetta.An ExpressionAnimation that drives the Offset of the blue ball referencing the Red Ball Offset and the Rotation property to maintain a perfect orbit.

Ci concentreremo sul ExpressionAnimation definito in #3.We’ll be focusing on the ExpressionAnimation defined in #3. Per costruire questa espressione verranno utilizzate anche le classi ExpressionBuilder.We will also be using the ExpressionBuilder classes to construct this Expression. Una copia del codice usato per compilare questa esperienza tramite stringhe è indicata alla fine.A copy of the code used to build this experience via Strings is listed at the end.

In questa equazione, è necessario fare riferimento a due proprietà da PropertySet; uno è un offset Centerpoint e l'altro è la rotazione.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");

Successivamente, è necessario definire il componente Vector3 che rappresenta la rotazione di orbita effettiva.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 è una notazione "using" abbreviata per definire ExpressionFunctions.EF is a shorthand "using" notation to define ExpressionFunctions.

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

Infine, combinare questi componenti insieme e fare riferimento alla posizione della palla rossa per definire la relazione matematica.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);

In una situazione ipotetica, cosa accade se si vuole usare questa stessa espressione, ma con altri due oggetti visivi, vale a dire 2 set di cerchi in orbita.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 è possibile riutilizzare l'animazione e la destinazione di più CompositionObjects.With CompositionAnimations, you can re-use the animation and target multiple CompositionObjects. L'unica cosa che è necessario modificare quando si usa questa espressione per il caso di orbita aggiuntivo è il riferimento all'oggetto visivo.The only thing you need to change when you use this Expression for the additional orbit case is the reference to the Visual. Questo modello viene chiamato.We call this templating.

In questo caso, si modifica l'espressione compilata in precedenza.In this case, you modify the Expression you built earlier. Anziché "ottenere" un riferimento a CompositionObject, si crea un riferimento con un nome e quindi si assegnano valori diversi: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);

Ecco il codice se l'espressione è stata definita con stringhe tramite l'API pubblica.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);