FireMonkey FMXAttachTAnimation Code Sample for C++

By: Tim DelChiaro

Abstract: This example demonstrates how the AnimationType and Interpolation properties affect the rate at which the value of a property changes under their control

    FMXAttachTAnimation (C++)

 

    Language:

    Versions:

 

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 itLinear, making the change of X and Y constant over time. The Interpolation andAnimationType 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 FireMonkey HD Application - C++ and add the following components to the form:

Rename the buttons to MoveRect and ReturnRect. Using the Object Inspector, add event handlers for the Form1.OnCreateMoveRect.OnClickReturnRect.OnClick,FloatAnimation1.OnProcess, and Form1.OnPaint events. Fill in with the sample code below.

The form should look like the following image.

File:Inital_form.png

After clicking the MoveRect button, the rectangle moves according to the selected options, drawing a line from its upper-left corner.

A linear animation:

File:Linear_animation.png

An elastic animation, with the rectangle moved:

File:Elasticinterpolation.png

    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::itLinear;
	i <= TInterpolationType::itBounce; 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::atInOut; 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::itLinear;
	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::itLinear;
	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

    See Also

Server Response from: ETNASC03