@@ -34,6 +34,14 @@ export class Minimap {
3434 this . _handleMouseMove = this . _onMouseMove . bind ( this ) ;
3535 this . _handleMouseUp = this . _onMouseUp . bind ( this ) ;
3636 this . _handleClick = this . _onClick . bind ( this ) ;
37+
38+ // Container drag state
39+ this . _isContainerDragging = false ;
40+ this . _containerDragOffset = null ;
41+ this . _dragBar = null ;
42+ this . _handleDragBarDown = null ;
43+ this . _cbContainerMove = null ;
44+ this . _cbContainerUp = null ;
3745 }
3846
3947 init ( container , domains ) {
@@ -66,6 +74,28 @@ export class Minimap {
6674 window . addEventListener ( 'mousemove' , this . _handleMouseMove ) ;
6775 window . addEventListener ( 'mouseup' , this . _handleMouseUp ) ;
6876
77+ // Prevent ALL mouse events on the minimap from propagating to the map canvas below
78+ container . addEventListener ( 'mousedown' , ( e ) => e . stopPropagation ( ) ) ;
79+ container . addEventListener ( 'mousemove' , ( e ) => e . stopPropagation ( ) ) ;
80+ container . addEventListener ( 'mouseup' , ( e ) => e . stopPropagation ( ) ) ;
81+ container . addEventListener ( 'click' , ( e ) => e . stopPropagation ( ) ) ;
82+ container . addEventListener ( 'wheel' , ( e ) => e . stopPropagation ( ) ) ;
83+ container . addEventListener ( 'pointerdown' , ( e ) => e . stopPropagation ( ) ) ;
84+
85+ // Drag bar for repositioning the minimap container
86+ this . _dragBar = document . createElement ( 'div' ) ;
87+ this . _dragBar . style . cssText =
88+ 'position:absolute;top:0;left:0;right:0;height:16px;cursor:grab;z-index:3;' +
89+ 'background:linear-gradient(to bottom, rgba(0,105,62,0.12), transparent);' ;
90+ // Grip pill visual indicator
91+ const grip = document . createElement ( 'div' ) ;
92+ grip . style . cssText =
93+ 'width:32px;height:4px;margin:6px auto 0;border-radius:2px;' +
94+ 'background:rgba(0,105,62,0.35);pointer-events:none;' ;
95+ this . _dragBar . appendChild ( grip ) ;
96+ container . appendChild ( this . _dragBar ) ;
97+ this . _initContainerDrag ( ) ;
98+
6999 this . render ( ) ;
70100 }
71101
@@ -348,6 +378,62 @@ export class Minimap {
348378 ctx . strokeRect ( x , y , vw , vh ) ;
349379 }
350380
381+ _initContainerDrag ( ) {
382+ this . _handleDragBarDown = ( e ) => {
383+ e . preventDefault ( ) ;
384+ e . stopPropagation ( ) ;
385+ this . _isContainerDragging = true ;
386+ const rect = this . container . getBoundingClientRect ( ) ;
387+ this . _containerDragOffset = {
388+ x : e . clientX - rect . left ,
389+ y : e . clientY - rect . top ,
390+ } ;
391+ this . _dragBar . style . cursor = 'grabbing' ;
392+ // Capture pointer so we receive events even outside the element
393+ if ( e . pointerId !== undefined ) {
394+ this . _dragBar . setPointerCapture ( e . pointerId ) ;
395+ }
396+ } ;
397+
398+ this . _cbContainerMove = ( e ) => {
399+ if ( ! this . _isContainerDragging ) return ;
400+ const parent = this . container . parentElement ;
401+ if ( ! parent ) return ;
402+ const parentRect = parent . getBoundingClientRect ( ) ;
403+ const contW = this . container . offsetWidth ;
404+ const contH = this . container . offsetHeight ;
405+
406+ let newLeft = e . clientX - parentRect . left - this . _containerDragOffset . x ;
407+ let newTop = e . clientY - parentRect . top - this . _containerDragOffset . y ;
408+
409+ // Clamp within parent bounds
410+ newLeft = Math . max ( 0 , Math . min ( parentRect . width - contW , newLeft ) ) ;
411+ newTop = Math . max ( 0 , Math . min ( parentRect . height - contH , newTop ) ) ;
412+
413+ this . container . style . left = newLeft + 'px' ;
414+ this . container . style . top = newTop + 'px' ;
415+ // Clear bottom/right anchoring so left/top take effect
416+ this . container . style . right = 'auto' ;
417+ this . container . style . bottom = 'auto' ;
418+ } ;
419+
420+ this . _cbContainerUp = ( e ) => {
421+ if ( this . _isContainerDragging ) {
422+ this . _isContainerDragging = false ;
423+ this . _containerDragOffset = null ;
424+ this . _dragBar . style . cursor = 'grab' ;
425+ if ( e . pointerId !== undefined ) {
426+ try { this . _dragBar . releasePointerCapture ( e . pointerId ) ; } catch ( _ ) { /* already released */ }
427+ }
428+ }
429+ } ;
430+
431+ // Use pointer events for capture support, with mouse fallback
432+ this . _dragBar . addEventListener ( 'pointerdown' , this . _handleDragBarDown ) ;
433+ window . addEventListener ( 'pointermove' , this . _cbContainerMove ) ;
434+ window . addEventListener ( 'pointerup' , this . _cbContainerUp ) ;
435+ }
436+
351437 _onResizeStart ( e ) {
352438 e . preventDefault ( ) ;
353439 e . stopPropagation ( ) ;
@@ -394,6 +480,23 @@ export class Minimap {
394480 }
395481
396482 destroy ( ) {
483+ // Clean up drag bar
484+ if ( this . _dragBar ) {
485+ if ( this . _handleDragBarDown ) {
486+ this . _dragBar . removeEventListener ( 'pointerdown' , this . _handleDragBarDown ) ;
487+ }
488+ this . _dragBar . remove ( ) ;
489+ this . _dragBar = null ;
490+ }
491+ if ( this . _cbContainerMove ) {
492+ window . removeEventListener ( 'pointermove' , this . _cbContainerMove ) ;
493+ this . _cbContainerMove = null ;
494+ }
495+ if ( this . _cbContainerUp ) {
496+ window . removeEventListener ( 'pointerup' , this . _cbContainerUp ) ;
497+ this . _cbContainerUp = null ;
498+ }
499+
397500 if ( this . _resizeHandle ) {
398501 if ( this . _handleResizeStart ) {
399502 this . _resizeHandle . removeEventListener ( 'mousedown' , this . _handleResizeStart ) ;
0 commit comments