From 71c3cf724b1ee1dfd775e74b1ec575d2d3220220 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 11 Nov 2025 16:12:10 +0000 Subject: [PATCH] feat: Add touch event support for drag-and-drop on mobile devices - Add @ontouchstart, @ontouchmove, and @ontouchend event handlers to overlay items - Add touch event handlers to diagram-area container - Implement OnTouchStart, OnTouchMove, and OnTouchEnd methods - Use touch.ClientX/ClientY for position tracking (same logic as mouse events) - Add touch-action: none CSS to prevent scrolling during drag - Add preventDefault to prevent default touch behaviors in edit mode Touch events work alongside mouse events, so drag-and-drop now works on: - Desktop (mouse) - iPad/iOS (touch) - Android tablets/phones (touch) - Touchscreen laptops (both) --- src/Frontend/VanDaemon.Web/Pages/Index.razor | 60 +++++++++++++++++++- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Frontend/VanDaemon.Web/Pages/Index.razor b/src/Frontend/VanDaemon.Web/Pages/Index.razor index 349dd43..84e46ac 100644 --- a/src/Frontend/VanDaemon.Web/Pages/Index.razor +++ b/src/Frontend/VanDaemon.Web/Pages/Index.razor @@ -87,7 +87,11 @@
+ @onmouseup="OnMouseUp" + @ontouchmove="OnTouchMove" + @ontouchend="OnTouchEnd" + @ontouchmove:preventDefault="isEditMode" + @ontouchend:preventDefault="isEditMode">
@if (!string.IsNullOrEmpty(backgroundImage)) { @@ -106,10 +110,12 @@ @foreach (var overlay in overlays) {
+ @onmousedown:preventDefault="isEditMode" + @ontouchstart="(e) => OnTouchStart(e, overlay)" + @ontouchstart:preventDefault="isEditMode"> @if (overlay.Type == OverlayType.Tank) { @@ -440,6 +446,54 @@ } } + // Touch event handlers for mobile devices + private void OnTouchStart(TouchEventArgs e, OverlayItem overlay) + { + if (isEditMode && e.Touches.Length > 0) + { + draggedOverlay = overlay; + var touch = e.Touches[0]; + dragStartX = touch.ClientX; + dragStartY = touch.ClientY; + } + } + + private async Task OnTouchMove(TouchEventArgs e) + { + if (draggedOverlay != null && isEditMode && e.Touches.Length > 0) + { + var touch = e.Touches[0]; + + // Calculate the change in touch position + double deltaX = touch.ClientX - dragStartX; + double deltaY = touch.ClientY - dragStartY; + + // Convert pixel delta to percentage + double deltaXPercent = (deltaX / containerWidth) * 100; + double deltaYPercent = (deltaY / containerHeight) * 100; + + // Update overlay position + draggedOverlay.X = Math.Max(0, Math.Min(100, draggedOverlay.X + deltaXPercent)); + draggedOverlay.Y = Math.Max(0, Math.Min(100, draggedOverlay.Y + deltaYPercent)); + + // Update drag start position for next move + dragStartX = touch.ClientX; + dragStartY = touch.ClientY; + + await InvokeAsync(StateHasChanged); + } + } + + private async Task OnTouchEnd(TouchEventArgs e) + { + if (draggedOverlay != null && isEditMode) + { + // Save position to backend + await SaveOverlayPosition(draggedOverlay); + draggedOverlay = null; + } + } + private async Task OnControlToggle(OverlayItem overlay, bool value) { try