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() {
};
// 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) {
};
// animate the piece to the destination square
+ // FIXME: support this for non-jquery
var opts = {
duration: cfg.moveSpeed,
complete: complete
$(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
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
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
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;
drawPositionInstant();
// hide the dragged piece
+ // FIXME: support this for non-jquery
$(draggedPieceEl).fadeOut(cfg.trashSpeed);
// set state
// 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;