Zoom to mouse point
#4
This way quite tricky :cool:

Sorry for waiting so long - I working on new version of Reader3ds.

So here is the solution:

The XAML part is the same as before:
Code:
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:zoomPanel="clr-namespace:Ab2d.Controls;assembly=Ab2d.Controls.ZoomPanel"
    Title="Window1" Height="300" Width="300"
    MouseWheel="Window_MouseWheel">
    <Grid>
        <zoomPanel:ZoomPanel Name="ZoomPanel1" IsMouseWheelZoomEnabled="False" ZoomMode="Move">
            <TextBlock Text="12345"/>
        </zoomPanel:ZoomPanel>
    </Grid>
</Window>

The tricky part is in the code:
Code:
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
{
    Point mousePosition;
    double zoomFactor;

    if (e.Delta > 0)
        zoomFactor = 1.3;
    else
        zoomFactor = 1 / 1.3;

    mousePosition = e.GetPosition(ZoomPanel1);

    ZoomPanel1.Viewbox = GetNewViewbox(zoomFactor, mousePosition);

    e.Handled = true;
}

private Rect GetNewViewbox(double zoomFactor, Point mousePosition)
{
    UIElement content;
    double zoomPanelAspectRatio, contentAspectRatio;
    double aspect;
    Rect newViewbox;
    Point relativeMousePosition;
    Point relativeViewboxPosition;
    Point relativeViewboxPosition2;
    Rect actualViewbox1, actualViewbox2;

    content = ZoomPanel1.Content as UIElement;
    
    if (content == null)
        return ZoomPanel1.Viewbox;

    zoomPanelAspectRatio = ZoomPanel1.ActualWidth / ZoomPanel1.ActualHeight;
    contentAspectRatio = content.DesiredSize.Width / content.DesiredSize.Height;

    // Apsect ration between ZoomPanel and its content
    aspect = contentAspectRatio / zoomPanelAspectRatio;


    relativeMousePosition = new Point(mousePosition.X / ZoomPanel1.ActualWidth,
                                      mousePosition.Y / ZoomPanel1.ActualHeight);


    // Calculate actual viewbox
    actualViewbox1 = AdjustRectForAspectRatio(ZoomPanel1.Viewbox, aspect);

    // mouse position on the original actual viewbox
    relativeViewboxPosition = new Point(actualViewbox1.X + actualViewbox1.Width * relativeMousePosition.X,
                                        actualViewbox1.Y + actualViewbox1.Height * relativeMousePosition.Y);





    // Do the normal zoom to the current center point for the zoomFactor
    double viewboxDx, viewboxDy;

    // viewboxDx and viewboxDy are the actual viewbox changes
    viewboxDx = ZoomPanel1.Viewbox.Width - (ZoomPanel1.Viewbox.Width / zoomFactor);
    viewboxDy = ZoomPanel1.Viewbox.Height - (ZoomPanel1.Viewbox.Height / zoomFactor);

    newViewbox = new Rect(ZoomPanel1.Viewbox.X + viewboxDx / 2,
                          ZoomPanel1.Viewbox.Y + viewboxDy / 2,
                          ZoomPanel1.Viewbox.Width - viewboxDx,
                          ZoomPanel1.Viewbox.Height - viewboxDy);



    // Now get where the mouse position would be in the newViewbox
    actualViewbox2 = AdjustRectForAspectRatio(newViewbox, aspect);


    relativeViewboxPosition2 = new Point(actualViewbox2.X + actualViewbox2.Width * relativeMousePosition.X,
                                         actualViewbox2.Y + actualViewbox2.Height * relativeMousePosition.Y);

    // Adjust the newViewbox so the objects under the mouse position stay on the same place
    newViewbox.X -= relativeViewboxPosition2.X - relativeViewboxPosition.X;
    newViewbox.Y -= relativeViewboxPosition2.Y - relativeViewboxPosition.Y;


    return newViewbox;
}

private Rect AdjustRectForAspectRatio(Rect originalRect, double aspect)
{
    Rect adjustedRect;

    adjustedRect = originalRect;

    if (aspect > 1) // content wider than ZoomPanel
    {
        //actualViewbox2.Y = actualViewbox1.Y * aspect - (actualViewbox1.Height * (aspect - 1) / 2);
        adjustedRect.Y *= aspect;
        adjustedRect.Height *= aspect;
    }
    else
    {
        adjustedRect.X /= aspect;
        adjustedRect.Width /= aspect;
    }

    return adjustedRect;
}

This should work.

The code will be probably included into next version of ZoomPanel (cannot say when it will be published).

Thank you for your recommendation.
  


Messages In This Thread
Zoom to mouse point - by marianokaplan - 11-23-2009, 09:29 PM
RE: Zoom to mouse point - by abenedik - 11-26-2009, 03:10 PM
RE: Zoom to mouse point - by Ronit Well - 11-28-2009, 06:31 AM
RE: Zoom to mouse point - by abenedik - 12-04-2009, 04:35 PM

Forum Jump:


Users browsing this thread:
1 Guest(s)