@@ -20,13 +20,13 @@ public partial class MiniMapView : ContentView
2020 private IMessageBus ? messageBus ;
2121 private IMessageBus ? MessageBus
2222 {
23- get
24- {
25- if ( messageBus != null ) return messageBus ;
26- messageBus = Handler ? . MauiContext ? . Services . GetService < IMessageBus > ( )
27- ?? IPlatformApplication . Current ? . Services . GetService < IMessageBus > ( ) ;
28- return messageBus ;
29- }
23+ get
24+ {
25+ if ( messageBus != null ) return messageBus ;
26+ messageBus = Handler ? . MauiContext ? . Services . GetService < IMessageBus > ( )
27+ ?? IPlatformApplication . Current ? . Services . GetService < IMessageBus > ( ) ;
28+ return messageBus ;
29+ }
3030 }
3131
3232 public MiniMapView ( )
@@ -35,10 +35,9 @@ public MiniMapView()
3535
3636 this . Loaded += ( s , e ) =>
3737 {
38- // Redraw when canvas is invalidated (drawing changes)
39- MessageBus ? . Listen < CanvasInvalidateMessage > ( )
40- . Throttle ( TimeSpan . FromMilliseconds ( 30 ) , RxApp . MainThreadScheduler ) // Throttle to avoid excessive redraws
41- . Subscribe ( _ => miniMapCanvas ? . InvalidateSurface ( ) ) ;
38+ MessageBus ? . Listen < CanvasInvalidateMessage > ( )
39+ . Throttle ( TimeSpan . FromMilliseconds ( 30 ) , RxApp . MainThreadScheduler )
40+ . Subscribe ( _ => miniMapCanvas ? . InvalidateSurface ( ) ) ;
4241 } ;
4342 }
4443
@@ -63,7 +62,7 @@ private void OnPaintSurface(object? sender, SKPaintSurfaceEventArgs e)
6362
6463 canvas . Clear ( SKColors . White ) ;
6564
66- // 1. Calculate Bounds of all elements
65+ // Calculate bounds of all elements
6766 var contentBounds = SKRect . Empty ;
6867 bool hasContent = false ;
6968
@@ -86,27 +85,23 @@ private void OnPaintSurface(object? sender, SKPaintSurfaceEventArgs e)
8685
8786 if ( ! hasContent )
8887 {
89- // Default to standard size if empty
9088 contentBounds = new SKRect ( 0 , 0 , 1000 , 1000 ) ;
9189 }
9290
93- // Add some padding to bounds
9491 contentBounds . Inflate ( 50 , 50 ) ;
9592
96- // 2. Calculate Fit Matrix (World -> MiniMap)
97- // Scale to fit contentBounds into info.Rect
93+ // Calculate fit matrix (world to minimap)
9894 float scaleX = info . Width / contentBounds . Width ;
9995 float scaleY = info . Height / contentBounds . Height ;
10096 float scale = Math . Min ( scaleX , scaleY ) ;
10197
102- // Center it
10398 float tx = ( info . Width - contentBounds . Width * scale ) / 2 - contentBounds . Left * scale ;
10499 float ty = ( info . Height - contentBounds . Height * scale ) / 2 - contentBounds . Top * scale ;
105100
106101 fitMatrix = SKMatrix . CreateScale ( scale , scale ) ;
107102 fitMatrix = SKMatrix . Concat ( SKMatrix . CreateTranslation ( tx , ty ) , fitMatrix ) ;
108103
109- // 3. Draw Content
104+ // Draw content
110105 canvas . Save ( ) ;
111106 canvas . Concat ( fitMatrix ) ;
112107
@@ -117,29 +112,27 @@ private void OnPaintSurface(object? sender, SKPaintSurfaceEventArgs e)
117112 foreach ( var element in layer . Elements )
118113 {
119114 if ( element . IsVisible )
120- {
115+ {
121116 element . Draw ( canvas ) ;
122117 }
123118 }
124119 }
125120 }
126121 canvas . Restore ( ) ;
127122
128- // 4. Draw Viewport Indicator
129- // Viewport is the inverse of the Main Canvas Matrix applied to the Main Canvas Screen Rect
130- if ( viewModel . NavigationModel . TotalMatrix . TryInvert ( out var mainInverse ) )
123+ // Draw viewport indicator
124+ if ( viewModel . NavigationModel . ViewMatrix . TryInvert ( out var mainInverse ) )
131125 {
132- // Main Canvas Screen Size (Approximate if not bound, but we can use the ViewModel's stored size)
133126 var mainScreenRect = viewModel . CanvasSize ;
134127 if ( mainScreenRect . Width > 0 )
135128 {
136- // Map Screen Rect Corners -> World Points
129+ // Map screen corners to world points
137130 var tl = mainInverse . MapPoint ( new SKPoint ( mainScreenRect . Left , mainScreenRect . Top ) ) ;
138131 var tr = mainInverse . MapPoint ( new SKPoint ( mainScreenRect . Right , mainScreenRect . Top ) ) ;
139132 var br = mainInverse . MapPoint ( new SKPoint ( mainScreenRect . Right , mainScreenRect . Bottom ) ) ;
140133 var bl = mainInverse . MapPoint ( new SKPoint ( mainScreenRect . Left , mainScreenRect . Bottom ) ) ;
141134
142- // Map World Points -> MiniMap Points
135+ // Map world points to minimap points
143136 var mTl = fitMatrix . MapPoint ( tl ) ;
144137 var mTr = fitMatrix . MapPoint ( tr ) ;
145138 var mBr = fitMatrix . MapPoint ( br ) ;
@@ -175,59 +168,31 @@ private void OnTouch(object? sender, SKTouchEventArgs e)
175168 {
176169 if ( viewModel == null ) return ;
177170
178- // Only process if the user is actually touching/clicking (avoids hover issues)
179- if ( ! e . InContact )
180- return ;
171+ if ( ! e . InContact ) return ;
181172
182173 var canvasView = sender as SKCanvasView ;
183174 if ( canvasView == null ) return ;
184175
185176 switch ( e . ActionType )
186- {
177+ {
187178 case SKTouchAction . Pressed :
188179 case SKTouchAction . Moved :
189- // Convert DIPs (Touch Location) to Pixels (Canvas Coordinates)
190- // SKTouchEventArgs.Location is ALREADY in pixels (canvas coordinates) for SKCanvasView.
191- // We do NOT need to multiply by density.
192180 var touchPointPixels = e . Location ;
193181
194- // Move main view to this location
195182 if ( fitMatrix . TryInvert ( out var inverseFit ) )
196183 {
197184 var worldPoint = inverseFit . MapPoint ( touchPointPixels ) ;
198185
199- // We want to center the Main View on this worldPoint.
200- // Main View Matrix: Scale * Translation.
201- // We want to keep current Scale.
202-
203- float currentScaleX = viewModel . NavigationModel . TotalMatrix . ScaleX ;
204- float currentScaleY = viewModel . NavigationModel . TotalMatrix . ScaleY ;
205-
206- // If rotated, extracting scale is harder.
207- // Let's assume we want to Pan the view so that worldPoint is at Center of Screen.
208-
209- // Target: TotalMatrix.MapPoint(worldPoint) = ScreenCenter
210- // TotalMatrix = [Existing Rotation/Scale] * [New Translation] ?
211- // No, we just want to adjust Translation.
212-
213- // Let's calculate the required translation.
214- // ViewPoint = Matrix * WorldPoint
215- // We want ViewPoint = ScreenCenter.
216-
217- // If we reconstruct the matrix:
218- // NewMatrix = OldMatrix without Translation * NewTranslation?
219- // This clears rotation if we aren't careful.
220-
221- // Better approach: Calculate the difference.
222- var currentViewPoint = viewModel . NavigationModel . TotalMatrix . MapPoint ( worldPoint ) ;
186+ // Calculate where this world point currently appears on screen
187+ var currentViewPoint = viewModel . NavigationModel . ViewMatrix . MapPoint ( worldPoint ) ;
223188 var screenCenter = new SKPoint ( viewModel . CanvasSize . Width / 2 , viewModel . CanvasSize . Height / 2 ) ;
224189
190+ // Calculate the delta to center it
225191 var delta = screenCenter - currentViewPoint ;
226192
227- // Translate the view by delta
193+ // Apply translation to view matrix
228194 var translation = SKMatrix . CreateTranslation ( delta . X , delta . Y ) ;
229- // Update UserMatrix using PostConcat to accumulate transformations (Legacy style)
230- viewModel . NavigationModel . UserMatrix = viewModel . NavigationModel . UserMatrix . PostConcat ( translation ) ;
195+ viewModel . NavigationModel . ViewMatrix = viewModel . NavigationModel . ViewMatrix . PostConcat ( translation ) ;
231196
232197 MessageBus ? . SendMessage ( new CanvasInvalidateMessage ( ) ) ;
233198 }
0 commit comments