Анимации на основе связей
В этой статье приводится краткий обзор создания анимаций на основе отношений с использованием составных анимаций ExpressionAnimations.
Динамические взаимодействия на основе отношений
При создании в приложении взаимодействий с движением это движение не всегда основано на времени — иногда движение зависит от свойства другого объекта. KeyFrameAnimations не позволяют легко и удобно представить такие типы взаимодействия с движением. Движение в таких сценариях не должно быть дискретным и определенным заранее. Напротив, движение может динамически адаптироваться с учетом отношений с другими свойствами объекта. Например, можно анимировать прозрачность объекта в зависимости от его горизонтального положения. Другие примеры включают такие взаимодействия с движением, как закрепленные заголовки или параллакс.
Эти типы движения позволяют создать пользовательский интерфейс, который выглядит более связно, а не разрозненно. У пользователя складывается впечатление, что в пользовательском интерфейсе происходит динамическое взаимодействие.
Использование ExpressionAnimations
Чтобы создать взаимодействия типа "движение" на основе отношений, следует использовать тип ExpressionAnimation. ExpressionAnimations (или кратко Expressions) — это новый тип анимации, который позволяет выражать математическую связь — связь, которую система использует для вычисления значения свойства анимации в каждом кадре. Другими словами, Expressions — это просто математическое выражение, которое определяет желаемое значение анимируемого свойства на кадр. Expressions — это универсальный компонент, который можно использовать в разнообразных сценариях, включая следующие:
- Относительный размер, анимации смещения.
- Закрепленные заголовки, параллакс с ScrollViewer. (См. Расширение возможностей существующих взаимодействий ScrollViewer.)
- Точки прикрепления с модификаторами InertiaModifiers и модулем InteractionTracker. (См. Создание точек прикрепления с модификаторами инерции.)
При работе с ExpressionAnimations существует несколько вещей, о которых требуется упомянуть заранее:
- Бесконечность: в отличие от родственного типа KeyFrameAnimation, у Expressions нет определенного срока действия. Поскольку Expressions — это математические отношения, это анимации, которые выполняются бесконечно. При желании эти анимации можно остановить.
- Выполняется, но не всегда оценивает: производительность — это всегда важный момент в работе с непрерывно выполняющимися анимациями. Однако не следует беспокоиться, систем достаточна умна, чтобы Expression выполняло переоценку, только если какой-либо ввод или параметр изменится.
- Разрешение в правильный тип объекта: поскольку Expressions — это математические отношения, важно убедиться, что выражение, определяющее Expression, разрешается в тот же тип свойства, на которое нацелена анимация. Например, при анимировании смещения Expression должно разрешаться в тип Vector3.
Компоненты Expression
При создании математического отношения Expression используется несколько базовых компонентов:
- Параметры: значения, представляющие значения-константы или ссылки на другие составные объекты.
- Математические операторы: стандартные математические операторы, такие как плюс (+), минус (-), умножить (*), разделить(/), которые объединяют параметры в выражение. Также включены условные операторы, такие как больше(>), equal(==), тернарный оператор (условие ? ifTrue : ifFalse) и т. д.
- Математические функции: математические функции/ярлыки на основе System.Numerics. Полный список поддерживаемых функций см. в разделе ExpressionAnimation.
Expressions также поддерживают набор ключевых слов — специальных фраз, имеющих определенное значение только в масштабах системы ExpressionAnimation. Они перечислены (вместе с полным списком математических функций) в документации ExpressionAnimation.
Создание выражений Expressions с помощью ExpressionBuilder
Существует два варианта создания выражений в приложении UWP:
- Создайте формулу в виде строки с помощью официального общедоступного API.
- Создайте уравнение в типобезопасной объектной модели с помощью средства ExpressionBuilder, входящего в состав набора средств сообщества Windows.
В контексте этого документа выражения Expressions определяются с использованием ExpressionBuilder.
Параметры
Параметры — это основа выражения Expression. Существует два типа параметров:
- Константы: эти параметры представляют типизированные переменные System.Numeric. Эти параметры получают значения, назначенные однократно при запуске анимации.
- Ссылки: эти параметры представляют ссылки на объекты CompositionObjects, их значения непрерывно обновляются после начала анимации.
Как правило, ссылки — это основной аспект, определяющий способ динамического изменения вывода Expression. Вывод Expression меняется в результате изменения этих ссылок. Если создать Expression со строками Strings или использовать их в шаблонном сценарии (используя Expression для работы с несколькими объектами CompositionObjects), потребуется назвать используемые параметры и задать их значения. См. дополнительные сведения в разделе "Пример".
Работа с KeyFrameAnimations
Expressions также могут использоваться с KeyFrameAnimations. В этих примерах Expression следует использовать для определения значения KeyFrame в определенной временной точке. Такие типы KeyFrames называются ExpressionKeyFrames.
KeyFrameAnimation.InsertExpressionKeyFrame(Single, String)
KeyFrameAnimation.InsertExpressionKeyFrame(Single, ExpressionNode)
Однако в отличие от ExpressionAnimations, ExpressionKeyFrames оцениваются только после запуска KeyFrameAnimation. Помните, что вы передаете ExpressionAnimation не в качестве значения KeyFrame, а как строку (или ExpressionNode, если используется ExpressionBuilder).
Пример
А сейчас рассмотрим пример использования Expressions, в частности пример PropertySet из коллекции примеров пользовательского интерфейса Windows. Рассмотрим Expression, управляющее поведением перемещения по орбите синего шара.
Все взаимодействие обеспечивается тремя компонентами:
- KeyFrameAnimation, анимирующая смещение красного шара по оси Y.
- PropertySet со свойством Rotation, которое обеспечивает движение орбиты, анимируемое другой анимацией KeyFrameAnimation.
- ExpressionAnimation, определяющая смещение синего шара в зависимости от смещения красного шара и свойство Rotation, сохраняющее идеальную орбиту.
Рассмотрим анимацию ExpressionAnimation, определенную в пункте 3. Кроме того, для создания этого выражения Expression будут использоваться классы ExpressionBuilder. Копия кода, используемого для создания этого взаимодействия через строки Strings, приводится в конце.
В этом выражении существует два свойства, на которые необходимо сослаться из PropertySet; одно — это смещение относительно центральной точки; другое — вращение.
var propSetCenterPoint =
_propertySet.GetReference().GetVector3Property("CenterPointOffset");
// This rotation value will animate via KFA from 0 -> 360 degrees
var propSetRotation = _propertySet.GetReference().GetScalarProperty("Rotation");
Затем необходимо определить компонент Vector3, обеспечивающий фактическое перемещение по орбите.
var orbitRotation = EF.Vector3(
EF.Cos(EF.ToRadians(propSetRotation)) * 150,
EF.Sin(EF.ToRadians(propSetRotation)) * 75, 0);
Примечание
EF
— это сокращенная нотация "using" для определения ExpressionFunctions.
using EF = Microsoft.Toolkit.Uwp.UI.Animations.Expressions.ExpressionFunctions;
Наконец, необходимо объединить эти компоненты и сослаться на положение красного шара, чтобы определить математическое отношение.
var orbitExpression = redSprite.GetReference().Offset + propSetCenterPoint + orbitRotation;
blueSprite.StartAnimation("Offset", orbitExpression);
Гипотетическая ситуация: что если бы нужно было использовать то же выражение Expression, но с двумя другими визуальными элементами Visuals, то есть если бы перемещающихся по орбите шаров было 2. Благодаря CompositionAnimations можно повторно использовать анимацию и делать целевыми несколько объектов CompositionObjects. Единственное, что нужно изменить, при использовании этого выражения Expression для работы с дополнительной орбитой, это ссылка на визуальный элемент Visual. Это называется "шаблоном".
В этом случае меняется выражение Expression, созданное ранее. Вместо того чтобы "получать" ссылку на CompositionObject, вы создаете ссылку с именем, а затем назначаете ей разные значения:
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);
вот код для сценария, когда Expression определяется с использованием строк Strings через общедоступный 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);
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по