]> git.sesse.net Git - remoteglot/blobdiff - www/js/chessboard-0.3.0.js
Various fixes for running with advanced JS optimizations, if we want to do that in...
[remoteglot] / www / js / chessboard-0.3.0.js
index c45feeb74b5dc9b593271dd9e8cd1143d6569ce8..e15ab00ff5d57b2d3ed61c6c683967e7f3b564b2 100644 (file)
@@ -1,7 +1,8 @@
 /*!
- * chessboard.js v0.3.0
+ * chessboard.js v0.3.0+asn
  *
  * Copyright 2013 Chris Oakman
+ * Portions copyright 2022 Steinar H. Gunderson
  * Released under the MIT license
  * http://chessboardjs.com/license
  *
@@ -367,24 +368,6 @@ function checkDeps() {
     containerEl = containerElOrId;
   }
 
-  // JSON must exist
-  if (! window.JSON ||
-      typeof JSON.stringify !== 'function' ||
-      typeof JSON.parse !== 'function') {
-    window.alert('ChessBoard Error 1004: JSON does not exist. ' +
-      'Please include a JSON polyfill.\n\nExiting...');
-    return false;
-  }
-
-  // check for a compatible version of jQuery
-  if (! (typeof window.$ && $.fn && $.fn.jquery &&
-      compareSemVer($.fn.jquery, MINIMUM_JQUERY_VERSION) === true)) {
-    window.alert('ChessBoard Error 1005: Unable to find a valid version ' +
-      'of jQuery. Please include jQuery ' + MINIMUM_JQUERY_VERSION + ' or ' +
-      'higher on the page.\n\nExiting...');
-    return false;
-  }
-
   return true;
 }
 
@@ -716,13 +699,15 @@ function animateSquareToSquare(src, dest, piece, completeFn) {
   var animatedPieceId = createId();
   document.body.append(buildPiece(piece, true, animatedPieceId));
   var animatedPieceEl = document.getElementById(animatedPieceId);
-  animatedPieceEl.style.display = '';
+  animatedPieceEl.style.display = null;
   animatedPieceEl.style.position = 'absolute';
-  animatedPieceEl.style.top = srcSquarePosition.top;
-  animatedPieceEl.style.left = srcSquarePosition.left;
+  animatedPieceEl.style.top = srcSquarePosition.top + 'px';
+  animatedPieceEl.style.left = srcSquarePosition.left + 'px';
 
-  // remove original piece from source square
-  srcSquareEl.querySelector('.' + CSS.piece).remove();
+  // 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() {
@@ -739,11 +724,13 @@ function animateSquareToSquare(src, dest, piece, completeFn) {
   };
 
   // animate the piece to the destination square
-  var opts = {
-    duration: cfg.moveSpeed,
-    complete: complete
-  };
-  $(animatedPieceEl).animate(destSquarePosition, opts);
+  animatedPieceEl.addEventListener('transitionend', complete, {once: true});
+  requestAnimationFrame(() => {
+    animatedPieceEl.style.transitionProperty = 'top left';
+    animatedPieceEl.style.transitionDuration = cfg.moveSpeed + 'ms';
+    animatedPieceEl.style.top = destSquarePosition.top + 'px';
+    animatedPieceEl.style.left = destSquarePosition.left + 'px';
+  });
 }
 
 function animateSparePieceToSquare(piece, dest, completeFn) {
@@ -776,11 +763,34 @@ function animateSparePieceToSquare(piece, dest, completeFn) {
   };
 
   // animate the piece to the destination square
+  // FIXME: support this for non-jquery
   var opts = {
     duration: cfg.moveSpeed,
     complete: complete
   };
-  $(animatedPieceEl).animate(destOffset, opts);
+  //$(animatedPieceEl).animate(destOffset, opts);
+}
+
+function fadeIn(piece, onFinish) {
+  piece.style.opacity = 0;
+  piece.style.display = null;
+  piece.addEventListener('transitionend', onFinish, {once: true});
+  requestAnimationFrame(() => {
+    piece.style.transitionProperty = 'opacity';
+    piece.style.transitionDuration = cfg.appearSpeed + 'ms';
+    piece.style.opacity = 1;
+  });
+}
+
+function fadeOut(piece, onFinish) {
+  piece.style.opacity = 1;
+  piece.style.display = null;
+  piece.addEventListener('transitionend', onFinish, {once: true});
+  requestAnimationFrame(() => {
+    piece.style.transitionProperty = 'opacity';
+    piece.style.transitionDuration = cfg.trashSpeed + 'ms';
+    piece.style.opacity = 0;
+  });
 }
 
 // execute an array of animations
@@ -788,7 +798,11 @@ function doAnimations(a, oldPos, newPos) {
   ANIMATION_HAPPENING = true;
 
   var numFinished = 0;
-  function onFinish() {
+  function onFinish(e) {
+    if (e && e.target) {
+      e.target.transitionProperty = null;
+    }
+
     numFinished++;
 
     // exit if all the animations aren't finished
@@ -807,16 +821,17 @@ function doAnimations(a, oldPos, newPos) {
   for (var i = 0; i < a.length; i++) {
     // clear a piece
     if (a[i].type === 'clear') {
-      $('#' + SQUARE_ELS_IDS[a[i].square] + ' .' + CSS.piece)
-        .fadeOut(cfg.trashSpeed, onFinish);
+      document.getElementById(SQUARE_ELS_IDS[a[i].square]).querySelectorAll('.' + CSS.piece).forEach(
+        (piece) => fadeOut(piece, onFinish)
+      );
     }
 
     // add a piece (no spare pieces)
     if (a[i].type === 'add' && cfg.sparePieces !== true) {
-      $('#' + SQUARE_ELS_IDS[a[i].square])
-        .append(buildPiece(a[i].piece, true))
-        .find('.' + CSS.piece)
-        .fadeIn(cfg.appearSpeed, onFinish);
+      let square = document.getElementById(SQUARE_ELS_IDS[a[i].square]);
+      square.append(buildPiece(a[i].piece, true));
+      let piece = square.querySelector('.' + CSS.piece);
+      fadeIn(piece, onFinish);
     }
 
     // add a piece from a spare piece
@@ -1101,11 +1116,13 @@ function snapbackDraggedPiece() {
     offset(document.getElementById(SQUARE_ELS_IDS[DRAGGED_PIECE_SOURCE]));
 
   // animate the piece to the target square
-  var opts = {
-    duration: cfg.snapbackSpeed,
-    complete: complete
-  };
-  $(draggedPieceEl).animate(sourceSquarePosition, opts);
+  draggedPieceEl.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';
+  });
 
   // set state
   DRAGGING_A_PIECE = false;
@@ -1123,7 +1140,8 @@ function trashDraggedPiece() {
   drawPositionInstant();
 
   // hide the dragged piece
-  $(draggedPieceEl).fadeOut(cfg.trashSpeed);
+  // FIXME: support this for non-jquery
+  //$(draggedPieceEl).fadeOut(cfg.trashSpeed);
 
   // set state
   DRAGGING_A_PIECE = false;
@@ -1149,16 +1167,20 @@ function dropDraggedPieceOnSquare(square) {
     // execute their onSnapEnd function
     if (cfg.hasOwnProperty('onSnapEnd') === true &&
       typeof cfg.onSnapEnd === 'function') {
-      cfg.onSnapEnd(DRAGGED_PIECE_SOURCE, square, DRAGGED_PIECE);
+      requestAnimationFrame(() => {  // HACK: so that we don't add event handlers from the callback...
+        cfg.onSnapEnd(DRAGGED_PIECE_SOURCE, square, DRAGGED_PIECE);
+      });
     }
   };
 
   // snap the piece to the target square
-  var opts = {
-    duration: cfg.snapSpeed,
-    complete: complete
-  };
-  $(draggedPieceEl).animate(targetSquarePosition, opts);
+  draggedPieceEl.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';
+  });
 
   // set state
   DRAGGING_A_PIECE = false;