Altering cursor to piece copy is interesting idea. Even though I just don't like this artificial drag-n-drop idea, still for this project it seems to be better, however in the above diagram I can't see dragged piece (Chrome on linux) - it just shows image placeholders in the cells I'm dragging over.hgm wrote: ↑Fri Dec 04, 2020 4:09 pm I think I have something now that works purely with background images, and doesn't rely on browser default behavior for dragging. It works by explicitly setting the style.cursor attribute of the board <table> element to the dragged piece, by copying the cell's back-ground image there (plus some coordinates for shifting the center of the image to the pointer location, rather than the upper-left corner), and then deleting that background.
The tricky thing is to undo that when the drag ends. Problem is that not every mousedown can be a drag start. (And I cannot use ondragstart, because when the pieces are background, there is nothing in the cells to drag. So it must happen on mousedown.) In click-click moving some clicks are 'to-clicks'. And this cannot be determined in advance, because the Diagram supports re-selection: if you have selected a piece, but then click another piece that is not a highlighted destination, it assumes that you want to move (and thus drag) that piece instead. So a 'from-click' is not guaranteed to be followed by a 'to-click', it can be a new 'from-click' as well.
And if every click prepares dragging, you would have to undo it on the mouseup of a to-click as well. That is OK for the cursor (which can always be the default if no button is pressed), but when you put back the piece you deleted, it would overwrite the piece that moved there in case of a to-click. I solved that by testing at the end of the mousdown handler whether the click left a piece selected; clicks that finish a move wouldn't do that, and handling the move would in that case have put the correct piece in that square. In other cases undoing the drag start is left to the mouseup handler, when in occurs on the same square as the mousedown.
I have the following code now (working in the diagram above):
It is still a bit troublesome on promotions, where the to-click does not finish the move, but where you have to select the promotion piece from the table first.Code: Select all
var downX; var downY; var noMouse = 0; var down = 0; var drag, draggedPiece; function Down(bnr, x, y, ev) { if(noMouse) return; SwitchDiag(bnr); if(ev.button == 2) { ev.preventDefault(); RightClick(x, y); return; } downX = x; downY = y; down = 1; var off = sqrSize >> 1; drag = document.getElementById(bnr + 'y' + y + 'y' + x); draggedPiece = drag.style.backgroundImage; curCell = ""; Click(x, y); if(xx < 0) drag = null; else { // attach piece to cursor if this click didn't finish move document.getElementById('board' + bnr).style.cursor = draggedPiece + ' ' + off + ' ' + off +', auto'; drag.style.backgroundImage = ''; } } function Up(bnr, x, y) { // catches up-click on empty square if(noMouse) return; SwitchDiag(bnr); if(drag) { document.getElementById('board' + bnr).style.cursor = 'default'; if(down && x == downX && y == downY) drag.style.backgroundImage = draggedPiece; drag = null; } if(x == downX && y == downY) return; // ignore up on static click Click(x, y); // on other square up counts as new click event }
re: not every mouse down is treated to be a dragstart
- event object has event.pageX and event.pageY attributes, so maybe checking for change of either of them might be a condition for actual drag start because drag start is literally mousedown event followed be cursor coordinate change.
Overall thoughts on this issue:
While having multiple chess variants sharing diagram with the same functionality it seems logical to separate UI code into a standalone library, however I see that UI manipulation code is heavily embedded into the variant itself so I clearly see the reason why you don't want to do that)
A fun fact I've realized during chess board libraries research I made before creating my own - seems like none of existing libraries contain all the possible features, e.g. fancy svg arrows and square marks/marks to show legal moves is done separately (like on lichess), drag-n-drop itself in serious chessboard libraries seems to always override default browser behavior most likely due to browser compatibility issues.
So I think you should keep your current idea of faking drag-n-drop and using background images.
After correct recognition of equivalent of drag start (mouse down + cursor coord change) your idea with cloning image to stick to mouse pointer seems to be the best possible assuming particular implementation.

