0

How to zoom to the cursor position after the graphics component has been transformed?
I want to be able to zoom to any of the test rectangles.

The panning is done with the Middle mouse button.
MouseWheel Event handles the zooming.
Ignore the DrawGrid method, it's just to get some visual reference.

Public Class Diagram

Dim renderOrigin As New Point
Dim zoom As Single = 1.0F
Dim startPoint As New Point
Dim isDragging As Boolean = False
Dim gridSpacing As Integer = 50

Dim testRects() As Rectangle = New Rectangle() {New Rectangle(-150, -150, 70, 25), _
                                                New Rectangle(-10, -5, 70, 25), _
                                                New Rectangle(100, 8, 70, 25), _
                                                New Rectangle(300, 80, 70, 25)}

Sub New()
    SetStyle(ControlStyles.ResizeRedraw, True)
    SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

End Sub

Protected Overrides Sub OnPaint(e As PaintEventArgs)

    Dim g As Graphics = e.Graphics
    g.TranslateTransform(renderOrigin.X, renderOrigin.Y)
    g.ScaleTransform(zoom, zoom)

    drawGrid(g)
    g.FillRectangles(Brushes.Green, testRects.ToArray)

End Sub


Private Sub drawGrid(ByRef g As Graphics)
    If zoom < 0.6 Then
        Exit Sub
    End If
    Dim oX As Integer = renderOrigin.X
    Dim oY As Integer = renderOrigin.Y
    Dim maxStepX As Integer = Math.Ceiling((Width - oX) / gridSpacing) / zoom
    Dim maxStepY As Integer = Math.Ceiling((Height - oY) / gridSpacing) / zoom
    Dim minStepX As Integer = Math.Floor((oX * -1) / gridSpacing) / zoom
    Dim minStepY As Integer = Math.Floor((oY * -1) / gridSpacing) / zoom


    For x = minStepX To maxStepX
        For y = minStepY To maxStepY
            g.DrawLine(Pens.Black, x * gridSpacing, gridSpacing * y, (x + 1) * gridSpacing, gridSpacing * y)
            g.DrawLine(Pens.Black, x * gridSpacing, gridSpacing * y, x * gridSpacing, (y + 1) * gridSpacing)
        Next
    Next
End Sub

Private Sub Diagram_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
    If e.Button = Windows.Forms.MouseButtons.Middle Then

        startPoint = New Point(e.X - renderOrigin.X, e.Y - renderOrigin.Y)
        isDragging = True
    End If
End Sub

Private Sub Diagram_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
    If isDragging Then
        renderOrigin = New Point(e.X - startPoint.X, e.Y - startPoint.Y)
        Invalidate()
    End If


End Sub

Private Sub Diagram_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
    isDragging = False

End Sub

Private Sub Diagram_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
    Dim i As Single = (e.Delta / Math.Abs(e.Delta)) / 100
    zoom += i
    If zoom < 0.1 Then zoom = 0.1
    If zoom > 1.0 Then zoom = 1.0

    renderOrigin = New Point(e.X - e.X * zoom, e.Y - e.Y * zoom)
    Invalidate()
End Sub



End Class
2
Contributors
1
Reply
32
Views
1 Year
Discussion Span
Last Post by Xavier_5
0

Your question has to do with windows forms and not with WPF. BTW I would move coordinates first to the mouse's position and then transform.

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.