From fcf5a469c78c7ea1c92a7b8409e70c723ef02ea3 Mon Sep 17 00:00:00 2001 From: backuppc Date: Thu, 23 Oct 2025 10:08:59 +0900 Subject: [PATCH] fix: Correct mouse-centered wheel zoom functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix ScreenToWorld coordinate transformation bug in wheel event - Implement proper mouse cursor-centered zoom calculation - Calculate world coordinates before zoom and maintain them after zoom - Adjust pan offset to keep mouse cursor pointing at same world position - Remove matrix-based transformation that was causing coordinate issues Fixes: Wheel zoom now correctly centers on mouse cursor position and no longer causes erratic panning πŸ€– Generated with Claude Code Co-Authored-By: Claude --- .../Controls/UnifiedAGVCanvas.Mouse.cs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs index 63bfaf3..a88484e 100644 --- a/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs +++ b/Cs_HMI/AGVLogic/AGVNavigationCore/Controls/UnifiedAGVCanvas.Mouse.cs @@ -170,23 +170,25 @@ namespace AGVNavigationCore.Controls private void UnifiedAGVCanvas_MouseWheel(object sender, MouseEventArgs e) { - // ν˜„μž¬ 마우슀 μœ„μΉ˜λ₯Ό μ›”λ“œ μ’Œν‘œλ‘œ λ³€ν™˜ (쀌 μ „) - var mouseWorldBefore = ScreenToWorld(e.Location); + // 마우슀 μ»€μ„œ μœ„μΉ˜ (슀크린 μ’Œν‘œ) + Point mouseScreenPos = e.Location; + // 쀌 μ „ λ§ˆμš°μŠ€κ°€ κ°€λ¦¬ν‚€λŠ” μ›”λ“œ μ’Œν‘œ + float worldX_before = (mouseScreenPos.X - _panOffset.X) / _zoomFactor; + float worldY_before = (mouseScreenPos.Y - _panOffset.Y) / _zoomFactor; + + // 이전 쀌 νŒ©ν„° μ €μž₯ float oldZoom = _zoomFactor; - // 쀌 νŒ©ν„° 계산 (휠 델타 기반) - 더 λΆ€λ“œλŸ¬μš΄ 쀌 + // 쀌 νŒ©ν„° 계산 (휠 델타 기반) if (e.Delta > 0) - _zoomFactor = Math.Min(_zoomFactor * 1.15f, 5.0f); // ν™•λŒ€ (더 λΆ€λ“œλŸ¬μ›€) + _zoomFactor = Math.Min(_zoomFactor * 1.15f, 5.0f); // ν™•λŒ€ else - _zoomFactor = Math.Max(_zoomFactor / 1.15f, 0.1f); // μΆ•μ†Œ (더 λΆ€λ“œλŸ¬μ›€) + _zoomFactor = Math.Max(_zoomFactor / 1.15f, 0.1f); // μΆ•μ†Œ - // 쀌 ν›„ 마우슀 μœ„μΉ˜μ˜ μ›”λ“œ μ’Œν‘œ - var mouseWorldAfter = ScreenToWorld(e.Location); - - // 마우슀 μœ„μΉ˜κ°€ 같은 μ›”λ“œ μ’Œν‘œλ₯Ό 가리킀도둝 팬 μ˜€ν”„μ…‹ μ‘°μ • - _panOffset.X += (int)((mouseWorldBefore.X - mouseWorldAfter.X) * _zoomFactor); - _panOffset.Y += (int)((mouseWorldBefore.Y - mouseWorldAfter.Y) * _zoomFactor); + // 쀌 후에도 λ§ˆμš°μŠ€κ°€ 같은 μ›”λ“œ μ’Œν‘œλ₯Ό 가리킀도둝 팬 μ˜€ν”„μ…‹ μ‘°μ • + _panOffset.X = (int)(mouseScreenPos.X - worldX_before * _zoomFactor); + _panOffset.Y = (int)(mouseScreenPos.Y - worldY_before * _zoomFactor); Invalidate(); }