Проект прикреплен к посту.
Код:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.Edit;
type
TForm1 = class(TForm)
Path1: TPath;
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Label1: TLabel;
Edit2: TEdit;
Label2: TLabel;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Edit4: TEdit;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TAnimationPath = class(TThread)
public
private
countflash: byte;
tmpline: TLine;
NowP,EndP: TPoint;
Sender: TObject;
duration: single;
Step: TPoint;
updateinterval: integer;
{ Private declarations }
protected
procedure Execute; override;
constructor Create(StartPos,EndPos:TPoint;induration:single;inSender:TObject);
procedure update;
procedure flashanim;
procedure flashcreate;
procedure delassept;
end;
var
Form1: TForm1;
Assept: array of Integer;
implementation
{$R *.fmx}
constructor TAnimationPath.Create(StartPos, EndPos: TPoint; induration: single; inSender: TObject);
begin
inherited Create(false);
NowP := StartPos;
EndP := EndPos;
Sender := inSender;
countflash := 5;
duration := induration*1000;
updateinterval := 50;
Step := (EndP - NowP);
Step.X := abs(Step.X * updateinterval);
Step.Y := abs(Step.Y * updateinterval);
Step.X := Trunc(Step.X / duration);
Step.Y := Trunc(Step.Y / duration);
tmpline := Tline.Create(nil);
tmpline.Parent := TPath(sender);
tmpline.Position.X := NowP.X;
tmpline.Position.Y := NowP.Y;
tmpline.Width := 1;
tmpline.Height := 1;
tmpline.Stroke := TPath(Sender).Stroke;
end;
procedure TAnimationPath.delassept;
var I: integer;
J: integer;
L: TLine;
begin
I := Trunc(tmpline.Width)-1;
J := Trunc(tmpline.Height)-1;
Tpath(Sender).Data.Data := Tpath(Sender).Data.Data + ' M' + IntToStr(Trunc(tmpline.Position.X)) + ',' + IntToStr(Trunc(tmpline.Position.Y)) + ' L' + IntToStr(Trunc(tmpline.Position.X + I)) + ',' + IntToStr(Trunc(tmpline.Position.Y + J));
for I := TPath(Sender).ChildrenCount-1 downto 0
do if TPath(Sender).Children[I] is TLine then
if (TLine(TPath(Sender).Children[I]) = tmpline) then
begin
L := TLine(TPath(Sender).Children[I]);
TPath(Sender).RemoveObject(L);
L.Free;
Exit;
end;
end;
procedure TAnimationPath.Execute;
begin
if (NowP.X <> EndP.X) and (NowP.Y <> EndP.Y) then tmpline.LineType := TLineType.Diagonal
else
begin
if (NowP.X <> EndP.X) then tmpline.LineType := TLineType.Top;
if (NowP.Y <> EndP.Y) then tmpline.LineType := TLineType.Left;
end;
try
while (NowP.X <> EndP.X)or(NowP.Y <> EndP.Y) do
begin
Synchronize(Update);
Synchronize(Flashcreate);
Synchronize(flashanim);
Sleep(updateinterval);
end;
while (tmpline.ChildrenCount > 0) do
begin
Synchronize(flashanim);
Sleep(updateinterval);
end;
except
end;
Synchronize(delassept);
end;
procedure TAnimationPath.flashanim;
var C: TCircle;
I: integer;
begin
for I := Tmpline.ChildrenCount-1 Downto 0
do if tmpline.Children[I] is TCircle
then
begin
C := TCircle(tmpline.Children[I]);
C.Position.Point := C.Position.Point + C.Position.DefaultValue;
if C.TagFloat / 10 < 1 then C.Opacity := C.TagFloat / 10;
C.TagFloat := C.TagFloat - 1;
if C.TagFloat < 0
then
begin
Tpath(Sender).RemoveObject(C);
C.Free;
end;
end;
end;
procedure TAnimationPath.flashcreate;
var I: Integer;
C: TCircle;
P: TPointF;
begin
for I := 0 to countflash do
begin
C := TCircle.Create(nil);
C.Parent := tmpline;
C.Width := 2 + Random * 4;
C.Height := C.Width;
C.fill.Color := TAlphaColors.Yellow;
C.Stroke.Kind := TBrushKind.None;
if NowP.X < EndP.X then P.X := tmpline.Width
else P.X := 0;
if NowP.Y < EndP.Y then P.Y := tmpline.Height
else P.Y := 0;
C.Position.Point := P;
C.Position.DefaultValue := PointF(0.5 - Random,0.5 - Random).Normalize * (1 + random * 2);
C.TagFloat := 10 + Random(15);
C.Opacity := 1 - Random;
end;
end;
procedure TAnimationPath.update;
begin
if (NowP.X < EndP.X) then
begin
if (NowP.X + Step.X > EndP.X) then
begin
tmpline.Width := tmpline.Width + EndP.X - NowP.X;
NowP.X := EndP.X;
end
else
begin
NowP.X := NowP.X + Step.X;
tmpline.Width := tmpline.Width + Step.X;
end;
end;
if (NowP.Y < EndP.Y) then
begin
if (NowP.Y + Step.Y > EndP.Y) then
begin
NowP.Y := EndP.Y;
tmpline.Height := tmpline.Height + EndP.Y - NowP.X;
end
else
begin
NowP.Y := NowP.Y + Step.Y;
tmpline.Height := tmpline.Height + Step.Y;
end;
end;
if (NowP.X > EndP.X) then
begin
if (NowP.X - Step.X < EndP.X) then
begin
NowP.X := EndP.X;
tmpline.Position.X := tmpline.Position.X - (NowP.X - EndP.X);
tmpline.Width := tmpline.Width + (NowP.X - EndP.X);
end
else
begin
NowP.X := NowP.X - Step.X;
tmpline.Position.X := tmpline.Position.X - Step.X;
tmpline.Width := tmpline.Width + Step.X;
end;
end;
if (NowP.Y > EndP.Y) then
begin
if (NowP.Y - Step.Y < EndP.Y) then
begin
NowP.Y := EndP.Y;
tmpline.Position.Y := tmpline.Position.Y - (NowP.Y - EndP.Y);
tmpline.Height := tmpline.Height + (NowP.Y - EndP.Y);
end
else
begin
NowP.Y := NowP.Y - Step.Y;
tmpline.Position.Y := tmpline.Position.Y - Step.Y;
tmpline.Height := tmpline.Height + Step.Y;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var TmpAnim: TAnimationPath;
X,Y: Integer;
begin
TmpAnim := TAnimationPath.create(Point(0,0),Point(0,200),1,Path1);
TmpAnim := TAnimationPath.create(Point(0,200),Point(400,200),2,Path1);
TmpAnim := TAnimationPath.create(Point(400,200),Point(400,0),3,Path1);
TmpAnim := TAnimationPath.create(Point(400,0),Point(0,0),4,Path1);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Path1.Data.Clear;
end;
end.
Постоепенная отрисовкаTPath.zip