FMXAttachTAnimation (C++)
Contents
Description
This example demonstrates how the AnimationType and Interpolation properties affect the rate at which the value of a property changes under their control. This is illustrated by controlling the X and Y of a TRectangle with TFloatAnimation instances.
The Interpolation properties on the TFloatAnimation objects are set to Linear
, making the change of X and Y constant over time. The Interpolation and AnimationType properties of the TFloatAnimation instance can be set in the Object Inspector to any TInterpolationType and any TAnimationType.
Drawing of the path is done using the DrawLine method of the form's Canvas. Points are collected and drawn using a TPointF array in the animation's OnProcess event handler and then redrawn in the form's OnPaint event handler.
The TFloatAnimation instances have to be created as children of the TRectangle. Many of the TFloatAnimation properties can be set at design time.
To replicate this example, create a Multi-Device Application - C++ and add the following components to the form:
- A TRectangle--the animated object
- Two TButton objects
- Two TComboBox objects
- Two TFloatAnimation objects
Rename the buttons to MoveRect and ReturnRect. Using the Object Inspector, add event handlers for the Form1.OnCreate, MoveRect.OnClick, ReturnRect.OnClick, FloatAnimation1.OnProcess, and Form1.OnPaint events. Fill in with the sample code below.
The form should look like the following image.
After clicking the MoveRect button, the rectangle moves according to the selected options, drawing a line from its upper-left corner.
A linear animation:
An elastic animation, with the rectangle moved:
Code
float saveX, saveY;
TPointF* oldPos = new TPointF;
TPointF posArray[3000];
int next;
// ---------------------------------------------------------------------------
void __fastcall TForm2::FloatAnimation1Process(TObject *Sender) {
int i;
TPointF* newPos;
newPos = new TPointF(Rectangle1->Position->X, Rectangle1->Position->Y);
if ((oldPos->X != newPos->X) || (oldPos->Y != newPos->Y)) {
posArray[++next] = (*newPos);
oldPos = newPos;
Invalidate();
}
}
// ---------------------------------------------------------------------------
void __fastcall TForm2::FormCreate(TObject *Sender) {
int i;
String s;
// Populate the ComboBox items with possible values for Interpolation
for (i = TInterpolationType::Linear;
i <= TInterpolationType::Bounce; i++) {
s = GetEnumName(__delphirtti(TInterpolationType), i);
ComboBox1->ListBox->Items->Add(s);
}
ComboBox1->ItemIndex = 0;
// Populate the ComboBox items with possible values for AnimationType
for (i = TAnimationType::atIn; i <= TAnimationType::InOut; i++) {
s = GetEnumName(__delphirtti(TAnimationType), i);
ComboBox2->ListBox->Items->Add(s);
}
ComboBox2->ItemIndex = 0;
saveX = Rectangle1->Position->X;
saveY = Rectangle1->Position->Y;
oldPos->X = Rectangle1->Position->X;
oldPos->Y = Rectangle1->Position->Y;
next = 0;
posArray[next] = (*oldPos);
this->Fill->Color = claSilver;
// Attach the FloatAnimations to the Rectangle's positio
FloatAnimation1->Parent = Rectangle1;
FloatAnimation1->PropertyName = "Position.X";
FloatAnimation1->StopValue = Rectangle1->Position->X + 200;
FloatAnimation1->Duration = 5;
FloatAnimation1->AnimationType = TAnimationType::atIn;
FloatAnimation1->Interpolation = TInterpolationType::Linear;
FloatAnimation1->StartFromCurrent = true;
FloatAnimation2->Parent = Rectangle1;
FloatAnimation2->PropertyName = "Position.Y";
FloatAnimation2->StopValue = Rectangle1->Position->Y - 200;
FloatAnimation2->Duration = 5;
FloatAnimation2->AnimationType = TAnimationType::atIn;
FloatAnimation2->Interpolation = TInterpolationType::Linear;
FloatAnimation2->StartFromCurrent = true;
}
// ---------------------------------------------------------------------------
void __fastcall TForm2::ReturnRectClick(TObject *Sender) {
// Returns the rectangle to the starting position
Rectangle1->Position->X = saveX;
Rectangle1->Position->Y = saveY;
oldPos->X = saveX;
oldPos->Y = saveY;
MoveRect->Enabled = true;
ReturnRect->Enabled = false;
}
// ---------------------------------------------------------------------------
void __fastcall TForm2::MoveRectClick(TObject *Sender) {
TAnimationType AniType;
TInterpolationType InterpType;
unsigned int ComboBoxIndex;
ComboBoxIndex = ComboBox2->ItemIndex;
AniType = TAnimationType(ComboBoxIndex);
FloatAnimation2->AnimationType = AniType;
ComboBoxIndex = ComboBox1->ItemIndex;
InterpType = TInterpolationType(ComboBoxIndex);
FloatAnimation2->Interpolation = InterpType;
FloatAnimation1->Start();
FloatAnimation2->Start();
MoveRect->Enabled = false;
ReturnRect->Enabled = true;
}
// ---------------------------------------------------------------------------
void __fastcall TForm2::FormPaint(TObject *Sender, TCanvas *Canvas,
const TRectF &ARect)
{
int i;
Canvas->BeginScene();
Canvas->StrokeThickness = 4;
Canvas->Fill->Color = claBlack;
Canvas->FillEllipse(RectF(FloatAnimation1->StopValue - 2,
FloatAnimation2->StopValue - 2, FloatAnimation1->StopValue + 2,
FloatAnimation2->StopValue + 2), 100);
Canvas->FillEllipse(RectF(saveX - 2, saveY - 2, saveX + 2, saveY + 2), 100);
Canvas->FillEllipse(RectF(Rectangle1->Position->X - 2,
Rectangle1->Position->Y - 2, Rectangle1->Position->X + 2,
Rectangle1->Position->Y + 2), 100);
for (i = 0; i < next; i++) {
if ((posArray[i].X != FloatAnimation1->StopValue) &&
(posArray[i].Y != FloatAnimation2->StopValue)) {
Canvas->DrawLine(posArray[i], posArray[i + 1], 1.0);
}
}
Canvas->EndScene();
}
// ---------------------------------------------------------------------------
Uses
- FMX.Ani.TFloatAnimation ( fr | de | ja )
- FMX.Controls.TControl.Position ( fr | de | ja )
- FMX.Ani.TAnimation.AnimationType ( fr | de | ja )
- FMX.Ani.TAnimation.Interpolation ( fr | de | ja )
- FMX.Types.TAnimationType ( fr | de | ja )
- FMX.Types.TInterpolationType ( fr | de | ja )
- FMX.Graphics.TCanvas.DrawLine ( fr | de | ja )
- FMX.Ani.TAnimation.OnProcess ( fr | de | ja )
- FMX.Ani.TAnimation.Enabled ( fr | de | ja )
- FMX.Ani.TAnimation.Pause ( fr | de | ja )