0

I have developed windows application in c# where I have a pictureBox inside a panel. I have applied zoom in and zoom out functionality in it. Now I want the image inside the pictureBox to pan. I have applied mouseDown, mouseMove and mouseUp event on pictureBox. The code for it is:

private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
   if (pflag == 1)
   {
       dragging = true;
       start = e.Location;
   }
}

private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
    // panning code
    if (pflag == 1)
    {
        if (dragging && zoom == 1)
        {
             pictureBox2.Location = new Point(pictureBox2.Left + (e.Location.X - start.X), pictureBox2.Top + (e.Location.Y - start.Y));
        }
    }
}

private void pictureBox2_MouseUp(object sender, MouseEventArgs e)
{ 
    if (pflag == 1)
    {
        dragging = false;
    }
}

Here the image is panning but with no boundary control. Sometimes even the image goes below the panel area while panning. What I need here is, image should move top, left , right, bottom according to zoom factor i.e like how scroll bar works and not beyond that.

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
Umaima B
  • 11
  • 4

1 Answers1

0

You don't need to worry about zoom as the mouse coordinates will be fine as they are. The distance of the shown pixels should be the same as those the cursor is moving..

You also do not really need the dragging variable, unless you use it for something else.

However you do need to check the mouse button during the MouseMove:

    if (pflag == 1  && e.Button == System.Windows.Forms.MouseButtons.Left  )

Do note few things:

  • The user expects that the spot he drags stays with the mouse cursor just as the pixel he touches should always move with the fingertip. Do not surprise him by scaling in the zoom-factor!

  • If you wanted to do that you would need to use a factor, not adding an number.

  • Yes, the scrollbars will factor in the zoom but also the lift will still stay with the mouse!

Here is an example of how to set limits to prevent the user from going too far. It it a little involved because it needs to work when zoomed in or out. Do not start with illegal positions, though, nor get into those while zooming!

//  panning code
if ( pflag == 1 && e.Button == System.Windows.Forms.MouseButtons.Left  )
{
    {
        Rectangle panRect = new Rectangle(panel1.Location, panel1.ClientSize);
        Rectangle picRect = new Rectangle(pictureBox2.Location, pictureBox2.ClientSize);
        int newLeft = pictureBox2.Left + (e.Location.X - start.X);
        int newTop = pictureBox2.Top + (e.Location.Y - start.Y);
        int newRight = newLeft + picRect.Width;
        int newBottom = newTop + picRect.Height;

        if ((newLeft < 0 && newRight < panRect.Width)
        || (newLeft > 0 /*&& newRight > panRect.Width */)) newLeft = picRect.Left;

        if ((newTop < 0 && newBottom < panRect.Width)
        || (newTop > 0 /*&& newBottom > panRect.Height*/)) newTop = picRect.Top;

        pictureBox2.Location = new Point(newLeft, newTop);
    }
    Text = "" + pictureBox2.Location;
}

Note the two parts I have commented out! As it is you can't move a picture that is smaller than the viewport; you can allow it by removing the comments but should then take care when zooming in to move it up and left to zero as it should never sit in the positve range and also overlap or else the scrollbars will behave in a weird way..!

TaW
  • 53,122
  • 8
  • 69
  • 111
  • I tried updating code according to your comment but still the same issue. Actually at the time of zooming I am increasing my pictureBox size but panel size remains same. When I am panning the image after zooming it, the pictureBox location changes with no limits. I want panning to be according to panel size plus zoom factor say 30. Beyond that limit if I am panning, the pictureBox/image should not be moved. The functionality should be like scroll bar. Beyond the limit of vertical and horizontal scroll bar, the image should not be moved or shifted. – Umaima B Feb 15 '16 at 04:26
  • _I want panning to be according to panel size plus zoom factor say 30._ That makes no sense! The panning always should follow the mouse, not be faster or run away from it!! _The functionality should be like scrollbar._ Well it should go in the other direction, right? If you want to put a limit on it you simply need to add it to the code. Other than that it works fine here: It work exactly like a touch screen, when I drag the image to the left it follows the fingertip/mouse.. – TaW Feb 15 '16 at 06:05
  • Can you please help me with some code in order to add limit? – Umaima B Feb 15 '16 at 06:10
  • Done, but the issue is a little trickier than it seems at first glance.. Letting the user do as he pleases sems simpler and also quite natural, imo. – TaW Feb 15 '16 at 08:27
  • It works like a wonder. Thank you so much. Your help works great for me. – Umaima B Feb 15 '16 at 09:21
  • If you are happy with the answer, please consider consider [accepting](http://stackoverflow.com/help/accepted-answer) it..! - I see that you have never done this: Go the the (invisible) checkmark at the top left, below the votes of the answer and click it! It turns green and gains us both a little reputation.. – TaW Feb 15 '16 at 09:29
  • This solution works perfect for images having same width and height. For images having width greater than height, the image is not moving/panning in upward/downward direction. For images having height greater than width, the image moves a little more in upward direction leaving bottom part of container(panel) blank. Please could you provide any suggestions on it?? – Umaima B Feb 15 '16 at 09:49
  • This is probably because your picturebox has an 'illegal' position and/or size. Both initially __and__ when zooming you need to make sure this doesn't happen. Start with `SizeMode=Autosize` and after that when zoomin in or out, ie with `SizeMode=Zoom` make sure to __keep the aspect ratio__! One way is to only use a __factor__, another is to __add__ an amount to __one__ side and the calculating the other __proportionally__. – TaW Feb 15 '16 at 10:03
  • Using a factor could look like this: `pictureBox2.Size = new Size(pictureBox2.ClientSize.Width * factor, pictureBox2.ClientSize.Height * factor);` Another solution would use a list of factors and calculate the sizes form the `Image.Size`; this will limit the zoom levels to a fixed series, like Photoshop does it. (Recommended) – TaW Feb 15 '16 at 10:06
  • I updated your code by adding foll: if (Math.Abs(newTop) >= (pictureBox5.Height - panel2.Height)) { newTop = pictureBox5.Top + (pictureBox5.Height - panel2.Height); } Now its working fine. – Umaima B Feb 16 '16 at 07:02