関係ベース アニメーションRelation based animations

この記事では、Composition の ExpressionAnimation を使用して関係ベース アニメーションを作成する方法の概要ついて説明します。This article provides a brief overview of how to make relation-based animations using Composition ExpressionAnimations.

動的な関係ベースのエクスペリエンスDynamic Relation-based Experiences

アプリのモーション エクスペリエンスを作成するとき、モーションが時間ベースではなく、他のオブジェクトのプロパティに影響される場合があります。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 では、このような種類のモーション エクスペリエンスを簡単に表現することはできません。KeyFrameAnimations are not able to express these types of motion experiences very easily. こうした場合、モーションを独立したものとして作成したり、事前に定義したりする必要はありません。In these specific instances, motion no longer needs to be discrete and pre-defined. 代わりに、モーションと他のオブジェクトのプロパティとの関係に基づいて、モーションを動的に対応させることができます。Instead, the motion can dynamically adapt based on its relationship to other object properties. たとえば、水平方向の位置に基づいてオブジェクトの不透明度をアニメーション化することができます。For example, you can animate the opacity of an object based on its horizontal position. 他の例としては、固定ヘッダーや視差などのモーション エクスペリエンスがあります。Other examples include motion experiences like Sticky Headers and Parallax.

これらの種類のモーション エクスペリエンスを使用すると、単一で独立して動作する UI ではなく、関連性の強い動作を示す UI を作成することができます。These types of motion experiences let you create UI that feels more connected, instead of feeling singular and independent. ユーザーに対しては、動的な UI エクスペリエンスの印象を与えます。To the user, this gives the impression of a dynamic UI experience.

軌道を回る円

視差を利用したリスト ビュー

ExpressionAnimation の使用Using ExpressionAnimations

関係ベースのモーション エクスペリエンスを作成するには、ExpressionAnimation という種類のアニメーションを使用します。To create relation-based motion experiences, you use the ExpressionAnimation type. ExpressionAnimation (短く示す場合は Expression) は新しい種類のアニメーションで、数学的な関係を表すことができます。数学的な関係とは、各フレームでアニメーション化するプロパティの値を計算する際にシステムで使用される関係です。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. 言い換えれば、Expression は、各フレームでアニメーション化するプロパティの目的の値を定義する単純な方程式です。Put another way, Expressions are simply a mathematical equation that defines the desired value of an animating property per frame. Expression は用途の広いコンポーネントで、次のようなさまざまなシナリオで使用できます。Expressions are a very versatile component that can be used across a wide variety of scenarios, including:

ExpressionAnimation を使用するときは、以下の点について留意してください。When working with ExpressionAnimations, there are a couple of things worth mentioning up front:

  • 終了しない – KeyFrameAnimation とは異なり、Expression には限定された継続時間はありません。Never Ending – unlike its KeyFrameAnimation sibling, Expressions don’t have a finite duration. Expression は数学的な関係であるため、継続して "実行されている" アニメーションとなります。Because Expressions are mathematical relationships, they are animations that are constantly "running". 必要な場合は、こうしたアニメーションを停止するオプションを使用できます。You have the option to stop these animations if you choose.
  • 継続して実行されているが、常に評価されるわけではない – パフォーマンスは、継続して実行されているアニメーションと常に関連する懸念事項です。Running, but not always evaluating – performance is always a concern with animations that are constantly running. ただし、心配する必要はありません。Expression はいずれかの入力またはパラメーターが変更された場合にのみ再評価されるということを、システムでは自動的に把握するためです。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.
  • 適切なオブジェクトの種類への解決 – Expression は数学的な関係であるため、Expression ではアニメーションのターゲットとなるプロパティと同じ種類のプロパティへの解決が行われることを式で定義することが重要となります。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. たとえば、オフセットをアニメーション化する場合、Expression では Vector3 の種類に解決する必要があります。For example, if animating Offset, your Expression should resolve to a Vector3 type.

Expression のコンポーネントComponents of an Expression

Expression の数学的な関係を構築する際に利用できる主なコンポーネントには、以下のものがあります。When building the mathematical relationship of an Expression, there are several core components:

  • パラメーター – 定数値または他のコンポジション オブジェクトへの参照を表す値です。Parameters – values representing constant values or references to other Composition objects.
  • 数学演算子 – 式を構成するためにパラメーターを結合する一般的な数学演算子 (加算 (+)、減算 (-)、乗算 (*)、除算 (/)) です。Mathematical Operators – the typical mathematical operators plus(+), minus(-), multiply(*), divide(/) that join together parameters to form an equation. 条件演算子 (より大きい (>)、等しい (==) など) や、三項演算子 (condition ? Also included are conditional operators such as greater than(>), equal(==), ternary operator (condition ? ifTrue : ifFalse) なども含まれます。ifTrue : ifFalse), etc.
  • 数学関数 – System.Numerics に基づく数学関数/数学ショートカットです。Mathematical Functions – mathematical functions/shortcuts based on System.Numerics. サポートされる関数の完全な一覧については、「ExpressionAnimation」をご覧ください。For a full list of supported functions, see ExpressionAnimation.

Expression では一連のキーワードもサポートされています。キーワードとは、ExpressionAnimation システム内でのみ使われる独自の意味を持つ特別な語句です。Expressions also support a set of keywords – special phrases that have distinct meaning only within the ExpressionAnimation system. これらのキーワードの一覧 (および数学関数の完全な一覧) については、「ExpressionAnimation」の説明をご覧ください。These are listed (along with the full list of math functions) in the ExpressionAnimation documentation.

ExpressionBuilder を使用して Expression を作成するCreating Expressions with ExpressionBuilder

