diff --git a/mibpov.js b/mibpov.js index 490b73c..03475d2 100644 --- a/mibpov.js +++ b/mibpov.js @@ -11,6 +11,18 @@ const GRID_STEP = 10 // be selected by clicking on it const POINT_SELECT_DISTANCE = 25 +// Distance a point has to be dragged after a single click +// before drag-n-drop starts. +// Normally, the user can drag-n-drop a point +// when clickong and dragging it *after* it has already been +// selected; there's no distance requirement. +// But it is also possible to select the point (by clicking +// on it) and dragging it with the same mouse click. But for +// this method, the mouse had to move the distance below +// from the point coordinates (in pixels) before drag-n-drop +// activates. +const ONE_CLICK_DRAG_DROP_DISTANCE = 30 + // Name to display if empty const FALLBACK_NAME = "(no name)" @@ -503,7 +515,7 @@ function clear(context) { if (!context) { context = getDrawContext(); if (!context) { - return false; + return false; } } context.fillStyle = CLEAR_COLOR; @@ -836,7 +848,7 @@ function selectPoint(point) { if (biomeID !== null) { if (point.id === biomeID) { if (elem.selected) { - return [true, true]; + return [true, true]; } elem.selected = "selected"; draw(true); @@ -903,11 +915,17 @@ function getNearestPointFromCanvasPos(x, y, maxDist) { // Whether the mouse is currently pressed let mouseIsDown = false; +// Coordinates of canvas pixel where the mouse was clicked. +// Used for drag-n-drop. +let mouseIsDownStartPos = null; // ID of point being currently dragged by the user // or null if none. let dragDropPointID = null; +// True while drag-n-drop is active +let dragDropActive = false; + /* Move and update the biome point while the user is dragging it */ function updatePointWhenDragged(pointID) { @@ -1019,8 +1037,15 @@ function unhideContent() { /* Canvas events */ voronoiCanvas.onmousemove = function(event) { + if ((!dragDropActive) && (dragDropPointID !== null)) { + if (!dragDropActive && (mouseIsDown && mouseIsDownStartPos !== null)) { + if (getDistance(mouseIsDownStartPos.x, mouseIsDownStartPos.y, event.offsetX, event.offsetY) > ONE_CLICK_DRAG_DROP_DISTANCE) { + dragDropActive = true; + } + } + } // drag-n-drop - if (mouseIsDown) { + if (dragDropActive) { updatePointWhenDragged(dragDropPointID); } updateCoordinateDisplay(event.offsetX, event.offsetY); @@ -1035,6 +1060,7 @@ voronoiCanvas.onmousedown = function(event) { // select point by clicking. // initiate drag-n-drop if already selected. mouseIsDown = true; + mouseIsDownStartPos = { x: event.offsetX, y: event.offsetY }; if (!showPoints) { // Points need to be shown for drag-n-drop to work return; @@ -1043,8 +1069,9 @@ voronoiCanvas.onmousedown = function(event) { if (nearest !== null) { let success, alreadySelected [success, alreadySelected] = selectPoint(nearest); + dragDropPointID = nearest.id; if (alreadySelected) { - dragDropPointID = nearest.id; + dragDropActive = true; } updateDragDropCursorStatus(); } @@ -1053,12 +1080,16 @@ voronoiCanvas.onmouseup = function(event) { // end drag-n-drop updatePointWhenDragged(dragDropPointID); mouseIsDown = false; + mouseIsDownStartPos = null; dragDropPointID = null; + dragDropActive = false; } voronoiCanvas.onmouseleave = function() { // end drag-n-drop mouseIsDown = false; + mouseIsDownStartPos = null; dragDropPointID = null; + dragDropActive = false; coordinateDisplay.innerHTML = " "; }