Анимации в визуальном слое универсальных приложений Windows (UWP)

Когда происходит динамическое изменение вёрстки универсального  приложения Windows (UWP), часто происходит небольшая задержка перед тем, как приложение перестроит содержимое экрана, чтобы соответствовать новому размеру экрана или ориентации. API отвечающее за композицию позволяет создавать гладкую непрерывную анимацию между этими состояниями, так что изменения вёрстки не потревожат пользователя. В конце концов, изменения разметки являются основным фактом  жизненного цикла приложения. Но это не значит, что мы не можем справиться с этим корректно.

Анимации вёрстки — это конечно не что-то абсолютно новое. Платформа UWP всегда позволяла вам использовать XAML переходы. Эти анимации получили тенденцию к использованию, давайте просто скажем о некоторых ограничениях. При использовании неявной анимации в визуальном слое, тем не менее, вы имеете иметь доступ к анимации низкого уровня, которая работает со скоростью 60 кадров в секунду в отдельном процессе, и вы полностью свободны в создании компоновки анимации, которую вы хотите создать.

Сравнение неявной и явной анимации
Что же такое неявная анимация? Лучше всего это можно понять, противопоставляя её явной анимации. Явная анимация — это анимация, которую вы инициируете запуском в коде путем вызова метода такого как StartAnimation применимого к визуальному слою приложения.
Например, вот пример анимации вращения шестерёнок и код, используемый, чтобы они начали вращаться.

  1. _gearMotionScalarAnimation.Duration = TimeSpan.FromSeconds(secondsPerRotation);
  2. _gearVisuals.First().StartAnimation(«RotationAngleInDegrees», _gearMotionScalarAnimation

Неявные анимации с другой стороны сконфигурированы, а потом просто срабатывает триггер настроенный на изменение свойств. Неявная анимация обладает таким качеством как «зарустил и забыл». Все, что вам нужно сделать — это подключить их, и они будут просто продолжать работать для вас, будут воссоздаваться с нуля и затем очищаться в исходное состояние каждый раз, когда триггер срабатывает.
Вот как создать и настроить неявную анимацию в четыре простых шага:
1) Создать коллекцию для анимации
2) Создать анимацию или группу анимаций
3) Связать значение анимации с ключом запуска в коллекции
4) Добавить вашу коллекцию в свойство ImplicitAnimations вашего визуального слоя
Нижеследующий код используется для создания анимации из изображений фруктов, которую вы уже видели в анимированном GIF в верхней части этого поста:

  1. // Create an implicit animation collection (just one member in this case)
  2. var implicitAnimationCollection = _compositor.CreateImplicitAnimationCollection();
  3. // Create the animation
  4. var offsetKeyFrameAnimation = _compositor.CreateVector3KeyFrameAnimation();
  5. offsetKeyFrameAnimation.Target = «Offset»;
  6. // Final Value signifies the target value to which the visual will animate
  7. // in this case it will be defined by new offset
  8. offsetKeyFrameAnimation.InsertExpressionKeyFrame(1.0f, «this.FinalValue»);
  9. offsetKeyFrameAnimation.Duration = TimeSpan.FromSeconds(3);
  10. // Associate the animation to the trigger
  11. implicitAnimationCollection[«Offset»] = offsetKeyFrameAnimation;
  12. // Finally, add the implicit animation to individual Visuals
  13. foreach (var child in _root.Children)
  14. {
  15.     child.ImplicitAnimations = implicitAnimationCollection;
  16. }

Есть две вещи, которые стоит отметить в этом коде:
— Во-первых, используется только один триггер свойства — Offset, поэтому ImplicitAnimationCollection имеет только один элемент.
— Во-вторых, анимация использует свойство Offset в качестве триггера, но также использует свойство Offset для самой анимации. На самом деле это довольно распространено, так как вы обычно хотите анимировать то же свойство, которое устанавливает переход – например, если происходит изменение масштаба, или поворот элемента, или нужно создать анимацию перехода между начальным и конечным масштабом размера, или начальным и конечным положениям вращения.
Для дополнительного визуального колорита вы могли бы также решить, чтобы изменения триггера визуального состояния Offset  вызывало более одной анимации — например, анимацию изменения позиции, а также пульсацию. Перейдите в GitHub в репозиторий Windows UI Dev Labs, чтобы получить полный исходный код примеров, использующих неявную анимацию.

