Анонс 1.11.0.0 и Анимация 🚀
Продолжаем серию статей, посвященных новинкам релиза FGX Native 1.11.0.0. И в этой статье поговорим о самой главной и ожидаемой новинке - поддержка полноценных анимаций 🔥🔥🔥.
TfgAnimationManager - центр управления анимациями
Главным центром управления анимации любого компонента является менеджер анимаций, доступ к которому можно получить через свойство TfgControl.AnimationManager. Именно он отвечает за создание, добавление и удаление аниматоров.
Создание аниматора
Чтобы создать нужный аниматор нужно воспользоваться одним из следующих методов TfgAnimationManager:
function AddOpacityAnimation(const AStartOpacity, AFinishOpacity: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation;
function AddBoundsAnimation(const AStartBounds, AFinishBounds: TRectF; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation;
function AddScaleAnimation(const AStartScaleX, AFinishScaleX, AStartScaleY, AFinishScaleY: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation;
function AddRotationAnimation(const AStartAngle, ASweepAngle: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation;
function AddTranslationAnimation(const AStartPoint, AFinishPoint: TPointF; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation;
function AddGroupAnimation: TfgAnimationGroup;
Каждый метод создает соответствующий своему названию тип аниматора с указанными стартовыми и конечными значениями. Например, если вы хотите плавно показать кнопку в течении 1 секунды, достаточно выполнить следующий код.
uses
FGX.Animation;
var Animation := Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec});
Animation.Start;
Обратите внимание, что в данном случае, созданный аниматор "Animation" останется у компонента и не будет удален, пока вы не сделаете это сами или компонент не будет уничтожен. Если вы планируете часто использовать один и тот же вид анимации на конкретном компоненте, то предпочтительным способом будет являться именование анимации. Например:
uses
FGX.Animaton.Helpers;
// Создаем аниматор один раз
Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec})
.SetName('fade-in');
// Будущие запуски анимации
Button.AnimationManager['fade-in'].Start;
Если же вам достаточно выполнить анимацию всего лишь один раз, то имеет смысл пометить ее для автоматического удаления опцией TfgAnimationOption.ReleaseOnFinish:
uses
FGX.Animation.Types, FGX.Animation.Helpers;
Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec})
.AddOption(TfgAnimationOption.ReleaseAnimationOnFinish)
.Start;
Хелпер анимации
Для удобного создания аниматоров мы предлагаем вам готовый хелпер FGX.Animation.Helpers, который позволяет использовать цепочку вызовов методов аниматора и облегчить визуальное восприятие готового кода.
Без хелпера:
uses
FGX.Animation;
var
OpacityAnimation: TfgAnimation;
OpacityAnimation := Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity});
OpacityAnimation.Duration := 1000 {msec};
OpacityAnimation.AutoReverse := True;
OpacityAnimation.Delay := 500 {msec};
OpacityAnimation.Options := OpacityAnimation.Options + [TfgAnimationOption.ReleaseAnimationOnFinish];
OpacityAnimation.Start;
С хелпером:
uses
FGX.Animation.Types, FGX.Animation.Helpers;
Button.AnimationManager.AddOpacityAnimation(0 {start opacity})
.SetDuration(1000 {msec})
.SetDelay(500 {msec})
.SetAutoReverse
.SetReleaseAnimationOnFinish
.Start;
Чтобы воспользоваться хелперами, необходимо подключить модуль FGX.Animation.Helpers.
Обзор базовых аниматоров
Поддерживается 5 базовых типов анимаций:
- Opacity. Изменение прозрачности (TfgControl.Opacity).
- Bounds. Изменение положения и размера (TfgControl.Position + TfgControl.Size).
- Scale. Изменение масштаба отображения компонента.
- Rotation. Изменение угла поворота компонента.
- Translate. Выполнение смещения компонента относительно его текущей позиции (TfgControl.Position).
Анимация прозрачности (TfgAnimationManager.AddOpacityAnimation)
Чтобы выполнить анимацию прозрачности нужно создать аниматор через метод TfgAnimationManager.AddOpacityAnimation и указать стартовое и конечное значение свойства TfgControl.Opacity.
Image.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 2000 {msec})
.Start;
Анимация перемещения и изменения размера (TfgAnimationManager.AddBoundsAnimation)
Чтобы выполнить анимацию изменения размера и позиции нужно создать аниматор через метод TfgAnimationManager.AddBoundsAnimation и указать стартовый и конечный прямоугольник. Пример ниже демонстрирует интересный прием акцентирования внимания на компоненте через визуальное расширение и сжатие компонента.
var
StartRect: TRectF;
StopRect: TRectF;
begin
StopRect := imgPhoto.Bounds;
StartRect := imgPhoto.Bounds;
StartRect.Inflate(16, 16);
Image.AnimationManager.AddBoundsAnimation(StartRect, StopRect)
.Start;
Анимация изменения масштаба (TfgAnimationManager.AddScaleAnimation)
Чтобы выполнить анимацию изменения масштаба нужно создать аниматор через метод TfgAnimationManager.AddScaleAnimation и указать стартовые и конечные значения коэффициентов масштабирования по горизонтали и вертикали.
Image.AnimationManager.AddScaleAnimation(0.5, 1, 0.5, 1, 1000)
.Start;
Анимация поворота компонента (TfgAnimationManager.AddRotationAnimation)
Чтобы выполнить анимацию поворота компонента нужно создать аниматор через метод TfgAnimationManager.AddRotationAnimation и указать стартовое значение угла и на сколько градусов нужно совершить поворот (в градусах). При этом, если угол поворота положительный, то поворот осуществляется по часовой стрелки, а если отрицательный, то против часовой стрелки.
Image.AnimationManager.AddRotationAnimation(0 {start}, 360 {Sweep}, 1000)
.Start;
Анимация смещения (TfgAnimationManager.AddTranslationAnimation)
Чтобы выполнить анимацию смещения компонента нужно создать аниматор через метод TfgAnimationManager.AddTranslationAnimation и указать стартовое и конечное смещения значения позиции компонента.
Image.AnimationManager.AddTranslationAnimation(TPointF.Create(-16, 0), TPointF.Create(16, 0), 1000)
.Start;
TfgAnimation - основа анимации
После того, как мы посмотрели несколько примеров создания аниматоров вживую, пришло время рассмотреть их настройки детальнее.
Длительность анимации (TfgAnimation.Duration)
Общая длительность выполнения текущей анимации в миллисекундах в одну сторону (от стартового значения до конечного).
Задержка перед запуском (TfgAnimation.Delay)
Если вам необходимо выполнить анимацию с задержкой, то вы можете это сделать указав значение задержки в миллисекундах в свойстве TfgAnimation.Delay.
Количество повторений (TfgAnimation.RepeatCount)
Если вам необходимо повторить анимацию несколько раз или сделать ее бесконечной, то вы можете это сделать при помощи этого свойства, где
- RepeatCount = 0 - повторение анимации бесконечное число раз.
- RepeatCount > 0 - повторение анимации ровно "RepeatCount" раз.
Например при помощи этого свойства легко сделать анимацию тряски: повторим 4 раза движение компонента по горизонтальной оси.
Интерполяция (TfgAnimation.CurveKind)
Это свойство отвечает за формулу интерполяции значений анимируемых свойств. Пока поддерживается 4 самых распространенных типов интерполяции.
TfgAnimationCurveKind = (Linear, EaseIn, EaseOut, EaseInOut);
Краткое описание стратегии изменения анимируемого значения на протяжении всей длительности анимации в зависимости от типа интерполяции:
- Linear - равномерное изменение. Варианты типичного применения: короткие анимации, изменение цвета.
- EaseIn - медленное начало с постепенным нарастанием скорости к концу анимации. Варианты типичного применения: исчезновения объекта.
- EaseOut - быстрое начало с постепенным замедлением скорости к концу анимации. Варианты типичного применения: появления объекта.
- EaseInOut - медленное начало с нарастанием скорости посередине и постепенным замедлением скорости к концу анимации. Варианты типичного применения: перемещение объекта, изменение масштаба.
Порядок запуска (TfgAnimation.RunOrder)
Это свойство актуально только в контексте групповых аниматоров и позволяет указывать порядок запуска текущей анимации в группе. Подробнее это будет рассмотрено в разделе "Групповые анимации".
- TfgAnimationRunOrder.Immediately - запуск анимации в момент старта родительского группового аниматора, либо вместо с предыдущим одноуровневым аниматором.
- TfgAnimationRunOrder.AfterPrevious - запуск анимации после окончания предыдущей анимации в рамках группового аниматора.
Дополнительные настройки (TfgAnimation.Options)
- TfgAnimationOption.StartFromCurrent - Начинать анимацию с текущего значения свойства компонента, а не указанного стартового значения.
- TfgAnimationOption.AlwaysSetFinalValue - При остановке анимации, эта опция позволяет указать сразу конечное значение свойства компоненту, иначе конечное значение останется таким, какое оно было на момент остановки.
- TfgAnimationOption.AutoReverse - Нужно ли автоматически выполнить анимацию в обратном порядке после окончания прямой анимации. Актуально для RepeatCount > 0.
- TfgAnimationOption.ReleaseControlOnFinish - позволяет автоматически удалить компонент по окончании анимации.
- TfgAnimationOption.ReleaseAnimationOnFinish - позволяет автоматически удалить аниматор по окончании анимации.
Название (TfgAnimation.Name)
Вы можете присвоить уникальное название аниматору, чтобы в последствии обращаться к нему напрямую по его имени.
Например:
var
FadeAnimation: TfgAnimation;
FadeInAnimation := Button.AnimationManager['fade-in'];
Групповые анимации
Для создания сложных анимаций мы предлагаем использовать групповые аниматоры, задача которых сгруппировать несколько анимаций и задать правила их запуска. По умолчанию групповой аниматор запускает все вложенные анимации одновременно. Например, такой аниматор ниже позволяет реализовать анимацию модального открытия формы на Android:
var
AnimationGroup: TfgAnimationGroup;
AnimationGroup := LForm.AnimationManager.AddGroupAnimation
.Add(LForm.AnimationManager.CreateScaleAnimation(1.125, 1, 1.125, 1))
.Add(LForm.AnimationManager.CreateOpacityAnimation(0, 1));
Мы создаем два аниматора, объединенные в группу, один из которых масштабирует форму, а второй меняет ее прозрачность.
Групповой аниматор TfgAnimationGroup по сути так же является аниматором TfgAnimation. А это значит, что вы можете их вкладывать друг в друга добиваясь анимации любой сложности.
Пример ниже показывает последовательно выполнение анимаций: вначале смещение компонента, а затем поворот:
Image.AnimationManager.AddGroupAnimation
.Add(Image.AnimationManager.AddTranslationAnimation(TPointF.Create(-16, 0), TPointF.Create(16, 0), 1000))
.Add(Image.AnimationManager.AddRotationAnimation(0, 360, 1000)
.SetRunOrder(TfgAnimationRunOrder.AfterPrevious))
.Start;
Вы можете выделить создание подобной анимации в отдельный метод и затем применять к любому компоненту.
Шаблоны анимаций
Это приятный бонус для наших пользователей. Мы предлагаем базовый набор уже готовых анимаций, которые вы можете использовать в своих проектах всего лишь одной строчкой кода. Для того, чтобы воспользоваться шаблонами, нужно подключить модуль FGX.Animation.Templates.
Чтобы просто потрясти компонент, достаточно просто написать:
Image.Shake;
А если требуется настроить параметры на свой вкус и цвет, можно воспользоваться перегруженной версией:
Image.Shake(TfgShakeAnimationParams.Default
.SetDuration(2000)
.SetRepeatCount(10));
Видео ниже демонстрирует все текущие доступные для использования шаблоны:
Среди шаблонов так же доступны различные варианты появления и скрытия компонентов с переносами и без. Вы можете ознакомиться с текущим набором в демо проекте: "Анимация" -> "Шаблоны анимаций".
Ограничения
Несмотря на то, что анимации уже работают, у них есть ряд ограничений, часть из которых мы будем постепенно убирать в будущих версиях.
- Нельзя менять стартовые и конечные значения уже созданных анимаций. Это можно делать только путем удаление старого и создания нового аниматора.
- Изменение свойств анимации во время ее выполнения не приведет их к применению. Все свойства применяются в момент старта анимации.
- Изменение размера компонента-контейнера через анимацию не приводит к выравниванию дочерних компонентов. Если вам нужно выполнить выравнивание содержимого, то надо добавлять дополнительные аниматоры для перемещения и изменения размеров вложенных компонентов отдельно.
Устаревшее API
Из-за создания полноценной анимации и выделения старых хелперов анимации TfgAnimationHelper в шаблоны анимации FGX.Animation.Templates, мы помечаем существующие методы анимации FadeIn, FadeOut, как устаревшие. Через несколько релизов мы удалим эти методы из TfgAnimationHelper, чтобы вы пользовались более удобными средствами анимации.
На текущий момент методы анимации формы остаются как есть. В ближайших релизах эту анимацию мы встроим прямо в TfgForm, в результате чего анимация открытия/закрытия форм будет осуществляться автоматически и не будет требовать от вас лишних строчек кода.
Итог
Мы продолжим развивать и совершенствовать реализацию анимаций. Поэтому нам очень важно получить от вам обратную связь о том, что удобно, что нет и чего не хватает. Эта информация поможет нам сделать анимацию лучше и удобнее для всех.
- 18
- 2
10 Comments
Recommended Comments