I want to zoom a control based on the current cursor location. The zoom should keep the point behind mouse cursor on the same position.
I have attached two files:
In Form2.cs, I'm zooming and drawing an image on a Form directly. It works fine as intended but it's not my requirement.
In Form1.cs, I'm zooming a panel using the same logic but it's behaving very differently. Can someone help me fix it?
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ImageZoom
{
public partial class Form1 : Form
{
float zoom = 1;
Size initSize;
int ctrlX, ctrlY;
Panel childControl;
public Form1()
{
InitializeComponent();
string imagefilename = @"..\..\test.tif";
Image img = Image.FromFile(imagefilename);
childControl = new Panel
{
BackgroundImage = img,
BackgroundImageLayout = ImageLayout.Stretch,
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(100, 100),
Size = new Size(200, 200)
};
Controls.Add(childControl);
initSize = childControl.Size;
ctrlX = childControl.Left;
ctrlY = childControl.Top;
}
protected override void OnMouseWheel(MouseEventArgs e)
{
float oldzoom = zoom;
if (e.Delta > 0)
zoom = Math.Min(zoom + 0.1F, 100F);
else if (e.Delta < 0)
zoom = Math.Max(zoom - 0.1F, 0.1F);
Point currLoc = e.Location;
int x = currLoc.X; // Where location of the mouse in the pictureframe
int y = currLoc.Y;
int oldimagex = (int)(x / oldzoom); // Where in the IMAGE is it now
int oldimagey = (int)(y / oldzoom);
int newimagex = (int)(x / zoom); // Where in the IMAGE will it be when the new zoom i made
int newimagey = (int)(y / zoom);
ctrlX += newimagex - oldimagex; // Where to move image to keep focus on one point
ctrlY += newimagey - oldimagey;
childControl.Width = (int)(initSize.Width * zoom);
childControl.Height = (int)(initSize.Height * zoom);
Point loc = new Point(ctrlX, ctrlY);
childControl.Location = loc;
}
}
}
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ImageZoom
{
public partial class Form2 : Form
{
Image img;
int imgx = 0; // current offset of image
int imgy = 0;
float zoom = 1;
public Form2()
{
InitializeComponent();
string imagefilename = @"..\..\test.tif";
img = Image.FromFile(imagefilename);
Paint += new PaintEventHandler(this_Paint);
}
protected override void OnMouseWheel(MouseEventArgs e)
{
float oldzoom = zoom;
if (e.Delta > 0)
zoom = Math.Min(zoom + 0.1F, 100F);
else if (e.Delta < 0)
zoom = Math.Max(zoom - 0.1F, 0.1F);
Point currLoc = e.Location;
int x = currLoc.X; // Where location of the mouse in the pictureframe
int y = currLoc.Y;
int oldimagex = (int)(x / oldzoom); // Where in the IMAGE is it now
int oldimagey = (int)(y / oldzoom);
int newimagex = (int)(x / zoom); // Where in the IMAGE will it be when the new zoom i made
int newimagey = (int)(y / zoom);
imgx += newimagex - oldimagex; // Where to move image to keep focus on one point
imgy += newimagey - oldimagey;
Invalidate();
}
private void this_Paint(object sender, PaintEventArgs e)
{
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.ScaleTransform(zoom, zoom);
e.Graphics.DrawImage(img, imgx, imgy);
}
}
}
What I want is to zoom that panel according to the mouse location. e.g. Like we zoom a canvas in Paint.NET or Adobe Illustrator etc. The area under the mouse stays there.