Zoom on Canvas, centered on mouse position

霸气de小男生 提交于 2019-12-01 14:26:50

Here is a very basic example for zooming and panning a Canvas with fixed initial size. The MatrixTransform in the RenderTransform of the inner Canvas provides the necessary transformations, while the outer Canvas handles mouse input and sets an initial scaling.

<Canvas Background="Transparent"
        SizeChanged="ViewportSizeChanged"
        MouseLeftButtonDown="ViewportMouseLeftButtonDown"
        MouseLeftButtonUp="ViewportMouseLeftButtonUp"
        MouseMove="ViewportMouseMove"
        MouseWheel="ViewportMouseWheel">

    <Canvas x:Name="canvas" Width="1000" Height="600">
        <Canvas.RenderTransform>
            <MatrixTransform x:Name="transform"/>
        </Canvas.RenderTransform>

        <Ellipse Fill="Red" Width="100" Height="100" Canvas.Left="100" Canvas.Top="100"/>
        <Ellipse Fill="Green" Width="100" Height="100" Canvas.Right="100" Canvas.Bottom="100"/>
    </Canvas>
</Canvas>

Code behind:

private Point? mousePos;

private void ViewportSizeChanged(object sender, SizeChangedEventArgs e)
{
    ((MatrixTransform)canvas.RenderTransform).Matrix = new Matrix(
        e.NewSize.Width / canvas.ActualWidth,
        0, 0,
        e.NewSize.Height / canvas.ActualHeight,
        0, 0);
}

private void ViewportMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var viewport = (UIElement)sender;
    viewport.CaptureMouse();
    mousePos = e.GetPosition(viewport);
}

private void ViewportMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    ((UIElement)sender).ReleaseMouseCapture();
    mousePos = null;
}

private void ViewportMouseMove(object sender, MouseEventArgs e)
{
    if (mousePos.HasValue)
    {
        var pos = e.GetPosition((UIElement)sender);
        var matrix = transform.Matrix;
        matrix.Translate(pos.X - mousePos.Value.X, pos.Y - mousePos.Value.Y);
        transform.Matrix = matrix;
        mousePos = pos;
    }
}

private void ViewportMouseWheel(object sender, MouseWheelEventArgs e)
{
    var pos = e.GetPosition((UIElement)sender);
    var matrix = transform.Matrix;
    var scale = e.Delta > 0 ? 1.1 : 1 / 1.1;
    matrix.ScaleAt(scale, scale, pos.X, pos.Y);
    transform.Matrix = matrix;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!