I have an .bmp image with a comic book layout. Currently my code works like this. If I right click and hold down mouse button i can draw a marquee type box around one of the
Do not use a while loop to update the zoom level, because of two problems:
Sleep
), the code is running in the main thread and the program turn out being unresponsive.Like sarnold and Elling already said: use a timing device (e.g. a TTimer
) to perform a piece of the total zoom operation on every interval. Now, there are two ways to calculate those pieces:
I used the second solution in this answer to your related question, from which the following relevant snippets are taken:
procedure TZImage.Animate(Sender: TObject);
var
Done: Single;
begin
Done := (GetTickCount - FAnimStartTick) / FAnimDuration;
if Done >= 1.0 then
begin
FAnimTimer.Enabled := False;
FAnimRect := FCropRect;
end
else
with FPrevCropRect do
FAnimRect := Rect(
Left + Round(Done * (FCropRect.Left - Left)),
Top + Round(Done * (FCropRect.Top - Top)),
Right + Round(Done * (FCropRect.Right - Right)),
Bottom + Round(Done * (FCropRect.Bottom - Bottom)));
Invalidate;
end;
procedure TZImage.Zoom(const ACropRect: TRect);
begin
FPrevCropRect := FCropRect;
FAnimRect := FPrevCropRect;
FCropRect := ACropRect;
FAnimStartTick := GetTickCount;
FAnimTimer.Enabled := True;
end;
Explanation:
FCropRect
is the new zooming rectangle, and FPrevCropRect
is the previous one,FAnimRect
is the rectangle in between both, depending on the progress of the animation,FAnimStartTick
is the time on which the zoom operation is started with a call to Zoom
,Animate
is called,Done
is the percentage of animation progress,Invalidate
triggers a repaint which draws the graphic into FAnimRect
.