Анимация графических объектов в Dephi на примерах

by Mar 2, 2016

Давайте познакомимся на примерах со средствами анимации графических объектов, которые есть в Delphi, и рассмотрим несколько вариантов, как в Delphi быстро реализовать практически любые нетривиальные потребности заказчика.

Уверен, что все уже заметили, насколько часто в последние годы мы сталкиваемся с таким явлением, как "Тыж<…>" – Тыжврач, Тыжучитель, Тыжархитектор и много еще таких же "Тыж.." – Generics, которые должны знать и уметь все, что по мнению друзей и знакомых входит в область их деятельности.

Недавно мне повезло узнать, что я – "ТЫЖПРОГРАММИСТ!" и даже с восклицательным знаком!. Этот знак, в конечном счете, вынудил меня срочно заняться тем, чем никогда раньше не приходилось – анимацией в пользовательском интерфейсе.

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

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

Так или иначе, давайте откроем Delphi и создадим приложение, которое будет передвигать окружность по внутренней поверхности другой окружности, вращаясь по мере движения – как основу для "часиков".

Как всегда в информатике, все можно сделать тремя-пятью и более способами. Для начала, покажу способ, предложенный Всеволодом Леоновым – потерянной нами Delphi-звездой, непререкаемым для меня авторитетом в области 2D и 3D графики. С его разрешения, покажем этот пример, который весьма прост, но прекрасно показывает всю возможную мощь анимации в FireMonkey. 

VL_clock

На форму помещены два круга: большой и маленький, вложенный в большой. Для наглядности внутрь малого круга помещен еще меньший квадрат. Параметрически движение по окружности можно задать при помощи пары sin / cos функций. Поэтому для горизонтали и вертикали используются по 2 анимации типа TFloatAnimation, у которых установлена синусоидальная интерполяция.

Все волшебство кроется в настройках этих компонент.

Circle1: TCircle

    Size.Width = 400

    Size.Height = 400

Circle2: TCircle

      Size.Width = 80

      Size.Height = 80

faRotation: TFloatAnimation

        Duration = 5.

        Loop = True

        RotationAngle  StartValue = 0.

        StopValue = 360.

faX1: TFloatAnimation

        AutoReverse = True

        Enabled = True

        Duration = 4.

        Interpolation = Sinusoidal

        Inverse = True

        OnFinish = faX1Finish

        PropertyName = 'Position.X'

        StartValue = 320.

        StopValue = 160.

faX2: TFloatAnimation

        AutoReverse = True

        Duration = 4.

        Interpolation = Sinusoidal

        Inverse = True

        OnFinish = faX2Finish

        PropertyName = 'Position.X'

        StartValue = 0.

        StopValue = 160.

faY0: TFloatAnimation

        Enabled = True

        Duration = 4.

        Interpolation = Sinusoidal

        OnFinish = faY0Finish

        PropertyName = 'Position.Y'

        StartValue = 320.

        StopValue = 160.

faY1: TFloatAnimation

        AutoReverse = True

        Duration = 4.

        Interpolation = Sinusoidal

        Inverse = True

        OnFinish = faY1Finish

        PropertyName = 'Position.Y'

        StartValue = 0.

        StopValue = 160.

faY2: TFloatAnimation

        AutoReverse = True

        Duration = 4.

        Interpolation = Sinusoidal

        Inverse = True

        PropertyName = 'Position.Y'

        StartValue = 320.

        StopValue = 160.

 

 Рассмотрим горизонталь:

  • faX1 – отвечает за движение из центра вправо и обратно<
  • faX2 – отвечает за движение из центра влево и обратно

Если использовать такую пару, то можно подобрать правильную комбинацию StartValue/StopValue + Inverse (true/false). 

  • у каждой анимации выключен Loop (зацикливание, бесконечное повторение);
  • у каждой анимации включён AutoReverse (чтобы сделать автоматически «туда-и-обратно»)
  • по окончании работы faX1 на событие «конец» включается faX2
  • по окончании работы faX2 на событие «конец» включается faX1

Чтобы синхронизировать эти анимации выполняется простая процедура: попеременно включая-выключая друг друга эти анимации двигают объект:  «из центра вправо и обратно» и «из центра влево и обратно»

Чуть сложнее с вертикальной анимацией. Тут двумя объектам TFloatAnimation обойтись нельзя, так как начальное положение объекта не в центре, а в нижней точке. Поэтому faY0 – работает с начала и один раз, переводя объект в «центральное положение». За это время объект по горизонтали уже ушёл в крайнюю правую точку. Потом уже пара faY1 и faY2 работает также, как и faX1 и faX2.

Управление по горизонтали и вертикали должны работать так, что когда по вертикали – крайняя точка, по горизонтали – центральная. И – наоборот.

Обработчики события OnFinish очень просты

procedure TForm1.faX1Finish(Sender: TObject);

begin

  faX2.Start;

end;

procedure TForm1.faX2Finish(Sender: TObject);

begin

  faX1.Start;

end;

procedure TForm1.faY0Finish(Sender: TObject);

begin

  faY1.Start;

end;

procedure TForm1.faY1Finish(Sender: TObject);

begin

  faY2.Start;

end;

procedure TForm1.faY2Finish(Sender: TObject);

begin

  faY1.Start;

end;

 

Но есть и другой способ создания такого приложения. Об этом я расскажу в следующем посте

Часть 2. Анимация графических объектов в Dephi на примерах