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 frames on the comic book page. When I release the button it will zoom into that frame. But its instant. And I would like for it to have an animation effect.
Thus instead of going and setting the values of PicRect to the “END VALUE”
PicRect.Left
PicRect.right
PicRect.top
PicRect.bottom
as seen in code below, I need a way to slowly get there, Some kind of while loop that sets those values a little at a time till untill it gets to the “end value” But I am not 100% sure on how this math is working. Nor do any of my while loop tries do anything but zoom in way too far. This is the procedure.
procedure TZImage.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var coef:Double;
t:integer;
begin
if FMouse=mNone then Exit;
if x>ShowRect.Right then x:=ShowRect.Right;
if y>ShowRect.Bottom then y:=ShowRect.Bottom;
if FMouse=mZoom then begin //calculate new PicRect
t:=startx;
startx:=Min(startx,x);
x:=Max(t,x);
t:=starty;
starty:=Min(starty,y);
y:=Max(t,y);
FMouse:=mNone;
MouseCapture:=False;
//enable the following if you want to zoom-out by dragging in the opposite direction}
{ if Startx>x then begin
DblClick;
Exit;
end;}
if Abs(x-startx)<5 then Exit;
if (x - startx < y - starty) then
begin
while (x - startx < y - starty) do
begin
x := x + 100;
startx := startx - 100;
end;
end
else if (x - startx > y - starty) then
begin
while (x - startx > y - starty) do
begin
y := y + 100;
starty := starty - 100;
end;
end;
//This is were it sets the zoom info. This is were
//I have to change to slowly get the PICRECT.Left/right/top/bottom
if (PicRect.Right=PicRect.Left)
then
coef := 100000
else
coef:=ShowRect.Right/(PicRect.Right-PicRect.Left);
PicRect.Left:=Round(PicRect.Left+startx/coef);
PicRect.Right:=PicRect.Left+Round((x-startx)/coef);
if (PicRect.Bottom=PicRect.Top)
then
coef := 100000
else
coef:=ShowRect.Bottom/(PicRect.Bottom-PicRect.Top);
PicRect.Top:=Round(PicRect.Top+starty/coef);
PicRect.Bottom:=PicRect.Top+Round((y-starty)/coef);
end;
if FMouse=mDrag then begin
FMouse:=mNone;
Canvas.Pen.Mode:=pmCopy;
Screen.Cursor:=crDefault;
end;
Invalidate;
end;
I believe this can be done in the code above. but also wanted to add this incase it helps.
type
TZImage = class(TGraphicControl)
private
FBitmap : TBitmap;
PicRect : TRect;
ShowRect : TRect;
FShowBorder : boolean;
FBorderWidth : integer;
FForceRepaint : boolean;
FMouse : (mNone, mDrag, mZoom);
FProportional : boolean;
FDblClkEnable : boolean;
startx, starty,
oldx, oldy : integer;
thanks for any help in getting this to work.
I’ve got a few suggestions; I’m not sure that they’ll be sufficient to solve your problem, but I hope it helps you get there.
First, your
whileloops are doing a fair amount of funny fiddling:Note that
x - start == y - startycase is being completely overlooked. I don’t know if this matters.Second, this could probably be re-written without a loop. I’m guessing here, it’d take a little testing to see if this is correct, but this feels like the right path:
I’m not entirely sure why you’re trying to get
(x-startx) - (y-starty)to within 200 of each other; there may be something better still.This section of code is a little confusing:
Is
coefsupposed to be overwritten from the earlier? Or, should you instead calculate acoefxandcoefyand then pick the (larger? smaller? closer to 100000?) value to serve for both the.Left,.Right,.Top, and.Bottomcalculations? I have to think that this code, as it stands, is more likely to lead to awkward stretching of your content in a way that will likely annoy users and authors both.Now, to address the real reason why you’re here, animating the zoom — you’ll probably need to drastically change something. I feel like your
whileloops were probably intended to do the zooming, but they come after thecoefcalculations, so I assumed they were meant for something else. But, once you do figure out where exactly to place the loop to calculate differentcoefvalues over a range from “no zoom” to “final zoom”, you’ll also need to add calls to repaint the display — or, depending upon your environment, maybe need to add some callback code fired by a timer every 50 ms or something to repaint with updatedcoefvalues.