]> git.sesse.net Git - remoteglot/commitdiff
Batch moving pieces together in one rAF.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 28 Dec 2022 23:24:51 +0000 (00:24 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 28 Dec 2022 23:24:51 +0000 (00:24 +0100)
www/js/chessboard-0.3.0.js

index a846f80db510b42014601505cad962a483169991..dc0e427b7fae69679c032147280fcdff7876fa17 100644 (file)
@@ -603,49 +603,55 @@ function offset(el) {  // From https://youmightnotneedjquery.com/.
   };
 }
 
-function animateSquareToSquare(src, dest, piece, completeFn) {
-  // get information about the source and destination squares
-  var srcSquareEl = document.getElementById(SQUARE_ELS_IDS[src]);
-  var srcSquarePosition = offset(srcSquareEl);
-  var destSquareEl = document.getElementById(SQUARE_ELS_IDS[dest]);
-  var destSquarePosition = offset(destSquareEl);
-
-  // create the animated piece and absolutely position it
-  // over the source square
-  var animatedPieceId = createId();
-  document.body.append(buildPiece(piece, true, animatedPieceId));
-  var 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
-  var 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 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();
+      }
+    };
 
-  // animate the piece to the destination square
-  animatedPieceEl.addEventListener('transitionend', complete, {once: true});
+    // animate the piece to the destination square
+    animatedPieceEl.addEventListener('transitionend', complete, {once: true});
+    pieces.push([animatedPieceEl, destSquarePosition]);
+  }
   requestAnimationFrame(() => {
-    animatedPieceEl.style.transitionProperty = 'top, left';
-    animatedPieceEl.style.transitionDuration = cfg.moveSpeed + 'ms';
-    animatedPieceEl.style.top = destSquarePosition.top + 'px';
-    animatedPieceEl.style.left = destSquarePosition.left + 'px';
+    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';
+    }
   });
 }
 
@@ -704,6 +710,7 @@ 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
@@ -723,8 +730,7 @@ function doAnimations(a, oldPos, newPos) {
 
       // move a piece
       if (a[i].type === 'move') {
-        animateSquareToSquare(a[i].source, a[i].destination, a[i].piece,
-          onFinish);
+        moved_pieces.push(a[i]);
       }
     }
 
@@ -736,6 +742,9 @@ function doAnimations(a, oldPos, newPos) {
     if (fadein_pieces.length > 0) {
       fadeIn(fadein_pieces, onFinish);
     }
+    if (moved_pieces.length > 0) {
+      animateSquareToSquare(moved_pieces, onFinish);
+    }
   });
 }