UWP アプリで Expression を作成するには、2 つの方法があります。There are two options for building Expressions in their UWP app:

  1. 公式のパブリック API を使用し、文字列として式を作成する。Building the equation as a string via the official, public API.
  2. オープンソースの ExpressionBuilder ツールを使用し、タイプ セーフなオブジェクト モデルで式を作成する。Building the equation in a type-safe object model via the open source ExpressionBuilder tool. Github のソースとドキュメントをご覧ください。See the Github source and documentation.

このドキュメントのために、ここでは ExpressionBuilder を使用して Expression を定義します。For the sake of this document, we will define our Expressions using ExpressionBuilder.

パラメーターParameters

パラメーターは、Expression の重要な部分を構成します。Parameters make up the core of an Expression. パラメーターには次の 2 種類があります。There are two types of parameters:

  • 定数: 型指定された System.Numeric 変数を表すパラメーターです。Constants: these are parameters representing typed System.Numeric variables. これらのパラメーターは、アニメーションが開始されたときに割り当てられる値を取得します。These parameters get their values assigned once when the animation is started.
  • 参照: CompositionObject への参照を表すパラメーターです。これらのパラメーターは、アニメーションが開始された後で更新された値を継続的に取得します。References: these are parameters representing references to CompositionObjects – these parameters continuously get their values updated after an animation is started.

一般的に参照は、Expression の出力が動的に変更される方法に関連する主要な側面となります。In general, References are the main aspect for how an Expression’s output can dynamically change. 参照が変更されると、その結果に伴って Expression の出力も変更されます。As these references change, the output of the Expression changes as a result. String を使用して Expression を作成する場合、またはテンプレートのシナリオで String を使用する場合 (複数の CompositionObject をターゲットとする Expression を使用)、パラメーターの名前を指定し、その値を設定する必要があります。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. 詳しくは、「例」セクションをご覧ください。See the Example section for more info.

KeyFrameAnimation の操作Working with KeyFrameAnimations

Expression は、KeyFrameAnimation と共にも使用することもできます。Expressions can also be used with KeyFrameAnimations. このような場合、ある時点での KeyFrame の値を定義する Expression を使用する必要があります。このような種類の KeyFrame は、ExpressionKeyFrame と呼ばれます。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)

ただし ExpressionAnimation とは異なり、ExpressionKeyFrame は KeyFrameAnimation の起動時に 1 回だけ評価されます。However, unlike ExpressionAnimations, ExpressionKeyFrames are evaluated only once when the KeyFrameAnimation is started. ExpressionAnimation を KeyFrame の値として渡すのではなく、文字列 (または ExpressionBuilder を使用している場合は ExpressionNode) として渡すという点に注意してください。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).

Example

Expression を使用した例を確認してみましょう。具体的には、Windows UI サンプル ギャラリーの PropertySet の例を紹介します。Let's now walk through an example of using Expressions, specifically the PropertySet sample from the Windows UI Sample Gallery. ここでは、軌道を回る青い円のモーションの動作を管理する Expression について説明します。We'll look at the Expression managing the orbit motion behavior of the blue ball.

軌道を回る円

エクスペリエンス全体では、3 つのコンポーネントが使用されています。There are three components at play for the total experience:

  1. KeyFrameAnimation。赤い円の Y オフセットをアニメーション化しています。A KeyFrameAnimation, animating the Y Offset of the red ball.
  2. 軌道の周回を駆動する際に利用される Rotation プロパティを含んでいる PropertySet。他の KeyFrameAnimation によってアニメーション化されます。A PropertySet with a Rotation property that helps drives the orbit, animated by another KeyFrameAnimation.
  3. 青い円のオフセットを駆動する ExpressionAnimation。赤い円のオフセットと Rotation プロパティを参照して、完全な軌道の周回を維持します。An ExpressionAnimation that drives the Offset of the blue ball referencing the Red Ball Offset and the Rotation property to maintain a perfect orbit.

3. で定義されている ExpressionAnimation に注目します。We’ll be focusing on the ExpressionAnimation defined in #3. また、ExpressionBuilder クラスも使用した、この Expression の作成も行います。We will also be using the ExpressionBuilder classes to construct this Expression. String を使用してこのエクスペリエンスを作成するためのコードのコピーが、最後に記載されています。A copy of the code used to build this experience via Strings is listed at the end.

この式では、PropertySet から参照する必要がある 2 つのプロパティが使用されています。1 つは中心点のオフセット、もう 1 つは回転です。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");

次に、実際の起動の周回を構成する Vector3 コンポーネントを定義する必要があります。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);

注意

EF ExpressionBuilder.ExpressionFunctions を定義する短縮形"using"表記です。EF is a shorthand “using” notation to define ExpressionBuilder.ExpressionFunctions.

最後に、これらのコンポーネントを一緒に組み合わせ、赤い円の位置を参照して、数学的な関係を定義します。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);

これと同じ Expression を使用するが、2 つの他の Visual (軌道を回る円の 2 つのセット) を使うと仮定した場合は、どうすればよいでしょうか。In a hypothetical situation, what if you wanted to use this same Expression but with two other Visuals, meaning 2 sets of orbiting circles. CompositionAnimation を使用すると、アニメーションを再利用し、複数の CompositionObject をターゲットにすることができます。With CompositionAnimations, you can re-use the animation and target multiple CompositionObjects. この Expression を使用して軌道周回のケースを追加する場合、変更する必要があるのは、Visual への参照だけです。The only thing you need to change when you use this Expression for the additional orbit case is the reference to the Visual. これをテンプレート化と呼びます。We call this templating.

この場合、前に作成した Expression を変更します。In this case, you modify the Expression you built earlier. CompositionObject への参照を "取得" するのではなく、名前を指定して参照を作成し、異なる値を割り当てます。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);

パブリック API 経由で String を使用して Expression を定義する場合のコードを次に示します。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);