Поделиться через


Базовая анимация

Классы анимации мультиплатформенного пользовательского интерфейса приложений .NET (.NET MAUI) предназначены для различных свойств визуальных элементов, при этом обычная анимация постепенно изменяет свойство с одного значения на другое в течение определенного периода времени.

Базовые анимации можно создать с помощью методов расширения, предоставляемых классом ViewExtensions , который работает с VisualElement объектами:

По умолчанию каждая анимация займет 250 миллисекундах. Однако при создании анимации можно указать длительность для каждой анимации.

Примечание.

Класс ViewExtensions также предоставляет LayoutTo метод расширения. Однако этот метод предназначен для использования макетами для анимации переходов между состояниями макета, содержащими изменения размера и положения.

Методы расширения анимации в ViewExtensions классе являются асинхронными и возвращают Task<bool> объект. Возвращаемое значение — это false значение, если анимация завершается, и true если анимация отменена. Поэтому при сочетании операций анимации с await оператором становится возможным создать последовательные анимации с последующими методами анимации, выполняемыми после завершения предыдущего метода. Дополнительные сведения см. в разделе "Составные анимации".

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

В Android анимации учитывают параметры системной анимации:

  • Если анимации системы отключены (с помощью специальных возможностей или функций разработчика), новые анимации будут немедленно переходить к завершенном состоянию.
  • Если режим экономии питания устройства активируется во время выполнения анимации, анимации немедленно переходят к завершенном состоянию.
  • Если длительность анимации устройства равна нулю (отключена) во время выполнения анимации, а версия API — 33 или больше, анимация сразу перейдет к завершенном состоянию.

Однократные анимации

Каждый метод расширения в ViewExtensions классе реализует одну операцию анимации, которая постепенно изменяет свойство с одного значения на другое значение за период времени.

Rotation

Поворот выполняется с RotateTo помощью метода, который постепенно изменяет Rotation свойство элемента:

await image.RotateTo(360, 2000);
image.Rotation = 0;

В этом примере Image экземпляр поворачивается на 360 градусов в течение 2 секунд (2000 миллисекунд). Метод RotateTo получает текущее Rotation значение свойства элемента для начала анимации, а затем поворачивается от этого значения к первому аргументу (360). После завершения анимации свойство изображения Rotation сбрасывается до 0. Это гарантирует, что Rotation свойство не остается в 360 после завершения анимации, что позволит предотвратить дополнительные повороты.

Примечание.

RotateTo Помимо метода, существуют также RotateXTo и RotateYTo методы, которые анимируют RotationX и RotationY свойства соответственно.

Относительный поворот

Относительная смена выполняется с RelRotateTo помощью метода, который постепенно изменяет Rotation свойство элемента:

await image.RelRotateTo(360, 2000);

В этом примере Image экземпляр поворачивается на 360 градусов с начальной позиции более 2 секунд (2000 миллисекунд). Метод RelRotateTo получает текущее Rotation значение свойства элемента для начала анимации, а затем поворачивается от этого значения к значению плюс его первый аргумент (360). Это гарантирует, что каждая анимация всегда будет поворотом в 360 градусов с начальной позиции. Таким образом, если при выполнении анимации вызывается новая анимация, она начинается с текущей позиции и может заканчиваться на позиции, которая не является шагом 360 градусов.

Масштабирование

Масштабирование выполняется с ScaleTo помощью метода, который постепенно изменяет Scale свойство элемента:

await image.ScaleTo(2, 2000);

В этом примере Image экземпляр масштабируется до 2 секунд (2000 миллисекунд). Метод ScaleTo получает текущее Scale значение свойства элемента для начала анимации, а затем масштабируется от этого значения до первого аргумента. Это влияет на расширение размера изображения до дважды его размера.

Примечание.

ScaleTo Помимо метода, существуют также ScaleXTo и ScaleYTo методы, которые анимируют ScaleX и ScaleY свойства соответственно.

Относительное масштабирование

Относительная масштабирование выполняется с RelScaleTo помощью метода, который постепенно изменяет Scale свойство элемента:

await image.RelScaleTo(2, 2000);

В этом примере Image экземпляр масштабируется до 2 секунд (2000 миллисекунд). Метод RelScaleTo получает текущее Scale значение свойства элемента для начала анимации, а затем масштабируется с этого значения на значение плюс его первый аргумент. Это гарантирует, что каждая анимация всегда будет масштабированием 2 из начальной позиции.

Масштабирование и поворот с привязками

AnchorY И AnchorX свойства визуального элемента задают центр масштабирования или поворота для Rotation и Scale свойств. Поэтому их значения также влияют на RotateTo методы и ScaleTo методы.

Image Учитывая, что он был размещен в центре макета, следующий пример кода демонстрирует поворот изображения вокруг центра макета, задав его AnchorY свойство:

double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);

Для поворота Image экземпляра вокруг центра макета AnchorX AnchorY необходимо задать значения, которые имеют значение относительно ширины и высоты Image. В этом примере центр определяется в центре Image макета, поэтому значение по умолчанию AnchorX 0,5 не требует изменения. AnchorY Однако свойство переопределено, чтобы быть значением из верхней части Image до центра макета. Это гарантирует, что Image делает полную смену 360 градусов вокруг центра макета.