Использование неявных анимаций для анимации макета/вёрстки
Для того чтобы применить неявные анимации для вашего макета XAML, единственный дополнительный шаг, который вам нужно сделать сверх того, что было раскрыто в предыдущем разделе — это захватить визуальное состояние для любых UiElement, которые вы собираетесь анимировать.

Демонстрация анимации макета из галереи примеров Windows UI Dev Labs на GitHub в базовом контроле GridView с несколькими изображениями в своей коллекции объектов Items.

  1. <GridView x:Name=«gridView» ContainerContentChanging=«gridView_ContainerContentChanging»>
  2.     <GridView.Items>
  3.         <Image Source=«1.jpg» Width=«235» Height=«200» Stretch=«UniformToFill»/>
  4.         <Image Source=«2.jpg» Stretch=«UniformToFill»/>
  5.         <Image Source=«3.jpg» Stretch=«UniformToFill»/>
  6.         <Image Source=«4.jpg» Stretch=«UniformToFill»/>
  7.         . . .
  8.     </GridView.Items>
  9. </GridView>

Всякий раз, когда страница XAML измененяет размеры, изображения внутри GridView автоматически смещаются вокруг расположенной под ним основы, изменяя свойство Offset каждого из визуальных элементов, поскольку он перемещается из одной позиции в другую. Вот как создать и настроить неявную анимацию и добавить её к элементам XAML в пять простых шагов:
1) Создать коллекцию неявной анимации
2) Создать анимацию
3) Связать значение параметра анимации с ключом запуска в коллекции
4) В обработчике событий ContainerContentChanging используйте метод взаимодействия GetElementVisual, чтобы отделить поддержку визуального состояния от UIElement.
5) Добавьте коллекцию к свойству ImplicitAnimations, которое поддерживает визуальное состояние.
Все три первые шага могут быть сделаны в конструкторе страницы.

  1. _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
  2. // Create ImplicitAnimations Collection. 
  3. _elementImplicitAnimation = _compositor.CreateImplicitAnimationCollection();
  4. // Define trigger and animation that should play when the trigger is triggered. 
  5. _elementImplicitAnimation[«Offset»] = createOffsetAnimation();

В демонстрации анимации макета, заключительные два этапа реализованы в обработчике событий ContainerContentChanging для GridView.

  1. private void gridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
  2. {
  3.     var photo = args.ItemContainer;
  4.     var elementVisual = ElementCompositionPreview.GetElementVisual(photo);
  5.     elementVisual.ImplicitAnimations = _elementImplicitAnimation;
  6. }

Это действительно так просто добавить быстрые, плавные и красивые анимации в визуальный слой макета страницы XAML.

Связанные анимации
Для анимационных переходов при навигации между страницами, визуальный слой обеспечивает другой механизм, известный как связанные анимации, чтобы помочь вам сделать ваш UI более привлекательным. Связанные анимации помогают пользователю ориентироваться что происходит, когда он выполняет общие задачи, такие как контекстное переключение от списка элементов к странице с детальной информацией.


Вы можете скачать полный исходный код примера для этих связанных анимаций на GitHub.

В завершение
Мощь визуальных возможностей для разработчиков через API композиции всегда были частью структуры работы с UI. Они просто не были доступны вам до сих пор. Представьте, что UI — это ядерный реактор, который вручили вам и вы можете поиграть с ним. С этой удивительной силой также приходит и ответственность за создание интересного пользовательского интерфейса и красивого взаимодействия. Идите вперед и удивляйте!
Чтобы узнать больше о темах, затронутых в этой публикации, рекомендуется погрузиться в следующие статьи и видео:
Неявные анимации
Композиция и неявные анимации
Понимание того, что можно сделать с помощью движка анимации Windows UI Animation Engine
Перемещения и эффекты: глубокое погружение
Связанные анимации
Обзор анимаций

Попробуйте свои навыки анимации — скачайте Visual Studio и начните разрабатывать!

Перевод оригинальной статьи Animations with the Visual Layer
Автор: Michael Crump
Перевод: Сергей Урусов

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *