From 249993293db3218abf9cfa7a88fd9fd2dd5e1101 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 29 Dec 2022 13:49:07 +0100 Subject: [PATCH] Rewrite how the chessboard works. Lots of changes; the board is now completely responsive, with everything being positioned in terms of 12.5% increments relative to the board (and the grid being an actual CSS grid). Animated pieces are now simply being moved, instead of making a separate piece for the animation and deleting it later. It's not much smaller and I'm not sure if it's actually faster, but it should make the problems of phantom pieces somewhat smaller. It should certainly fix the off-grid pieces showing up. --- www/css/chessboard-0.3.0.css | 23 +- www/css/remoteglot.css | 2 +- www/js/chessboard-0.3.0.js | 463 +++++++++++++++-------------------- www/js/remoteglot.js | 29 ++- 4 files changed, 219 insertions(+), 298 deletions(-) diff --git a/www/css/chessboard-0.3.0.css b/www/css/chessboard-0.3.0.css index bf1a53a..557f283 100644 --- a/www/css/chessboard-0.3.0.css +++ b/www/css/chessboard-0.3.0.css @@ -9,23 +9,19 @@ * Date: 10 Aug 2013 */ -/* clearfix */ -.clearfix-7da63 { - clear: both; -} - /* board */ .board-b72b1 { - border: 2px solid #404040; - -moz-box-sizing: content-box; - box-sizing: content-box; + outline: 2px solid #404040; + display: grid; + grid-template-rows: repeat(8, 12.5%); + grid-template-columns: repeat(8, 12.5%); + grid-gap: 0px; + width: 100%; + aspect-ratio: 1; } /* square */ .square-55d63 { - float: left; - position: relative; - /* disable any native browser highlighting */ user-select: none; } @@ -48,7 +44,7 @@ } /* notation */ -.notation-322f9 { +.alpha-d2270, .numeric-fc462 { cursor: default; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; @@ -65,4 +61,7 @@ .piece-417db { transform: translate(0,0); /* Force a new stacking context for SVG pieces. */ + position: absolute; + width: 12.5%; + height: 12.5%; } diff --git a/www/css/remoteglot.css b/www/css/remoteglot.css index 2b113af..670f9ce 100644 --- a/www/css/remoteglot.css +++ b/www/css/remoteglot.css @@ -105,7 +105,7 @@ p { } #bottompanel { display: block; - width: 100%; + width: calc(100% + 4px); font-size: smaller; margin-top: 0.5em; margin-bottom: 0; diff --git a/www/js/chessboard-0.3.0.js b/www/js/chessboard-0.3.0.js index 26c0217..5d257a0 100644 --- a/www/js/chessboard-0.3.0.js +++ b/www/js/chessboard-0.3.0.js @@ -207,13 +207,11 @@ var CSS = { alpha: 'alpha-d2270', board: 'board-b72b1', chessboard: 'chessboard-63f37', - clearfix: 'clearfix-7da63', highlight1: 'highlight1-32417', highlight2: 'highlight2-9c5d2', notation: 'notation-322f9', numeric: 'numeric-fc462', piece: 'piece-417db', - row: 'row-5277c', square: 'square-55d63' }; var CSSColor = {}; @@ -236,16 +234,13 @@ var widget = {}; // Stateful //------------------------------------------------------------------------------ -var BOARD_BORDER_SIZE = 2, - CURRENT_ORIENTATION = 'white', +var CURRENT_ORIENTATION = 'white', CURRENT_POSITION = {}, - SQUARE_SIZE, DRAGGED_PIECE, DRAGGED_PIECE_LOCATION, DRAGGED_PIECE_SOURCE, DRAGGING_A_PIECE = false, - SQUARE_ELS_IDS = {}, - SQUARE_ELS_OFFSETS; + PIECE_ON_SQUARE = {}; //------------------------------------------------------------------------------ // JS Util Functions @@ -424,44 +419,6 @@ function expandConfig() { return true; } -//------------------------------------------------------------------------------ -// DOM Misc -//------------------------------------------------------------------------------ - -// calculates square size based on the width of the container -// got a little CSS black magic here, so let me explain: -// get the width of the container element (could be anything), reduce by 1 for -// fudge factor, and then keep reducing until we find an exact mod 8 for -// our square size -function calculateSquareSize() { - var containerWidth = parseInt(getComputedStyle(containerEl).width, 10); - - // defensive, prevent infinite loop - if (! containerWidth || containerWidth <= 0) { - return 0; - } - - // pad one pixel - var boardWidth = containerWidth - 1; - - while (boardWidth % 8 !== 0 && boardWidth > 0) { - boardWidth--; - } - - return (boardWidth / 8); -} - -// create random IDs for elements -function createElIds() { - // squares on the board - for (var i = 0; i < COLUMNS.length; i++) { - for (var j = 1; j <= 8; j++) { - var square = COLUMNS[i] + j; - SQUARE_ELS_IDS[square] = square + '-' + createId(); - } - } -} - //------------------------------------------------------------------------------ // Markup Building //------------------------------------------------------------------------------ @@ -476,22 +433,6 @@ function buildBoardContainer() { return html; } -/* -var buildSquare = function(color, size, id) { - var html = '
'; - - if (cfg.showNotation === true) { - - } - - html += '
'; - - return html; -}; -*/ - function buildBoard(orientation) { if (orientation !== 'black') { orientation = 'white'; @@ -509,27 +450,29 @@ function buildBoard(orientation) { var squareColor = 'white'; for (var i = 0; i < 8; i++) { - html += '
'; for (var j = 0; j < 8; j++) { var square = alpha[j] + row; html += '
'; if (cfg.showNotation === true) { // alpha notation if ((orientation === 'white' && row === 1) || (orientation === 'black' && row === 8)) { - html += '
' + + let bottom = 'calc(' + (12.5 * (7-i)) + '% + 1px)'; + let right = 'calc(' + (12.5 * (7-j)) + '% + 3px)'; + html += '
' + alpha[j] + '
'; } // numeric notation if (j === 0) { - html += '
' + + let top = 'calc(' + (12.5 * i) + '% + 2px)'; + let left = 'calc(' + (12.5 * j) + '% + 2px)'; + html += '
' + row + '
'; } } @@ -538,7 +481,6 @@ function buildBoard(orientation) { squareColor = (squareColor === 'white' ? 'black' : 'white'); } - html += '
'; squareColor = (squareColor === 'white' ? 'black' : 'white'); @@ -570,19 +512,12 @@ function buildPieceImgSrc(piece) { /** * @param {!string} piece * @param {boolean=} hidden - * @param {!string=} id */ -function buildPiece(piece, hidden, id) { +function buildPiece(piece, hidden) { let img = document.createElement('img'); img.src = buildPieceImgSrc(piece); - if (id && typeof id === 'string') { - img.setAttribute('id', id); - } img.setAttribute('alt', ''); img.classList.add(CSS.piece); - img.setAttribute('data-piece', piece); - img.style.width = SQUARE_SIZE + 'px'; - img.style.height = SQUARE_SIZE + 'px'; if (hidden === true) { img.style.display = 'none'; } @@ -602,55 +537,37 @@ function offset(el) { // From https://youmightnotneedjquery.com/. }; } -function animateSquareToSquare(moved_pieces, completeFn) { - let pieces = []; - for (const {source, destination, piece} of moved_pieces) { - // get information about the source and destination squares - let srcSquareEl = document.getElementById(SQUARE_ELS_IDS[source]); - let srcSquarePosition = offset(srcSquareEl); - let destSquareEl = document.getElementById(SQUARE_ELS_IDS[destination]); - let destSquarePosition = offset(destSquareEl); - - // create the animated piece and absolutely position it - // over the source square - let animatedPieceId = createId(); - document.body.append(buildPiece(piece, true, animatedPieceId)); - let animatedPieceEl = document.getElementById(animatedPieceId); - animatedPieceEl.style.display = null; - animatedPieceEl.style.position = 'absolute'; - animatedPieceEl.style.top = srcSquarePosition.top + 'px'; - animatedPieceEl.style.left = srcSquarePosition.left + 'px'; - - // remove original piece(s) from source square - // TODO: multiple pieces should never really happen, but it will if we are moving - // while another animation still isn't done - srcSquareEl.querySelectorAll('.' + CSS.piece).forEach((piece) => piece.remove()); - - // on complete - let complete = function() { - // add the "real" piece to the destination square - destSquareEl.append(buildPiece(piece)); - - // remove the animated piece - animatedPieceEl.remove(); - - // run complete function - if (typeof completeFn === 'function') { - completeFn(); - } - }; +function findSquarePosition(square) { + let s1 = square.split(''); + var s1x = COLUMNS.indexOf(s1[0]); + var s1y = parseInt(s1[1], 10) - 1; + if (CURRENT_ORIENTATION === 'white') { + s1y = 7 - s1y; + } + return { + top: (s1y * 12.5) + '%', + left: (s1x * 12.5) + '%', + }; +} + +function animateSquareToSquare(move_pieces, complete) { + for (const [piece, destination] of move_pieces) { + // Move it to the end of the stack, which changes the implicit z-index + // so that it will go on top of any pieces it's replacing. + piece.remove(); + boardEl.appendChild(piece); // animate the piece to the destination square - animatedPieceEl.addEventListener('transitionend', complete, {once: true}); - pieces.push([animatedPieceEl, destSquarePosition]); + piece.addEventListener('transitionend', complete, {once: true}); } requestAnimationFrame(() => { - for (let [animatedPieceEl, destSquarePosition] of pieces) { - animatedPieceEl.style.transitionProperty = 'top, left'; - animatedPieceEl.style.transitionDuration = cfg.moveSpeed + 'ms'; - animatedPieceEl.style.top = destSquarePosition.top + 'px'; - animatedPieceEl.style.left = destSquarePosition.left + 'px'; - } + for (const [piece, destination] of move_pieces) { + let destSquarePosition = findSquarePosition(destination); + piece.style.transitionProperty = 'top, left'; + piece.style.transitionDuration = cfg.moveSpeed + 'ms'; + piece.style.top = destSquarePosition.top; + piece.style.left = destSquarePosition.left; + } }); } @@ -686,10 +603,65 @@ function fadeOut(pieces, onFinish) { // execute an array of animations function doAnimations(a, oldPos, newPos) { + let fadeout_pieces = []; + let fadein_pieces = []; + let move_pieces = []; + let squares_to_clear = []; + let squares_to_fill = {}; + let removed_pieces = []; + + for (var i = 0; i < a.length; i++) { + // clear a piece + if (a[i].type === 'clear') { + let square = a[i].square; + let piece = PIECE_ON_SQUARE[square]; + if (piece) { + fadeout_pieces.push(piece); + squares_to_clear.push(square); + removed_pieces.push(piece); + } + } + + // add a piece + if (a[i].type === 'add') { + let square = a[i].square; + let pos = findSquarePosition(square); + let piece = buildPiece(a[i].piece, true); + piece.style.left = pos.left; + piece.style.top = pos.top; + boardEl.append(piece); + squares_to_fill[square] = piece; + fadein_pieces.push(piece); + } + + // move a piece + if (a[i].type === 'move') { + let piece = PIECE_ON_SQUARE[a[i].source]; + move_pieces.push([piece, a[i].destination]); + squares_to_clear.push(a[i].source); + squares_to_fill[a[i].destination] = piece; + + // This is O(n²), but OK. + let replaced_piece = PIECE_ON_SQUARE[a[i].destination]; + if (replaced_piece && !a.some(e => e.type === 'move' && e.source === a[i].destination)) { + removed_pieces.push(replaced_piece); + } + } + } + + for (const square of squares_to_clear) { + delete PIECE_ON_SQUARE[square]; + } + for (const [square, piece] of Object.entries(squares_to_fill)) { + PIECE_ON_SQUARE[square] = piece; + piece.setAttribute('data-square', square); + } + var numFinished = 0; function onFinish(e) { if (e && e.target) { e.target.transitionProperty = null; + e.target.transitionDuration = null; } numFinished++; @@ -697,7 +669,9 @@ function doAnimations(a, oldPos, newPos) { // exit if all the animations aren't finished if (numFinished !== a.length) return; - drawPositionInstant(); + for (let piece of removed_pieces) { + piece.remove(); + } // run their onMoveEnd function if (cfg.hasOwnProperty('onMoveEnd') === true && @@ -707,42 +681,14 @@ function doAnimations(a, oldPos, newPos) { } requestAnimationFrame(() => { // Firefox workaround. - let fadeout_pieces = []; - let fadein_pieces = []; - let moved_pieces = []; - - for (var i = 0; i < a.length; i++) { - // clear a piece - if (a[i].type === 'clear') { - document.getElementById(SQUARE_ELS_IDS[a[i].square]).querySelectorAll('.' + CSS.piece).forEach( - (piece) => fadeout_pieces.push(piece) - ); - } - - // add a piece - if (a[i].type === 'add') { - let square = document.getElementById(SQUARE_ELS_IDS[a[i].square]); - square.append(buildPiece(a[i].piece, true)); - let piece = square.querySelector('.' + CSS.piece); - fadein_pieces.push(piece); - } - - // move a piece - if (a[i].type === 'move') { - moved_pieces.push(a[i]); - } - } - - // TODO: Batch moves as well, not just fade in/out. - // (We batch them because requestAnimationFrame seemingly costs real time.) if (fadeout_pieces.length > 0) { fadeOut(fadeout_pieces, onFinish); } if (fadein_pieces.length > 0) { fadeIn(fadein_pieces, onFinish); } - if (moved_pieces.length > 0) { - animateSquareToSquare(moved_pieces, onFinish); + if (move_pieces.length > 0) { + animateSquareToSquare(move_pieces, onFinish); } }); } @@ -867,10 +813,14 @@ function drawPositionInstant() { boardEl.querySelectorAll('.' + CSS.piece).forEach((piece) => piece.remove()); // add the pieces - for (var i in CURRENT_POSITION) { - if (CURRENT_POSITION.hasOwnProperty(i) !== true) continue; - - document.getElementById(SQUARE_ELS_IDS[i]).append(buildPiece(CURRENT_POSITION[i])); + for (const [square, piece] of Object.entries(CURRENT_POSITION)) { + let pos = findSquarePosition(square); + let pieceEl = buildPiece(piece); + pieceEl.style.left = pos.left; + pieceEl.style.top = pos.top; + pieceEl.setAttribute('data-square', square); + boardEl.append(pieceEl); + PIECE_ON_SQUARE[square] = pieceEl; } } @@ -917,31 +867,6 @@ function setCurrentPosition(position) { CURRENT_POSITION = position; } -function isXYOnSquare(x, y) { - for (var i in SQUARE_ELS_OFFSETS) { - if (SQUARE_ELS_OFFSETS.hasOwnProperty(i) !== true) continue; - - var s = SQUARE_ELS_OFFSETS[i]; - if (x >= s.left && x < s.left + SQUARE_SIZE && - y >= s.top && y < s.top + SQUARE_SIZE) { - return i; - } - } - - return 'offboard'; -} - -// records the XY coords of every square into memory -function captureSquareOffsets() { - SQUARE_ELS_OFFSETS = {}; - - for (var i in SQUARE_ELS_IDS) { - if (SQUARE_ELS_IDS.hasOwnProperty(i) !== true) continue; - - SQUARE_ELS_OFFSETS[i] = offset(document.getElementById(SQUARE_ELS_IDS[i])); - } -} - function removeSquareHighlights() { boardEl.querySelectorAll('.' + CSS.square).forEach((piece) => { piece.classList.remove(CSS.highlight1); @@ -955,7 +880,6 @@ function snapbackDraggedPiece() { // animation complete function complete() { drawPositionInstant(); - draggedPieceEl.style.display = 'none'; // run their onSnapbackEnd function if (cfg.hasOwnProperty('onSnapbackEnd') === true && @@ -966,16 +890,15 @@ function snapbackDraggedPiece() { } // get source square position - var sourceSquarePosition = - offset(document.getElementById(SQUARE_ELS_IDS[DRAGGED_PIECE_SOURCE])); + var sourceSquarePosition = findSquarePosition(DRAGGED_PIECE_SOURCE); // animate the piece to the target square - draggedPieceEl.addEventListener('transitionend', complete, {once: true}); + DRAGGED_PIECE.addEventListener('transitionend', complete, {once: true}); requestAnimationFrame(() => { - draggedPieceEl.style.transitionProperty = 'top, left'; - draggedPieceEl.style.transitionDuration = cfg.snapbackSpeed + 'ms'; - draggedPieceEl.style.top = sourceSquarePosition.top + 'px'; - draggedPieceEl.style.left = sourceSquarePosition.left + 'px'; + DRAGGED_PIECE.style.transitionProperty = 'top, left'; + DRAGGED_PIECE.style.transitionDuration = cfg.snapbackSpeed + 'ms'; + DRAGGED_PIECE.style.top = sourceSquarePosition.top; + DRAGGED_PIECE.style.left = sourceSquarePosition.left; }); // set state @@ -984,20 +907,32 @@ function snapbackDraggedPiece() { function dropDraggedPieceOnSquare(square) { removeSquareHighlights(); + DRAGGING_A_PIECE = false; + + if (DRAGGED_PIECE_SOURCE === square) { + // Nothing to do, but call onSnapEnd anyway + if (cfg.hasOwnProperty('onSnapEnd') === true && typeof cfg.onSnapEnd === 'function') { + cfg.onSnapEnd(DRAGGED_PIECE_SOURCE, square, DRAGGED_PIECE); + } + return; + } // update position var newPosition = deepCopy(CURRENT_POSITION); + newPosition[square] = newPosition[DRAGGED_PIECE_SOURCE]; delete newPosition[DRAGGED_PIECE_SOURCE]; - newPosition[square] = DRAGGED_PIECE; setCurrentPosition(newPosition); + delete PIECE_ON_SQUARE[DRAGGED_PIECE_SOURCE]; + PIECE_ON_SQUARE[square] = DRAGGED_PIECE; + DRAGGED_PIECE.setAttribute('data-square', square); + // get target square information - var targetSquarePosition = offset(document.getElementById(SQUARE_ELS_IDS[square])); + var targetSquarePosition = findSquarePosition(square); // animation complete var complete = function() { drawPositionInstant(); - draggedPieceEl.style.display = 'none'; // execute their onSnapEnd function if (cfg.hasOwnProperty('onSnapEnd') === true && @@ -1009,16 +944,13 @@ function dropDraggedPieceOnSquare(square) { }; // snap the piece to the target square - draggedPieceEl.addEventListener('transitionend', complete, {once: true}); + DRAGGED_PIECE.addEventListener('transitionend', complete, {once: true}); requestAnimationFrame(() => { - draggedPieceEl.style.transitionProperty = 'top, left'; - draggedPieceEl.style.transitionDuration = cfg.snapSpeed + 'ms'; - draggedPieceEl.style.top = targetSquarePosition.top + 'px'; - draggedPieceEl.style.left = targetSquarePosition.left + 'px'; + DRAGGED_PIECE.style.transitionProperty = 'top, left'; + DRAGGED_PIECE.style.transitionDuration = cfg.snapSpeed + 'ms'; + DRAGGED_PIECE.style.top = targetSquarePosition.top; + DRAGGED_PIECE.style.left = targetSquarePosition.left; }); - - // set state - DRAGGING_A_PIECE = false; } function beginDraggingPiece(source, piece, x, y) { @@ -1032,46 +964,62 @@ function beginDraggingPiece(source, piece, x, y) { // set state DRAGGING_A_PIECE = true; - DRAGGED_PIECE = piece; + DRAGGED_PIECE = PIECE_ON_SQUARE[source]; DRAGGED_PIECE_SOURCE = source; DRAGGED_PIECE_LOCATION = source; + DRAGGED_PIECE.style.transitionProperty = null; + DRAGGED_PIECE.style.transitionDuration = null; - // capture the x, y coords of all squares in memory - captureSquareOffsets(); + // Move it to the end of the stack, which changes the implicit z-index + // so that it will go on top of any pieces it's replacing. + DRAGGED_PIECE.remove(); + boardEl.appendChild(DRAGGED_PIECE); - // create the dragged piece - draggedPieceEl.setAttribute('src', buildPieceImgSrc(piece)); - draggedPieceEl.style.display = null; - draggedPieceEl.style.position = 'absolute'; - draggedPieceEl.style.left = (x - (SQUARE_SIZE / 2)) + 'px'; - draggedPieceEl.style.top = (y - (SQUARE_SIZE / 2)) + 'px'; - - // highlight the source square and hide the piece - let square = document.getElementById(SQUARE_ELS_IDS[source]); + // highlight the source square + let square = document.querySelector('.' + CSS.square + '[data-square="' + source + '"]'); square.classList.add(CSS.highlight1); - square.querySelector('.' + CSS.piece).style.display = 'none'; } -function updateDraggedPiece(x, y) { - // put the dragged piece over the mouse cursor - draggedPieceEl.style.left = (x - (SQUARE_SIZE / 2)) + 'px'; - draggedPieceEl.style.top = (y - (SQUARE_SIZE / 2)) + 'px'; +function findSquareFromEvent(pageX, pageY) { + let o = offset(boardEl); + let x = pageX - o.left; + let y = pageY - o.top; + + let position = { + x: x, + y: y, + left: Math.floor(x * 8 / boardEl.getBoundingClientRect().width), + top: Math.floor(y * 8 / boardEl.getBoundingClientRect().width) + }; + if (CURRENT_ORIENTATION === 'white') { + position.top = 7 - position.top; + } + if (position.left >= 0 && position.left < 8 && position.top >= 0 && position.top < 8) { + position.square = COLUMNS[position.left] + (position.top + 1); + } else { + position.square = 'offboard'; + } + return position; +} - // get location - var location = isXYOnSquare(x, y); +function updateDraggedPiece(position) { + // put the dragged piece over the mouse cursor + DRAGGED_PIECE.style.left = 'calc(' + position.x + 'px - 6.25%)'; + DRAGGED_PIECE.style.top = 'calc(' + position.y + 'px - 6.25%)'; // do nothing if the location has not changed - if (location === DRAGGED_PIECE_LOCATION) return; + if (position === DRAGGED_PIECE_LOCATION) return; // remove highlight from previous square - if (validSquare(DRAGGED_PIECE_LOCATION) === true) { - document.getElementById(SQUARE_ELS_IDS[DRAGGED_PIECE_LOCATION]) + if (validSquare(DRAGGED_PIECE_LOCATION)) { + document.querySelector('.' + CSS.square + '[data-square="' + DRAGGED_PIECE_LOCATION + '"]') .classList.remove(CSS.highlight2); } // add highlight to new square - if (validSquare(location) === true) { - document.getElementById(SQUARE_ELS_IDS[location]).classList.add(CSS.highlight2); + if (validSquare(position.square)) { + document.querySelector('.' + CSS.square + '[data-square="' + position.square + '"]') + .classList.add(CSS.highlight2); } // run onDragMove @@ -1082,13 +1030,13 @@ function updateDraggedPiece(x, y) { } // update state - DRAGGED_PIECE_LOCATION = location; + DRAGGED_PIECE_LOCATION = position.square; } function stopDraggedPiece(location) { // determine what the action should be var action = 'drop'; - if (location === 'offboard' && cfg.dropOffBoard === 'snapback') { + if (location.square === 'offboard' && cfg.dropOffBoard === 'snapback') { action = 'snapback'; } @@ -1099,15 +1047,20 @@ function stopDraggedPiece(location) { // source piece was on the board and position is on the board if (validSquare(DRAGGED_PIECE_SOURCE) === true && - validSquare(location) === true) { + validSquare(location.square) === true) { // move the piece delete newPosition[DRAGGED_PIECE_SOURCE]; - newPosition[location] = DRAGGED_PIECE; + newPosition[location.square] = DRAGGED_PIECE; + if (location.square !== DRAGGED_PIECE_SOURCE) { + PIECE_ON_SQUARE[location.square] = PIECE_ON_SQUARE[DRAGGED_PIECE_SOURCE]; + DRAGGED_PIECE.setAttribute('data-square', location.square); + delete PIECE_ON_SQUARE[DRAGGED_PIECE_SOURCE]; + } } var oldPosition = deepCopy(CURRENT_POSITION); - var result = cfg.onDrop(DRAGGED_PIECE_SOURCE, location, DRAGGED_PIECE, + var result = cfg.onDrop(DRAGGED_PIECE_SOURCE, location.square, DRAGGED_PIECE, newPosition, oldPosition, CURRENT_ORIENTATION); if (result === 'snapback') { action = result; @@ -1119,7 +1072,7 @@ function stopDraggedPiece(location) { snapbackDraggedPiece(); } else if (action === 'drop') { - dropDraggedPieceOnSquare(location); + dropDraggedPieceOnSquare(location.square); } } @@ -1278,18 +1231,6 @@ widget.position = function(position, useAnimation) { }; widget.resize = function() { - // calulate the new square size - SQUARE_SIZE = calculateSquareSize(); - - // set board width - boardEl.style.width = (SQUARE_SIZE * 8) + 'px'; - - // set drag piece size - if (draggedPieceEl !== null) { - draggedPieceEl.style.height = SQUARE_SIZE + 'px'; - draggedPieceEl.style.width = SQUARE_SIZE + 'px'; - } - // redraw the board drawBoard(); }; @@ -1308,22 +1249,17 @@ function isTouchDevice() { } function mousedownSquare(e) { - let target = e.target.closest('.' + CSS.square); - if (!target) { - return; - } - - // do nothing if we're not draggable - if (cfg.draggable !== true) return; - - var square = target.getAttribute('data-square'); + let square = e.target.getAttribute('data-square'); // no piece on this square - if (validSquare(square) !== true || + if (!validSquare(square) || CURRENT_POSITION.hasOwnProperty(square) !== true) { return; } + // do nothing if we're not draggable + if (cfg.draggable !== true) return; + beginDraggingPiece(square, CURRENT_POSITION[square], e.pageX, e.pageY); } @@ -1352,7 +1288,7 @@ function mousemoveWindow(e) { // do nothing if we are not dragging a piece if (DRAGGING_A_PIECE !== true) return; - updateDraggedPiece(e.pageX, e.pageY); + updateDraggedPiece(findSquareFromEvent(e.pageX, e.pageY)); } function touchmoveWindow(e) { @@ -1362,18 +1298,15 @@ function touchmoveWindow(e) { // prevent screen from scrolling e.preventDefault(); - updateDraggedPiece(e.changedTouches[0].pageX, - e.changedTouches[0].pageY); + updateDraggedPiece(findSquareFromEvent(e.changedTouches[0].pageX, + e.changedTouches[0].pageY)); } function mouseupWindow(e) { // do nothing if we are not dragging a piece if (DRAGGING_A_PIECE !== true) return; - // get the location - var location = isXYOnSquare(e.pageX, e.pageY); - - stopDraggedPiece(location); + stopDraggedPiece(findSquareFromEvent(e.pageX, e.pageY)); } function touchendWindow(e) { @@ -1384,7 +1317,8 @@ function touchendWindow(e) { var location = isXYOnSquare(e.changedTouches[0].pageX, e.changedTouches[0].pageY); - stopDraggedPiece(location); + stopDraggedPiece(findSquareFromEvent(e.changedTouches[0].pageX, + e.changedTouches[0].pageY)); } function mouseenterSquare(e) { @@ -1484,14 +1418,6 @@ function initDom() { containerEl.innerHTML = buildBoardContainer(); boardEl = containerEl.querySelector('.' + CSS.board); - // create the drag piece - var draggedPieceId = createId(); - document.body.append(buildPiece('wP', true, draggedPieceId)); - draggedPieceEl = document.getElementById(draggedPieceId); - - // get the border size - BOARD_BORDER_SIZE = parseInt(boardEl.style.borderLeftWidth, 10); - // set the size and draw the board widget.resize(); } @@ -1500,9 +1426,6 @@ function init() { if (checkDeps() !== true || expandConfig() !== true) return; - // create unique IDs for all the elements we will create - createElIds(); - initDom(); addEvents(); } diff --git a/www/js/remoteglot.js b/www/js/remoteglot.js index c2bf8ff..f65dd98 100644 --- a/www/js/remoteglot.js +++ b/www/js/remoteglot.js @@ -504,12 +504,11 @@ function position_arrow(arrow) { return; } - let board_width = parseInt(document.querySelector(".board-b72b1").style.width, 10); - let zoom_factor = board_width / 400.0; - let line_width = arrow.line_width * zoom_factor; - let arrow_size = arrow.arrow_size * zoom_factor; + // We always draw as if the board is 400x400, the viewBox will adjust that for us + let line_width = arrow.line_width; + let arrow_size = arrow.arrow_size; - let square_width = board_width / 8; + let square_width = 400 / 8; let from_y, to_y, from_x, to_x; if (board.orientation() === 'black') { from_y = (arrow.from_row + 0.5)*square_width; @@ -526,10 +525,9 @@ function position_arrow(arrow) { let SVG_NS = "http://www.w3.org/2000/svg"; let XHTML_NS = "http://www.w3.org/1999/xhtml"; let svg = document.createElementNS(SVG_NS, "svg"); - svg.setAttribute("width", board_width); - svg.setAttribute("height", board_width); - svg.setAttribute("style", "position: absolute"); - svg.setAttribute("position", "absolute"); + svg.setAttribute("width", "100%"); + svg.setAttribute("height", "100%"); + svg.setAttribute("viewBox", "0 0 400 400"); svg.setAttribute("version", "1.1"); svg.setAttribute("class", "c1"); svg.setAttribute("xmlns", XHTML_NS); @@ -570,8 +568,9 @@ function position_arrow(arrow) { head.setAttribute("fill", arrow.fg_color); svg.appendChild(head); - svg.style.top = '2px'; /* Border for .board-b72b1. */ - svg.style.left = '2px'; + svg.style.position = 'absolute'; + svg.style.top = '0px'; /* Border for .board-b72b1. */ + svg.style.left = '0px'; svg.style.pointerEvents = 'none'; document.getElementById('board').appendChild(svg); arrow.svg = svg; @@ -2077,12 +2076,12 @@ function onDragStart(source, piece, position, orientation) { } function mousedownSquare(e) { - if (!e.target || !e.target.closest('.square-55d63')) { + if (!e.target || !e.target.getAttribute('data-square')) { return; } reverse_dragging_from = null; - let square = e.target.closest('.square-55d63').getAttribute('data-square'); + let square = e.target.getAttribute('data-square'); let pseudogame = new Chess(display_fen); if (pseudogame.game_over() === true) { @@ -2107,13 +2106,13 @@ function mousedownSquare(e) { } function mouseupSquare(e) { - if (!e.target || !e.target.closest('.square-55d63')) { + if (!e.target || !e.target.getAttribute('data-square')) { return; } if (reverse_dragging_from === null) { return; } - let source = e.target.closest('.square-55d63').getAttribute('data-square'); + let source = e.target.getAttribute('data-square'); let target = reverse_dragging_from; reverse_dragging_from = null; if (onDrop(source, target) !== 'snapback') { -- 2.39.2