From 414c9bc196ce51ea26fe7c09406a0843c23bac55 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 7 Sep 2023 18:36:25 +0200 Subject: [PATCH] Animate pieces using the Web Animation API. This seemingly fixes our Chromium power saving issues. Since we don't use all the new fanciness (e.g. fill mode), it ends up being a bit icky, but no more than what we already had. --- www/js/chessboard-0.3.0.js | 142 +++++++++++++++---------------------- 1 file changed, 59 insertions(+), 83 deletions(-) diff --git a/www/js/chessboard-0.3.0.js b/www/js/chessboard-0.3.0.js index f69d0ed..24aa3da 100644 --- a/www/js/chessboard-0.3.0.js +++ b/www/js/chessboard-0.3.0.js @@ -608,77 +608,51 @@ function doAnimations(a, oldPos, newPos) { var numFinished = 0; function onFinish(e, opt_force) { - if (e && e.target) { - e.target.transitionProperty = null; - e.target.transitionDuration = null; - } - - if (opt_force) { - // For whatever reason, the transition didn't seem to actually run - // (and thus, we didn't get an end event). Finish off now. - // (In particular, this seems to happen in Chrome if the tab is - // hidden and left alone for a while.) - if (numFinished == a.length) return; - numFinished = a.length; // Make sure a very delayed later event will be ignored. - } else { - numFinished++; - if (numFinished !== a.length) return; - } - - for (let piece of removed_pieces) { - piece.remove(); - } + if (++numFinished === a.length) { + for (let piece of removed_pieces) { + piece.remove(); + } - // run their onMoveEnd function - if (cfg.hasOwnProperty('onMoveEnd') && - typeof cfg.onMoveEnd === 'function') { - cfg.onMoveEnd(deepCopy(oldPos), deepCopy(newPos)); + // run their onMoveEnd function + if (cfg.hasOwnProperty('onMoveEnd') && + typeof cfg.onMoveEnd === 'function') { + cfg.onMoveEnd(deepCopy(oldPos), deepCopy(newPos)); + } } } - if (fadeout_pieces.length == 0 || fadein_pieces.length > 0 || move_pieces.length > 0) { - requestAnimationFrame(() => { // Firefox workaround. - // Backup in case the transition never runs. - setTimeout(() => onFinish(null, true), - cfg.appearSpeed + cfg.trashSpeed + cfg.moveSpeed + 100); - - fadein_pieces.forEach((piece) => { - piece.style.opacity = 0; - piece.style.display = null; - piece.addEventListener('transitionend', onFinish, {once: true}); - }); - fadeout_pieces.forEach((piece) => { - piece.style.opacity = 1; - piece.style.display = null; - piece.addEventListener('transitionend', onFinish, {once: true}); - }); - 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); - piece.addEventListener('transitionend', onFinish, {once: true}); - } - requestAnimationFrame(() => { - fadein_pieces.forEach((piece) => { - piece.style.transitionProperty = 'opacity'; - piece.style.transitionDuration = cfg.appearSpeed + 'ms'; - piece.style.opacity = 1; - }); - fadeout_pieces.forEach((piece) => { - piece.style.transitionProperty = 'opacity'; - piece.style.transitionDuration = cfg.trashSpeed + 'ms'; - piece.style.opacity = 0; - }); - 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; - } - }); - }); + fadein_pieces.forEach((piece) => { + piece.style.display = null; + piece.style.opacity = 1; + piece.animate( + [ { opacity: 0 }, { opacity: 1 } ], + { duration: cfg.appearSpeed } + ).addEventListener('finish', onFinish); + }); + fadeout_pieces.forEach((piece) => { + piece.style.display = null; + piece.style.opacity = 0; + piece.animate( + [ { opacity: 1 }, { opacity: 0 } ], + { duration: cfg.trashSpeed } + ).addEventListener('finish', onFinish); + }); + 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); + + let destSquarePosition = findSquarePosition(destination); + piece.animate( + [ + { top: piece.style.top, left: piece.style.left }, + { top: destSquarePosition.top, left: destSquarePosition.left } + ], + { duration: cfg.moveSpeed } + ).addEventListener('finish', onFinish); + piece.style.top = destSquarePosition.top; + piece.style.left = destSquarePosition.left; } } @@ -882,13 +856,15 @@ function snapbackDraggedPiece() { var sourceSquarePosition = findSquarePosition(DRAGGED_PIECE_SOURCE); // animate the piece to the target square - DRAGGED_PIECE.addEventListener('transitionend', complete, {once: true}); - requestAnimationFrame(() => { - 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; - }); + DRAGGED_PIECE.animate( + [ + { top: DRAGGED_PIECE.style.top, left: DRAGGED_PIECE.style.left }, + { top: sourceSquarePosition.top, left: sourceSquarePosition.left } + ], + { duration: cfg.snapbackSpeed } + ).addEventListener('finish', complete); + DRAGGED_PIECE.style.top = sourceSquarePosition.top; + DRAGGED_PIECE.style.left = sourceSquarePosition.left; // set state DRAGGING_A_PIECE = false; @@ -933,13 +909,15 @@ function dropDraggedPieceOnSquare(square) { }; // snap the piece to the target square - DRAGGED_PIECE.addEventListener('transitionend', complete, {once: true}); - requestAnimationFrame(() => { - 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; - }); + DRAGGED_PIECE.animate( + [ + { top: DRAGGED_PIECE.style.top, left: DRAGGED_PIECE.style.left }, + { top: targetSquarePosition.top, left: targetSquarePosition.left } + ], + { duration: cfg.snapSpeed } + ).addEventListener('finish', complete); + DRAGGED_PIECE.style.top = targetSquarePosition.top; + DRAGGED_PIECE.style.left = targetSquarePosition.left; } function beginDraggingPiece(source, piece, x, y) { @@ -956,8 +934,6 @@ function beginDraggingPiece(source, piece, x, y) { DRAGGED_PIECE = PIECE_ON_SQUARE[source]; DRAGGED_PIECE_SOURCE = source; DRAGGED_PIECE_LOCATION = source; - DRAGGED_PIECE.style.transitionProperty = null; - DRAGGED_PIECE.style.transitionDuration = null; // 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. -- 2.39.2