# Анимации, состояния, переходы

Copyright&nbsp;©&nbsp;2016–2023 ООО&nbsp;«Открытая мобильная платформа».
Этот документ предоставляется в&nbsp;соответствии
с&nbsp;[Публичной лицензией Creative Commons с&nbsp;указанием авторства версии&nbsp;4.0 Международная](../../LICENSE.CC-BY-4.0.ru.md).

## Transform — преобразование элементов

Отрисованными объектами можно манипулировать различным образом.
Рассматривать будем три возможные операции: перемещение, масштабирование, вращение.
Применять их можно присвоением одного из трёх объектов свойству transform.
Для применения сразу нескольких операций присваивать необходимо массив объектов.

Виды трансформаций:

*	Перемещение задаётся объектом Translate.
	У объекта есть два свойства: x и y, которые используются для перемещения объекта вдоль
	осей x и y соответственно.
	Перемещение производится относительно уже заданных координат объекта.
*	Масштабирование задаётся с помощью объекта Scale.
	У объекта есть два свойства: xScale и yScale для масштабирования элемента относительно осей x и y.
	Значениями свойств являются множители, на которые необходимо увеличить ширину или высоту.
	Если задать масштабированию свойства origin.x или origin.y, то масштабирование будет
	осуществляться относительно заданной точки.
*	Для вращения элементов используется объект Rotation.
	По умолчанию вращение производится вокруг оси z.
	Угол вращения задаётся свойством angle.
	Для того, чтобы вращать элемент относительно других осей, необходимо изменять значения
	свойств axis.x, axis.y, axis.y.

## Timer — периодические сигналы

Элемент `Timer` генерирует периодические сигналы.

Таймер можно использовать для запуска действия один раз или несколько раз через заданный интервал.
Если nаймер запущен и одно из его свойств изменено, истекшее время будет сброшено.

*	interval : int — интервал между событиями в миллисекундах
*	repeat : bool — повторяются ли сигналы
*	running : bool — true для старта, false для остановка
*	triggeredOnStart : bool — сигнал сразу после старта
*	triggered() — сигнал завершения времени
*	restart() — сброс к началу
*	start() — запуск
*	stop() — остановка

## Пример трансформаций с таймером

Пример трансформации по таймеру: через заданные промежутки времени изменяется угол поворота.
Углом поворота управляет компонент Rotation.

## Анимации — изменения свойств

Анимации применяются к изменениям свойств.
Анимация определяет кривую интерполяции, когда для изменения значения свойства создаются
плавные переходы от одного значения к другому.
Анимация определяется серией целевых свойств для анимации, кривой ослабления для кривой
интерполяции и в большинстве случаев длительностью, которая определяет время изменения свойства.
Все анимации в Qt Quick контролируются одним и тем же таймером и поэтому синхронизируются.
Это улучшает производительность и визуальное качество анимации.

Основные методы и свойства анимаций:

*	loops : int — сколько раз проигрывать анимацию
*	paused : bool — на паузе ли анимация
*	running : bool — воспроизводится ли анимация
*	alwaysRunToEnd : bool — всегда завершать анимацию полностью, даже если был сигнал остановки
*	started() — сигнал начала анимации
*	stopped() — сигнал завершения анимации
*	complete() — завершить анимацию полностью
*	pause(), resume() — пауза, продолжение
*	restart() — сброс к началу
*	start(), stop() — начать, остановить

## Способы использования анимаций

Анимация может применяться несколькими способами:

*	анимация по свойствам выполняется автоматически после полной загрузки элемента;
*	поведение по свойствам выполняется автоматически при изменении значения свойства;
*	автономная анимация запускается, когда анимация явно запускается с использованием функции
	start() или свойству running устанавливается значение true.

## Анимации и переходы

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

*	Transition — анимируется переход между состояниями;
*	SequentialAnimation — последовательные анимации;
*	ParallelAnimation — параллельные анимации;
*	Behavior — анимация изменения свойств;
*	PauseAnimation — пауза в анимации;
*	SmoothedAnimation — сглаживание анимации перехода;
*	SpringAnimation — пружинная анимация.

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

*	PropertyAction — определяет немедленные изменения свойств во время анимации;
*	ScriptAction — определяет скрипты, которые будут выполняться во время анимации.

## Анимации на основе типов данных

На слайде представлен список компонентов, которые умеют анимировать изменение
свойств объекта заданных типов.

*	AnchorAnimation — изменения якорей;
*	ParentAnimation — изменение родителя;
*	PathAnimation — перемещать элемент вдоль пути;
*	ColorAnimation — изменение цвета;
*	NumberAnimation — изменения числовых свойств;
*	RotationAnimation — повороты;
*	Vector3dAnimation — изменения значений QVector3d;
*	PropertyAnimation — изменения любых свойств.

