Math for slow image scaling

I have a .bmp image with a comic book layout. Currently my code works like this. If I right-click and hold down the mouse button, I can draw a tent-type field around one of the frames on the comic page. When I release the button, it will increase in this frame. But its a moment. And I would like for him to have an animation effect.

Thus, instead of switching and setting PicRect values ​​to "END VALUE"

PicRect.Left
PicRect.right
PicRect.top
PicRect.bottom

as you can see from the code below, I need a way to get there slowly. Some kind of while loop that sets these values ​​a little at a time until it reaches the "final value". But I'm not 100% sure how this math works. None of my while attempts do anything but scale 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, which 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;

Thank you for any help in the work.

+5
source share
4 answers

I have a few suggestions; I am not sure that there will be enough of them to solve your problem, but I hope this helps you get there.

Firstly, your loops whilemake quite a lot of funny driving:

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
     /* similar code */

, x - start == y - starty . , .

-, , , . , , , , :

foo := (x - startx) - (y - starty)
if (foo > 200 || foo < -200)
    bar = foo / 200  # I assume integer truncation
    x += bar * 100
    startx += bar * 100

, (x-startx) - (y-starty) 200 ; - .

:

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;

, coef ? , coefx coefy, (? ? 100000?), .Left, .Right, .Top, .Bottom ? , , , , , , .

, , , - , , - . , while, , , coef, , - . , coef " " " ", - , , , 50 - coef.

+6

while - :

  • , , , ..
  • , (, Sleep), , .

sarnold Elling : (, TTimer) . :

  • , , , . :
    • - , Windows,
    • - .
  • . , , .

, :

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; 

:

  • FCropRect - , FPrevCropRect - ,
  • FAnimRect - , ,
  • FAnimStartTick - , Zoom,
  • ( 15 , ~ 67 ), Animate ,
  • Done - ,
  • Invalidate , FAnimRect.
+5

( , , , stackoverflow).

, glflow:

http://code.google.com/p/glflow/

GLScene , .

GLScene, , , .

, .

. .

+3

. , , . , . , . :

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;

, , , , , . . , , , , x-startx y-starty . , , 50pix 100pix, 50pix, , 100 . . , , , , , , , . , , , , . , . , . , , 200pix , . 85% +, , - .

, , , . , , . , . , . coefx coefy, . , . , , .

, , . http://www.torry.net/authorsmore.php?id=986 Zimage .

, , , , . , , , slop . .

Add another animation question. At the same time, it will also allow us to add animation when moving from one image zoom point to another zoom point. For our application, it will be from one comic panel to another, either below or on the side, and in most cases a different size. Will loading between the values ​​on the left, right, top and bottom be the best way to show this type of animation? If so, I think this will also work when moving from a full image to the first enlarged panel.

0
source

All Articles