Reputation: 21
I am trying to animate a dropdown menu of 7 images using a for
loop, using a different component to change after each iteration of the code inside the for
loop. For example, the first time the loop runs: imgCourses7.Top
is used, but the second time the loop runs (when I = 1
) then imgCourses6.Top
should be used instead.
iCoursesCount := 7;
iTotalLength := (6+41)*iCoursesCount;
imgCourses7.Top := 6;
imgCourses6.Top := 6;
imgCourses5.Top := 6;
imgCourses4.Top := 6;
imgCourses3.Top := 6;
imgCourses2.Top := 6;
imgCourses1.Top := 6;
for I := 0 to iCoursesCount -1 do
begin
while not(imgCourses7.Top = iTotalLength - 41*(I+1)) do
begin
imgCourses8.Top := imgCourses8.Top + 6;
sleep(8);
application.ProcessMessages;
if imgCourses7.Top >= iTotalLength - 41*(I+1) then
begin
imgCourses7.Top := iTotalLength - 41*(I+1);
break;
end;
end;
end;
Upvotes: 0
Views: 102
Reputation: 596582
Like @AndreasRejbrand said in a comment, you can use an array, eg:
var
Images: array[0..6] of TImage;
TargetTop: Integer;
...
...
Images[0] := imgCourses7;
Images[1] := imgCourses6;
Images[2] := imgCourses5;
Images[3] := imgCourses4;
Images[4] := imgCourses3;
Images[5] := imgCourses2;
Images[6] := imgCourses1;
iCoursesCount := Length(Images);
TargetTop := 6+(41*iCoursesCount);
for I := 0 to iCoursesCount-1 do begin
Images[I].Top := 6;
end;
for I := 0 to iCoursesCount-1 do
begin
Dec(TargetTop, 41);
while Images[I].Top <> TargetTop do
begin
Images[I].Top := Images[I].Top + 6;
Sleep(8);
Application.ProcessMessages;
if Images[I].Top >= TargetTop then
begin
Images[I].Top := TargetTop;
Break;
end;
end;
end;
That being said, you really shouldn't be using a sleeping loop that requires Application.ProcessMessages()
on each iteration. You might consider using a TTimer
or TThread.ForceQueue()
instead. Don't block the main UI thread unnecessarily. For example:
published
procedure FormCreate(Sender: TObject);
private
Images: array[0..6] of TImage;
TargetTop: Integer;
CurrentImage: Integer;
procedure StartAnimatingMenu;
procedure StartAnimatingNextMenuItem;
procedure StepAnimateCurrentMenuItem;
...
...
procedure TMyForm.FormCreate(Sender: TObject);
begin
Images[0] := imgCourses7;
Images[1] := imgCourses6;
Images[2] := imgCourses5;
Images[3] := imgCourses4;
Images[4] := imgCourses3;
Images[5] := imgCourses2;
Images[6] := imgCourses1;
end;
procedure TMyForm.StartAnimatingMenu;
var
I: Integer;
begin
for I := Low(Images) to High(Images) do begin
Images[I].Top := 6;
end;
TargetTop := 6+(41*Length(Images));
CurrentImage := -1;
StartAnimatingNextMenuItem;
end;
procedure TMyForm.StartAnimatingNextMenuItem;
begin
Inc(CurrentImage);
if CurrentImage < Length(Images) then
begin
Dec(TargetTop, 41);
StepAnimateCurrentMenuItem;
end;
end;
procedure TMyForm.StepAnimateCurrentMenuItem;
begin
if Images[CurrentImage].Top <> TargetTop then
begin
Images[CurrentImage].Top := Images[CurrentImage].Top + 6;
TThread.ForceQueue(nil, StepAnimateCurrentMenuItem, 8);
end
else if Images[CurrentImage].Top >= TargetTop then
begin
Images[CurrentImage].Top := TargetTop;
StartAnimatingNextMenuItem;
end;
end;
Upvotes: 1