## Анимация изменения свойства

На слайде предствален пример анимации изменения свойства:

Анимация начинатеся по нажатию на экран.

В PropertyAnimation прописаны детали анимации:
она назначается прямоугольнику и меняет его цвет за 2 секунды.

## Пример анимации Behavior

Такую же анимацию можно задать альтернативным образом с помощью Behavior.

## Выполнение набора анимаций

Часто анимация бывает более сложной, чем просто анимация одного свойства.
Возможно, вы захотите запустить несколько анимаций одновременно или последовательно
или даже выполнить сценарий между двумя анимациями.
Для этого можно группировать анимации.
Группировка может выполняться двумя способами: параллельным или последовательным.
Вы можете использовать элемент SequentialAnimation или ParallelAnimation, которые действуют
как контейнеры анимации для других элементов анимации.

Все прямые дочерние анимации параллельной анимации будут запускаться параллельно при запуске.
Это позволяет одновременно анимировать разные свойства.
Следующая анимация запускает две числовые анимации параллельно.
Прямоугольник перемещается в (50,50), одновременно анимируя свои свойства x и y.

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

Последовательная анимация сначала запускает первую дочернюю анимацию, а после её окончания – следующую.

В следующем примере выполняется две анимации чисел в последовательности.
Прямоугольник анимируется в положение x в 50, затем в y в 50.

Анимации, определенные в рамках перехода, автоматически запускаются параллельно,
поэтому SequentialAnimation может использоваться для включения анимаций в переход,
если это предпочтительное поведение.

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

После того, как анимация была сгруппирована в SequentialAnimation или ParallelAnimation, она не может
быть индивидуально запущена и остановлена.
Последовательность SequentialAnimation или ParallelAnimation должна быть запущена и остановлена как группа.

## Состояния и управление свойствами

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

Механизм работы с состояниями в QML представляет из себя некое подобие графа, где в качестве вершин
выступают конкретные состояния, а ребра — это условия перехода между ними.
У всех объектов, основанных на Item, есть свойства states и state.
В свойстве states хранится список всех состояний, определенных для объекта.
Даже если не задавать ни одного состояния, в переменной states будет всегда содержаться одно начальное состояние,
которое содержит изначальный свойства объекта и имеет пустую строку в качестве названия.
Новые состояния могут быть определены добавлением объектов State в свойство states, что позволяет объекту
переключаться между различным наборами конфигураций.
Название текущего состояния объекта находится в свойстве state, а изменение текущего состояния может
производится присваиванием свойству state название другого состояние.

State — QML-компонент, назначение которого — описание состояний объекта и условий перехода между ними.
Он представляет собой набор изменений значений свойств относительно начальной конфигурации объекта.
У каждого объекта происходящего от Item имеется как минимум одно состояние — состояние по-умолчанию.
Каждое состояние внутри одного объекта имеет свое уникальное название, в случае начального состояния
в качестве название выступает пустая строка.
Обращение к объектам из State идет по их id.

State — конфигурации объектов и свойств:

*	name : string — название состояния;
*	extend : string — расширяемое состояние;
*	when : bool — когда состояние наступает;
*	changes : list<Change> — изменения для прихода в состояние.

Элемент PropertyChanges используется, чтобы задать новые значение свойств при изменении состояния.
Переходя в новое состояние, значения в соответствующем PropertyChanges будут применяться к объекту.
Таким образом, можно задать новое значение свойства или осуществить привязку к другому параметру.
Кроме того, это позволяет переопределить обработчики событий объекта.

PropertyChanges обладает некоторыми свойствами, определяющими, как будет происходить изменение
состояния в той или иной ситуации.
PropertyChanges не позволяет изменить какие-либо значение anchors, кроме margins,
так как за это отвечает другой элемент.

*	target : Object — объект для изменения свойств;
*	explicit : bool — задать свойства один раз вместо привязок;
*	restoreEntryValues : bool — восстановить предыдущие значения при выходе из состояния.

## Пример PropertyChanges

Пример показывает, как изменение состояния привязывается к нажатию на область.

Изменение конкретных свойств определяется при помощи PropertyChanges.

## Transition — анимации при смене состояний

Переход определяет анимацию, которая будет применяться при изменении состояния.

У каждого наследника Item имеется свойство transitions — список переходов между состояниями.

Свойства компонента Transition:

*	animations : list<Animation> —  выполняемые анимации;
*	from, to : string — изменения состояний, которые вызывают переход;
*	reversible : bool — обратный переход;
*	enabled : bool — выполнять ли переход.

## Пример Transitions

Пример задания анимации для переходов между состояниями.

У прямоугольника есть два состояния, только одно из них имеет явно заданное имя blue.

При описании переходов медлу состояниями достаточно указать одно состояние, исходное или целевое.