Перевод текста

Преобразование выполняется с TranslateTo помощью метода, который постепенно изменяет TranslationX и TranslationY свойства элемента:

await image.TranslateTo(-100, -100, 1000);

В этом примере Image экземпляр преобразуется горизонтально и вертикально более 1 секунды (1000 миллисекунд). Метод TranslateTo одновременно преобразует изображение 100 независимых от устройств единиц слева и 100 независимых от устройств единиц вверх. Это связано с тем, что первый и второй аргументы являются отрицательными числами. Предоставление положительных чисел приведет к переводу изображения вправо и вниз.

Важно!

Если элемент изначально выложен с экрана, а затем переведен на экран, после перевода входного макета элемента остается вне экрана, и пользователь не может взаимодействовать с ним. Поэтому рекомендуется, чтобы представление должно быть изложено в окончательной позиции, а затем все необходимые переводы.

Исчезание

Увядание выполняется с FadeTo помощью метода, который постепенно изменяет Opacity свойство элемента:

image.Opacity = 0;
await image.FadeTo(1, 4000);

В этом примере Image экземпляр исчезает в течение 4 секунд (4000 миллисекунд). Метод FadeTo получает текущее Opacity значение свойства элемента для начала анимации, а затем исчезает из этого значения до первого аргумента.

Составные анимации

Составная анимация — это последовательное сочетание анимаций и может быть создано с await помощью оператора:

await image.TranslateTo(-100, 0, 1000);    // Move image left
await image.TranslateTo(-100, -100, 1000); // Move image diagonally up and left
await image.TranslateTo(100, 100, 2000);   // Move image diagonally down and right
await image.TranslateTo(0, 100, 1000);     // Move image left
await image.TranslateTo(0, 0, 1000);       // Move image up

В этом примере Image экземпляр преобразуется более 6 секунд (6000 миллисекунд). Перевод Image пяти анимаций с await оператором, указывающим, что каждая анимация выполняется последовательно. Поэтому последующие методы анимации выполняются после завершения предыдущего метода.

Составные анимации

Составная анимация — это сочетание анимаций, в которых одновременно выполняются две или несколько анимаций. Составные анимации можно создать путем объединения ожидаемых и не ожидающих анимаций:

image.RotateTo(360, 4000);
await image.ScaleTo(2, 2000);
await image.ScaleTo(1, 2000);

В этом примере Image экземпляр масштабируется и одновременно поворачивается в течение 4 секунд (4000 миллисекунд). Масштабирование Image двух последовательных анимаций, происходящих одновременно с поворотом. Метод RotateTo выполняется без await оператора и возвращается немедленно с первой ScaleTo анимацией, а затем начинается. Оператор await первого ScaleTo метода задерживает второй ScaleTo метод до завершения первого ScaleTo метода. На этом этапе анимация RotateTo завершается наполовину, и Image она будет поворачиваться на 180 градусов. В течение последних 2 секунд (2000 миллисекунд), вторая ScaleTo анимация и анимация RotateTo оба завершены.

Параллельное выполнение нескольких анимаций

Методы Task.WhenAny и Task.WhenAll методы можно использовать для одновременного выполнения нескольких асинхронных методов и, следовательно, создавать составные анимации. Оба метода возвращают Task объект и принимают коллекцию методов, которые возвращают Task объект. Метод Task.WhenAny завершается, когда любой метод в коллекции завершает выполнение, как показано в следующем примере кода:

await Task.WhenAny<bool>
(
  image.RotateTo(360, 4000),
  image.ScaleTo(2, 2000)
);
await image.ScaleTo(1, 2000);

В этом примере Task.WhenAny метод содержит две задачи. Первая задача поворачивает экземпляр в течение 4 секунд (4000 миллисекунд), а вторая задача масштабирует Image изображение в течение 2 секунд (2000 миллисекунд). После завершения Task.WhenAny второй задачи вызов метода завершается. Однако, несмотря на то, что RotateTo метод по-прежнему запущен, второй ScaleTo метод может начаться.

Метод Task.WhenAll завершается, когда все методы в коллекции завершены, как показано в следующем примере кода:

// 10 minute animation
uint duration = 10 * 60 * 1000;
await Task.WhenAll
(
  image.RotateTo(307 * 360, duration),
  image.RotateXTo(251 * 360, duration),
  image.RotateYTo(199 * 360, duration)
);

В этом примере Task.WhenAll метод содержит три задачи, каждая из которых выполняется более 10 минут. Каждая Task из них составляет 360 градусов поворотов — 307 поворотов для , 251 поворотов для RotateToRotateXToи 199 поворотов для RotateYTo. Эти значения являются простыми числами, поэтому гарантируя, что повороты не синхронизированы и поэтому не приводят к повторяющимся шаблонам.

отмена анимации

Приложение может отменить одну или несколько анимаций с вызовом CancelAnimations метода расширения:

image.CancelAnimations();

В этом примере все анимации, выполняемые на экземпляре Image , немедленно отменяются.