]> git.sesse.net Git - remoteglot/blobdiff - www/js/chessboard-0.3.0.js
Batch moving pieces together in one rAF.
[remoteglot] / www / js / chessboard-0.3.0.js
index 333935930aaace2bfe6c3c972d680eb25abe24ad..dc0e427b7fae69679c032147280fcdff7876fa17 100644 (file)
@@ -199,8 +199,7 @@ cfg = cfg || {};
 // Constants
 //------------------------------------------------------------------------------
 
-var MINIMUM_JQUERY_VERSION = '1.7.0',
-  START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR',
+var START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR',
   START_POSITION = fenToObj(START_FEN);
 
 // use unique class names to prevent clashing with anything else on the page
@@ -262,28 +261,6 @@ function deepCopy(thing) {
   return JSON.parse(JSON.stringify(thing));
 }
 
-function parseSemVer(version) {
-  var tmp = version.split('.');
-  return {
-    major: parseInt(tmp[0], 10),
-    minor: parseInt(tmp[1], 10),
-    patch: parseInt(tmp[2], 10)
-  };
-}
-
-// returns true if version is >= minimum
-function compareSemVer(version, minimum) {
-  version = parseSemVer(version);
-  minimum = parseSemVer(minimum);
-
-  var versionNum = (version.major * 10000 * 10000) +
-    (version.minor * 10000) + version.patch;
-  var minimumNum = (minimum.major * 10000 * 10000) +
-    (minimum.minor * 10000) + minimum.patch;
-
-  return (versionNum >= minimumNum);
-}
-
 //------------------------------------------------------------------------------
 // Validation / Errors
 //------------------------------------------------------------------------------
@@ -397,11 +374,6 @@ function expandConfig() {
     cfg.draggable = false;
   }
 
-  // default for dropOffBoard is 'snapback'
-  if (cfg.dropOffBoard !== 'trash') {
-    cfg.dropOffBoard = 'snapback';
-  }
-
   // default piece theme is wikipedia
   if (cfg.hasOwnProperty('pieceTheme') !== true ||
       (typeof cfg.pieceTheme !== 'string' &&
@@ -631,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';
+    }
   });
 }
 
@@ -732,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
@@ -751,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]);
       }
     }
 
@@ -764,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);
+    }
   });
 }
 
@@ -1002,25 +983,6 @@ function snapbackDraggedPiece() {
   DRAGGING_A_PIECE = false;
 }
 
-function trashDraggedPiece() {
-  removeSquareHighlights();
-
-  // remove the source piece
-  var newPosition = deepCopy(CURRENT_POSITION);
-  delete newPosition[DRAGGED_PIECE_SOURCE];
-  setCurrentPosition(newPosition);
-
-  // redraw the position
-  drawPositionInstant();
-
-  // hide the dragged piece
-  // FIXME: support this for non-jquery
-  //$(draggedPieceEl).fadeOut(cfg.trashSpeed);
-
-  // set state
-  DRAGGING_A_PIECE = false;
-}
-
 function dropDraggedPieceOnSquare(square) {
   removeSquareHighlights();
 
@@ -1130,21 +1092,12 @@ function stopDraggedPiece(location) {
   if (location === 'offboard' && cfg.dropOffBoard === 'snapback') {
     action = 'snapback';
   }
-  if (location === 'offboard' && cfg.dropOffBoard === 'trash') {
-    action = 'trash';
-  }
 
   // run their onDrop function, which can potentially change the drop action
   if (cfg.hasOwnProperty('onDrop') === true &&
     typeof cfg.onDrop === 'function') {
     var newPosition = deepCopy(CURRENT_POSITION);
 
-    // source piece was on the board and position is off the board
-    if (validSquare(DRAGGED_PIECE_SOURCE) === true && location === 'offboard') {
-      // remove the piece from the board
-      delete newPosition[DRAGGED_PIECE_SOURCE];
-    }
-
     // source piece was on the board and position is on the board
     if (validSquare(DRAGGED_PIECE_SOURCE) === true &&
       validSquare(location) === true) {
@@ -1157,7 +1110,7 @@ function stopDraggedPiece(location) {
 
     var result = cfg.onDrop(DRAGGED_PIECE_SOURCE, location, DRAGGED_PIECE,
       newPosition, oldPosition, CURRENT_ORIENTATION);
-    if (result === 'snapback' || result === 'trash') {
+    if (result === 'snapback') {
       action = result;
     }
   }
@@ -1166,9 +1119,6 @@ function stopDraggedPiece(location) {
   if (action === 'snapback') {
     snapbackDraggedPiece();
   }
-  else if (action === 'trash') {
-    trashDraggedPiece();
-  }
   else if (action === 'drop') {
     dropDraggedPieceOnSquare(location);
   }