Продолжаем разговор про реализацию анимации окружности, движущейся по внутренней поверхности большей окружности, средствами Delphi. В предыдущем посте я рассказал о способе с применением нескольких компонент TFloatAnimation, который предоставил мой коллега В. Леонов. Сейчас - о своем способе реализации этой задачи. 

На картинке ниже видно, как выглядит проект для 5" Android - телефона. Как и раньше, на форме - большой и малый круги. Для более простого масштабирования под разные  устройства вся эта конструкция содержится в ScaledLayout1, растянутому на всю форму.

Для наглядности большой круг Circle4 вписан в квадрат Rectangle1. Малый круг, точнее окружность Circle3, выделена голубым цветом и более толстой обводкой. Для наглядности демонстрации вращения в эту окружность вписан меньший квадрат Rectangle2, и на верхний край линии окружности помещен красный указатель Arc2.  На TrackBar1 и TrackBar2, также как на FloatAnimation4, FloatAnimation5, пока не обращайте внимания - они пригодятся в следующем проекте. 

Обратите внимание на вложенность объектов в окне Structure. Чтобы зафиксировать взаимное расположение объектов, у Arc2 и Rectangle2 значение свойства Locked установлено в True.

Предназначенный для следующего проекта  ArcDial1 работает и в этом примере - вращение его во время выполнения мышью или касанием вращает малую окружность вокруг ее центра. Еще этот элемент используется для демонстрации влияния анимации на группу объектов. Для управления режимами демонстрации предназначены два чек-бокса cbBinded, cbRotate, на событие OnChange которых работают два обработчика, управляющих работой анимации.

Начать анимацию можно нажатием кнопки Button2 ("Начать PathAnimation"), повторное нажатие которой выполнение анимации останавливает. Никаких особых установок свойств перечисленных компонент нет.

  

Все волшебство заключено в компоненте PathAnimation1 типа TPathAnimation, значения свойств которого устанавливаются в OnFormCreate

procedure TForm1.FormCreate(Sender: TObject);
begin
  PathAnimation1.Path.Clear;
  PathAnimation1.Path.MoveTo(PointF(0, 0));
  MyRect := TRectF.Create(0, 0, 300, 300);
  PathAnimation1.Path.AddEllipse(MyRect);
  PathAnimation1.Path.ClosePath;
  PathAnimation1.Loop := True;
  PathAnimation1.Rotate := cbRotate.IsChecked;
  PathAnimation1.Duration := 8;
end;

TPathAnimation выполняет движение визуального компонента по траектории, задаваемой набором координат точек в свойстве Path. Для нашей задачи нужна круговая траектория, которую я получаю с помощью добавления в Path эллипса, задаваемого с помощью квадратной области MyRect. Делаем PathAnimation1.Path замкнутым, длительность движения по траектории задаем равной 8 с, анимацию - циклически повторяющейся с PathAnimation1.Loop := True.

Старт анимации происходит по нажатию кнопки Button2, где срабатывает следующий код:

procedure TForm1.Button2Click(Sender: TObject);
begin
  Circle3.Position.X := 30;
  Circle3.Position.Y := 150;
  PathAnimation1.Enabled := not PathAnimation1.Enabled;
if PathAnimation1.Enabled then
  Button2.Text := 'PathAnimation Стоп'
else
  Button2.Text := 'Начать PathAnimation'
end;

 

Собственно за запуск анимации отвечает строка 

  PathAnimation1.Enabled := not PathAnimation1.Enabled;

Вот и все! Дополнительно я включил возможность познакомиться с разными режимами анимации.

Переключатель cbBinded помещает элемент "ручка вращения" ArcDial1 в центр движущейся окружности, если он включен, и наоборот, убирает элемент, если выключен. Соответствующий код очень прост и, надеюсь, ясен всем:

procedure TForm1.cbBindedChange(Sender: TObject);
begin
  if cbBinded.IsChecked then
  begin
    ArcDial1.Parent := Circle3;
    ArcDial1.Align := TAlignLayout.Center;
  end
  else
  begin
    ArcDial1.Parent := Form1;
    ArcDial1.Align := TAlignLayout.None;
    ArcDial1.Position.X := 70;
    ArcDial1.Position.Y := 188;
  end;
end;

Переключатель cbRotate, как следует из его имени, служит для "разрешения" визуальному элементу вращаться при движении по указанной  в PathAnimation1 траектории:

procedure TForm1.cbRotateChange(Sender: TObject);
begin
  PathAnimation1.Rotate := cbRotate.IsChecked;
end;

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

 

 

 

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder. Design. Code. Compile. Deploy.

Start Free Trial   Free Delphi Community Edition   Free C++Builder Community Edition   Upgrade Today