I have an owner-draw PictureBox (picGrid
) and I want to allow the user to zoom using the mouse wheel. That part is easy. But I want to automatically scroll such that the logical point under the mouse is still the logical point under the mouse after the zoom.
Here's what I have so far. It almost works but is just not right. XScroll
and YScroll
are my scroll positions and will be used to set the scroll bar (in addition to offset the image).
/// <summary>
/// Sets the current zoom percent.
/// </summary>
/// <param name="percent">The percent that the zoom should be set (100 == 1:1 scaling).</param>
/// <param name="x">X coordinate of the mouse in pixels.</param>
/// <param name="y">Y coordinate of the mouse in pixels.</param>
public void SetZoom(int percent, int x, int y)
{
// If needed, this method translates mouse coordinate to logical coordinates
// but doesn't appear to be needed here.
//TranslateCoordinates(ref x, ref y);
// Calculate new scale (1.0f == 1:1 scaling)
float newDrawScale = (float)percent / 100;
// Enforce zoom limits
if (newDrawScale < 0.1f)
newDrawScale = 0.1f;
else if (newDrawScale > 1500.0f)
newDrawScale = 1500.0f;
// Set new zoom (if it's changed)
if (newDrawScale != DrawScale)
{
DrawScale = newDrawScale;
// *** Here's the part that isn't right ***
// Scroll to keep same logical point under mouse
float delta = (DrawScale - 1f);
XScroll = (x * delta);
YScroll = (y * delta);
// Reflect change in scrollbars
UpdateScrollbars();
// Redraw content
picGrid.Invalidate();
}
}
How can I calculate the new scroll position so that the same logical point remains under the mouse pointer after the zoom?