In a view of 846 x 660, an image is rendered. By clicking anywhere on the image, zoom is multiplied by 1.2. However, and this is the important part, the part of the image clicked on shall remain the center of the zoom and remain in place of the part of the view clicked - i.e. directly below the mouse.
Since I'm not a VB-coder, my reply is in C-like quasi code.
To solve the problem, we need to be absolutely clear about what the input data is, which in turn is dependent on the source of the data. We start off with the follwing information:
// STATIC DATA
int imageWidth, imageHeight; // Size of source image
int viewWidth=846, viewHeight=660; // Size of onscreen view
Then you have the mouse click. We need to know two things from the click: Visually where in the view you clicked (viewX,viewY where top left of view is 0,0), and what position this represents in the image (imgX,imgY). The image coordinates can be calculated from viewX,viewY this way:
// VARIABLE DATA
// Position of view/sliders on the projected (zoomed) image
int scrollX, scrollY;
// Size of projected (zoomed) view/sliders
int scrollWidth, scrollHeight;
// Bar/slider size represents the view compared to projected image
int barWidth=viewWidth, barHeight=viewHeight;
float zoom=1; // Current zoom
int imgX=(viewX+scrollX)*zoom, imgY=(viewY+scrollY)*zoom;However, in my friend's case, the input data had the entire zoomed image as its reference, so top left of entire zoomed image represents 0,0 and bottom right (with sliders also bottom right) represents scrollWidth,scrollHeight. Hence, the parameter representing the clicked position (clickX,clickY) is the position in the view (viewX,viewY) PLUS the position of the slider bar (scrollX,scrollY).
Since we need to know the actual visual position on screen, relative to the top left corner of the view, the two coordinates must be calculated as such:
// Position unzoomed to fit zoom=1User control
// Pos. shifted to visual position
New zoom is calculated per policy defined by my friend - basically:
int zoomstep=1.2;Calculating new scroll bars
We now know the new zoom and want to render the view with (imgX,imgY) located where the mouse is on screen (viewX,viewY). First step is to tell the scroll bar control what the new sizes are:
// Size of projected image changed with zoomIf we set scrollX to imgX*zoom (image coordinate projected to new zoom level), our point ends up in top left corner of the view. However, we want this point at viewX,viewY, so we must offset the X-coordinate to the left, i.e. subtract the viewX,viewY coordinate:
// Size of bar/slider doesn't really change unless you change size of view
scrollX=(imgX*zoom)-viewX; scrollY=(imgY*zoom)-viewY;Edge adjustment
Unless we want to scroll off edge, we may need to adjust:
If you need to render the image manually, the typical approach is to find the source rectangle within the image and project it to the full view.
int left=scrollX/zoom, top=scrollY/zoom; // Reduce position to zoom=1Then complete the operation using StretchBlt (if in a Windows development environment) to stretch-copy the rectangle from the source image to your new view context.
int right=(scrollX+viewWidth)/zoom, bottom=(scrollY+viewHeight)/zoom;
Feel free to ask for further calculations or other parameters in the comments. If the above code fails, it may be that you have other input parameters or need to calculate some other numbers than what this article has attempted to convey.