@alepot55/chessboardjs 2.3.5 → 2.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chessboard.cjs.js +127 -246
- package/dist/chessboard.esm.js +127 -246
- package/dist/chessboard.iife.js +127 -246
- package/dist/chessboard.umd.js +127 -246
- package/package.json +1 -1
- package/src/core/Chessboard.js +117 -201
- package/src/core/ChessboardConfig.js +0 -16
- package/src/core/ChessboardFactory.js +0 -5
- package/src/errors/messages.js +0 -1
- package/src/services/PieceService.js +9 -3
- package/src/services/ValidationService.js +1 -14
- package/src/utils/validation.js +1 -5
- package/tests/unit/chessboard-config-animations.test.js +0 -9
package/dist/chessboard.iife.js
CHANGED
|
@@ -127,7 +127,6 @@ var Chessboard = (function (exports) {
|
|
|
127
127
|
invalid_fadeTime: 'Invalid fadeTime: ',
|
|
128
128
|
invalid_fadeAnimation: 'Invalid fadeAnimation: ',
|
|
129
129
|
invalid_ratio: 'Invalid ratio: ',
|
|
130
|
-
invalid_animationStyle: 'Invalid animationStyle: ',
|
|
131
130
|
animation_failed: 'Animation failed: ',
|
|
132
131
|
|
|
133
132
|
// Event handlers
|
|
@@ -379,7 +378,6 @@ var Chessboard = (function (exports) {
|
|
|
379
378
|
movableColors: ['w', 'b', 'white', 'black', 'both', 'none'],
|
|
380
379
|
dropOffBoard: ['snapback', 'trash'],
|
|
381
380
|
easingTypes: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out'],
|
|
382
|
-
animationStyles: ['sequential', 'simultaneous'],
|
|
383
381
|
modes: ['normal', 'creative', 'analysis'],
|
|
384
382
|
promotionPieces: ['q', 'r', 'b', 'n', 'Q', 'R', 'B', 'N']
|
|
385
383
|
});
|
|
@@ -708,14 +706,6 @@ var Chessboard = (function (exports) {
|
|
|
708
706
|
return this._validValues.easingTypes.includes(easing);
|
|
709
707
|
}
|
|
710
708
|
|
|
711
|
-
/**
|
|
712
|
-
* Validates animation style
|
|
713
|
-
* @param {string} style - Animation style to validate
|
|
714
|
-
* @returns {boolean} True if valid
|
|
715
|
-
*/
|
|
716
|
-
isValidAnimationStyle(style) {
|
|
717
|
-
return this._validValues.animationStyles.includes(style);
|
|
718
|
-
}
|
|
719
709
|
|
|
720
710
|
/**
|
|
721
711
|
* Validates CSS color format
|
|
@@ -912,11 +902,7 @@ var Chessboard = (function (exports) {
|
|
|
912
902
|
if (config.dropOffBoard && !this.isValidDropOffBoard(config.dropOffBoard)) {
|
|
913
903
|
errors.push(ERROR_MESSAGES.invalid_dropOffBoard + config.dropOffBoard);
|
|
914
904
|
}
|
|
915
|
-
|
|
916
|
-
if (config.animationStyle && !this.isValidAnimationStyle(config.animationStyle)) {
|
|
917
|
-
errors.push(ERROR_MESSAGES.invalid_animationStyle + config.animationStyle);
|
|
918
|
-
}
|
|
919
|
-
|
|
905
|
+
|
|
920
906
|
// Validate callbacks
|
|
921
907
|
const callbacks = ['onMove', 'onMoveEnd', 'onChange', 'onDragStart', 'onDragMove', 'onDrop', 'onSnapbackEnd'];
|
|
922
908
|
for (const callback of callbacks) {
|
|
@@ -1094,7 +1080,6 @@ var Chessboard = (function (exports) {
|
|
|
1094
1080
|
fadeAnimation: 'ease',
|
|
1095
1081
|
ratio: 0.9,
|
|
1096
1082
|
piecesPath: '../assets/themes/default',
|
|
1097
|
-
animationStyle: 'simultaneous',
|
|
1098
1083
|
simultaneousAnimationDelay: 100,
|
|
1099
1084
|
onMove: () => true,
|
|
1100
1085
|
onMoveEnd: () => true,
|
|
@@ -1220,7 +1205,6 @@ var Chessboard = (function (exports) {
|
|
|
1220
1205
|
this.fadeTime = this._setTime(config.fadeTime);
|
|
1221
1206
|
|
|
1222
1207
|
// Animation style properties
|
|
1223
|
-
this.animationStyle = this._validateAnimationStyle(config.animationStyle);
|
|
1224
1208
|
this.simultaneousAnimationDelay = this._validateDelay(config.simultaneousAnimationDelay);
|
|
1225
1209
|
}
|
|
1226
1210
|
|
|
@@ -1281,19 +1265,6 @@ var Chessboard = (function (exports) {
|
|
|
1281
1265
|
return callback;
|
|
1282
1266
|
}
|
|
1283
1267
|
|
|
1284
|
-
/**
|
|
1285
|
-
* Validates animation style
|
|
1286
|
-
* @private
|
|
1287
|
-
* @param {string} style - Animation style
|
|
1288
|
-
* @returns {string} Validated style
|
|
1289
|
-
* @throws {ConfigurationError} If style is invalid
|
|
1290
|
-
*/
|
|
1291
|
-
_validateAnimationStyle(style) {
|
|
1292
|
-
if (!this._validationService.isValidAnimationStyle(style)) {
|
|
1293
|
-
throw new ConfigurationError('Invalid animation style', 'animationStyle', style);
|
|
1294
|
-
}
|
|
1295
|
-
return style;
|
|
1296
|
-
}
|
|
1297
1268
|
|
|
1298
1269
|
/**
|
|
1299
1270
|
* Validates animation delay
|
|
@@ -1431,7 +1402,6 @@ var Chessboard = (function (exports) {
|
|
|
1431
1402
|
fadeTime: this.fadeTime,
|
|
1432
1403
|
fadeAnimation: this.fadeAnimation,
|
|
1433
1404
|
piecesPath: this.piecesPath,
|
|
1434
|
-
animationStyle: this.animationStyle,
|
|
1435
1405
|
simultaneousAnimationDelay: this.simultaneousAnimationDelay,
|
|
1436
1406
|
onlyLegalMoves: this.onlyLegalMoves
|
|
1437
1407
|
};
|
|
@@ -4654,9 +4624,15 @@ var Chessboard = (function (exports) {
|
|
|
4654
4624
|
console.debug(`[PieceService] addPieceOnSquare: ${piece.id} to ${square.id}`);
|
|
4655
4625
|
square.putPiece(piece);
|
|
4656
4626
|
|
|
4627
|
+
// Imposta sempre il drag (touch e mouse)
|
|
4657
4628
|
if (dragFunction) {
|
|
4658
4629
|
piece.setDrag(dragFunction(square, piece));
|
|
4659
4630
|
}
|
|
4631
|
+
// Forza il drag touch se manca (debug/robustezza)
|
|
4632
|
+
if (!piece.element.ontouchstart) {
|
|
4633
|
+
piece.element.ontouchstart = dragFunction ? dragFunction(square, piece) : () => { };
|
|
4634
|
+
console.debug(`[PieceService] Forzato ontouchstart su ${piece.id}`);
|
|
4635
|
+
}
|
|
4660
4636
|
|
|
4661
4637
|
if (fade && this.config.fadeTime > 0) {
|
|
4662
4638
|
piece.fadeIn(
|
|
@@ -4714,8 +4690,8 @@ var Chessboard = (function (exports) {
|
|
|
4714
4690
|
*/
|
|
4715
4691
|
movePiece(piece, targetSquare, duration, callback) {
|
|
4716
4692
|
console.debug(`[PieceService] movePiece: ${piece.id} to ${targetSquare.id}`);
|
|
4717
|
-
if (!piece) {
|
|
4718
|
-
console.warn(
|
|
4693
|
+
if (!piece || !piece.element) {
|
|
4694
|
+
console.warn(`[PieceService] movePiece: piece or element is null, skipping animation`);
|
|
4719
4695
|
if (callback) callback();
|
|
4720
4696
|
return;
|
|
4721
4697
|
}
|
|
@@ -4771,7 +4747,7 @@ var Chessboard = (function (exports) {
|
|
|
4771
4747
|
};
|
|
4772
4748
|
|
|
4773
4749
|
// Check if piece is currently being dragged
|
|
4774
|
-
const isDragging = move.piece.element.classList.contains('dragging');
|
|
4750
|
+
const isDragging = move.piece.element && move.piece.element.classList.contains('dragging');
|
|
4775
4751
|
|
|
4776
4752
|
if (isDragging) {
|
|
4777
4753
|
// If piece is being dragged, don't animate - just move it immediately
|
|
@@ -7496,7 +7472,7 @@ var Chessboard = (function (exports) {
|
|
|
7496
7472
|
const capturedPiece = move.to.piece;
|
|
7497
7473
|
|
|
7498
7474
|
// For castle moves in simultaneous mode, we need to coordinate both animations
|
|
7499
|
-
if (isCastleMove
|
|
7475
|
+
if (isCastleMove) {
|
|
7500
7476
|
// Start king animation
|
|
7501
7477
|
this.pieceService.translatePiece(
|
|
7502
7478
|
move,
|
|
@@ -7721,172 +7697,62 @@ var Chessboard = (function (exports) {
|
|
|
7721
7697
|
}
|
|
7722
7698
|
|
|
7723
7699
|
/**
|
|
7724
|
-
*
|
|
7700
|
+
* Aggiorna i pezzi sulla scacchiera con animazione e delay configurabile (greedy matching)
|
|
7725
7701
|
* @private
|
|
7726
|
-
* @param {boolean} [animation=false] -
|
|
7727
|
-
* @param {boolean} [isPositionLoad=false] -
|
|
7702
|
+
* @param {boolean} [animation=false] - Se animare
|
|
7703
|
+
* @param {boolean} [isPositionLoad=false] - Se è un caricamento posizione (delay 0)
|
|
7728
7704
|
*/
|
|
7729
7705
|
_doUpdateBoardPieces(animation = false, isPositionLoad = false) {
|
|
7730
|
-
// Blocca update se un drag è in corso
|
|
7731
7706
|
if (this._isDragging) return;
|
|
7732
|
-
|
|
7733
|
-
if (this.
|
|
7734
|
-
return;
|
|
7735
|
-
}
|
|
7736
|
-
if (!this.positionService || !this.positionService.getGame()) {
|
|
7737
|
-
return;
|
|
7738
|
-
}
|
|
7707
|
+
if (this._isPromoting) return;
|
|
7708
|
+
if (!this.positionService || !this.positionService.getGame()) return;
|
|
7739
7709
|
const squares = this.boardService.getAllSquares();
|
|
7740
7710
|
const gameStateBefore = this.positionService.getGame().fen();
|
|
7741
7711
|
if (/^8\/8\/8\/8\/8\/8\/8\/8/.test(gameStateBefore)) {
|
|
7742
7712
|
const boardContainer = document.getElementById(this.config.id_div);
|
|
7743
7713
|
if (boardContainer) {
|
|
7744
7714
|
const pieceElements = boardContainer.querySelectorAll('.piece');
|
|
7745
|
-
pieceElements.forEach(element =>
|
|
7746
|
-
element.remove();
|
|
7747
|
-
});
|
|
7715
|
+
pieceElements.forEach(element => element.remove());
|
|
7748
7716
|
}
|
|
7749
|
-
Object.values(squares).forEach(sq => {
|
|
7750
|
-
if (sq && sq.piece) {
|
|
7751
|
-
sq.piece = null;
|
|
7752
|
-
}
|
|
7753
|
-
});
|
|
7717
|
+
Object.values(squares).forEach(sq => { if (sq && sq.piece) sq.piece = null; });
|
|
7754
7718
|
this._clearVisualState();
|
|
7755
7719
|
this._addListeners();
|
|
7756
7720
|
if (this.config.onChange) this.config.onChange(gameStateBefore);
|
|
7757
7721
|
return;
|
|
7758
7722
|
}
|
|
7759
|
-
const useSimultaneous = this.config.animationStyle === 'simultaneous';
|
|
7760
|
-
if (useSimultaneous) {
|
|
7761
|
-
this._doSimultaneousUpdate(squares, gameStateBefore, isPositionLoad);
|
|
7762
|
-
} else {
|
|
7763
|
-
this._doSequentialUpdate(squares, gameStateBefore, animation);
|
|
7764
|
-
}
|
|
7765
|
-
// Pulizia finale robusta: rimuovi tutti i pezzi orfani dal DOM e dal riferimento JS
|
|
7766
|
-
Object.values(this.boardService.getAllSquares()).forEach(square => {
|
|
7767
|
-
const expectedPieceId = this.positionService.getGamePieceId(square.id);
|
|
7768
|
-
if (!expectedPieceId && typeof square.forceRemoveAllPieces === 'function') {
|
|
7769
|
-
square.forceRemoveAllPieces();
|
|
7770
|
-
}
|
|
7771
|
-
});
|
|
7772
|
-
}
|
|
7773
7723
|
|
|
7774
|
-
|
|
7775
|
-
* Performs sequential piece updates (original behavior)
|
|
7776
|
-
* @private
|
|
7777
|
-
* @param {Object} squares - All squares
|
|
7778
|
-
* @param {string} gameStateBefore - Game state before update
|
|
7779
|
-
* @param {boolean} animation - Whether to animate
|
|
7780
|
-
*/
|
|
7781
|
-
_doSequentialUpdate(squares, gameStateBefore, animation) {
|
|
7782
|
-
// Mappa: squareId -> expectedPieceId
|
|
7783
|
-
const expectedMap = {};
|
|
7784
|
-
Object.values(squares).forEach(square => {
|
|
7785
|
-
expectedMap[square.id] = this.positionService.getGamePieceId(square.id);
|
|
7786
|
-
});
|
|
7787
|
-
|
|
7788
|
-
Object.values(squares).forEach(square => {
|
|
7789
|
-
const expectedPieceId = expectedMap[square.id];
|
|
7790
|
-
const currentPiece = square.piece;
|
|
7791
|
-
const currentPieceId = currentPiece ? currentPiece.getId() : null;
|
|
7792
|
-
|
|
7793
|
-
// Se il pezzo attuale e quello atteso sono identici, non fare nulla
|
|
7794
|
-
if (currentPieceId === expectedPieceId) {
|
|
7795
|
-
return;
|
|
7796
|
-
}
|
|
7797
|
-
|
|
7798
|
-
// Se c'è un pezzo attuale ma non è quello atteso, rimuovilo
|
|
7799
|
-
if (currentPiece && currentPieceId !== expectedPieceId) {
|
|
7800
|
-
// Rimozione robusta: elimina tutti i pezzi orfani dal DOM e dal riferimento JS
|
|
7801
|
-
if (typeof square.forceRemoveAllPieces === 'function') {
|
|
7802
|
-
square.forceRemoveAllPieces();
|
|
7803
|
-
} else {
|
|
7804
|
-
this.pieceService.removePieceFromSquare(square, animation);
|
|
7805
|
-
}
|
|
7806
|
-
}
|
|
7807
|
-
|
|
7808
|
-
// Se c'è un pezzo atteso ma non è quello attuale, aggiungilo
|
|
7809
|
-
if (expectedPieceId && currentPieceId !== expectedPieceId) {
|
|
7810
|
-
const newPiece = this.pieceService.convertPiece(expectedPieceId);
|
|
7811
|
-
this.pieceService.addPieceOnSquare(
|
|
7812
|
-
square,
|
|
7813
|
-
newPiece,
|
|
7814
|
-
animation,
|
|
7815
|
-
this._createDragFunction.bind(this)
|
|
7816
|
-
);
|
|
7817
|
-
}
|
|
7818
|
-
});
|
|
7819
|
-
|
|
7820
|
-
this._addListeners();
|
|
7821
|
-
const gameStateAfter = this.positionService.getGame().fen();
|
|
7822
|
-
if (gameStateBefore !== gameStateAfter) {
|
|
7823
|
-
this.config.onChange(gameStateAfter);
|
|
7824
|
-
}
|
|
7825
|
-
}
|
|
7826
|
-
|
|
7827
|
-
/**
|
|
7828
|
-
* Performs simultaneous piece updates
|
|
7829
|
-
* @private
|
|
7830
|
-
* @param {Object} squares - All squares
|
|
7831
|
-
* @param {string} gameStateBefore - Game state before update
|
|
7832
|
-
* @param {boolean} [isPositionLoad=false] - Whether this is a position load
|
|
7833
|
-
*/
|
|
7834
|
-
_doSimultaneousUpdate(squares, gameStateBefore, isPositionLoad = false) {
|
|
7835
|
-
// Matching greedy per distanza minima, robusto
|
|
7724
|
+
// --- Matching greedy tra attuale e atteso ---
|
|
7836
7725
|
const currentMap = {};
|
|
7837
7726
|
const expectedMap = {};
|
|
7838
|
-
|
|
7839
7727
|
Object.values(squares).forEach(square => {
|
|
7840
7728
|
const currentPiece = square.piece;
|
|
7841
7729
|
const expectedPieceId = this.positionService.getGamePieceId(square.id);
|
|
7842
7730
|
if (currentPiece) {
|
|
7843
|
-
// Normalizza la chiave come 'color+type' lowercase
|
|
7844
7731
|
const key = (currentPiece.color + currentPiece.type).toLowerCase();
|
|
7845
7732
|
if (!currentMap[key]) currentMap[key] = [];
|
|
7846
|
-
currentMap[key].push({ square, id: square.id });
|
|
7733
|
+
currentMap[key].push({ square, id: square.id, piece: currentPiece });
|
|
7847
7734
|
}
|
|
7848
7735
|
if (expectedPieceId) {
|
|
7849
|
-
// Normalizza la chiave come 'color+type' lowercase
|
|
7850
7736
|
const key = expectedPieceId.toLowerCase();
|
|
7851
7737
|
if (!expectedMap[key]) expectedMap[key] = [];
|
|
7852
7738
|
expectedMap[key].push({ square, id: square.id });
|
|
7853
7739
|
}
|
|
7854
7740
|
});
|
|
7855
|
-
|
|
7856
|
-
let animationsCompleted = 0;
|
|
7741
|
+
const animationDelay = isPositionLoad ? 0 : this.config.simultaneousAnimationDelay || 0;
|
|
7857
7742
|
let totalAnimations = 0;
|
|
7858
|
-
|
|
7859
|
-
let animationIndex = 0;
|
|
7860
|
-
|
|
7861
|
-
Object.keys(expectedMap).forEach(key => {
|
|
7862
|
-
totalAnimations += Math.max((currentMap[key] || []).length, expectedMap[key].length);
|
|
7863
|
-
});
|
|
7864
|
-
|
|
7865
|
-
if (totalAnimations === 0) {
|
|
7866
|
-
this._addListeners();
|
|
7867
|
-
const gameStateAfter = this.positionService.getGame().fen();
|
|
7868
|
-
if (gameStateBefore !== gameStateAfter) {
|
|
7869
|
-
this.config.onChange(gameStateAfter);
|
|
7870
|
-
}
|
|
7871
|
-
return;
|
|
7872
|
-
}
|
|
7873
|
-
|
|
7874
|
-
const onAnimationComplete = () => {
|
|
7875
|
-
animationsCompleted++;
|
|
7876
|
-
if (animationsCompleted === totalAnimations) {
|
|
7877
|
-
this._addListeners();
|
|
7878
|
-
const gameStateAfter = this.positionService.getGame().fen();
|
|
7879
|
-
if (gameStateBefore !== gameStateAfter) {
|
|
7880
|
-
this.config.onChange(gameStateAfter);
|
|
7881
|
-
}
|
|
7882
|
-
}
|
|
7883
|
-
};
|
|
7743
|
+
let animationsCompleted = 0;
|
|
7884
7744
|
|
|
7745
|
+
// 1. Matching greedy: trova i movimenti
|
|
7746
|
+
const moves = [];
|
|
7747
|
+
const fromMatched = {};
|
|
7748
|
+
const toMatched = {};
|
|
7749
|
+
const unchanged = [];
|
|
7885
7750
|
Object.keys(expectedMap).forEach(key => {
|
|
7886
7751
|
const fromList = (currentMap[key] || []).slice();
|
|
7887
7752
|
const toList = expectedMap[key].slice();
|
|
7888
|
-
|
|
7889
|
-
|
|
7753
|
+
const localFromMatched = new Array(fromList.length).fill(false);
|
|
7754
|
+
const localToMatched = new Array(toList.length).fill(false);
|
|
7755
|
+
// Matrice delle distanze
|
|
7890
7756
|
const distances = [];
|
|
7891
7757
|
for (let i = 0; i < fromList.length; i++) {
|
|
7892
7758
|
distances[i] = [];
|
|
@@ -7895,18 +7761,12 @@ var Chessboard = (function (exports) {
|
|
|
7895
7761
|
Math.abs(fromList[i].square.col - toList[j].square.col);
|
|
7896
7762
|
}
|
|
7897
7763
|
}
|
|
7898
|
-
|
|
7899
|
-
// 2. Matching greedy: abbina i più vicini
|
|
7900
|
-
const fromMatched = new Array(fromList.length).fill(false);
|
|
7901
|
-
const toMatched = new Array(toList.length).fill(false);
|
|
7902
|
-
const moves = [];
|
|
7903
|
-
|
|
7904
7764
|
while (true) {
|
|
7905
7765
|
let minDist = Infinity, minI = -1, minJ = -1;
|
|
7906
7766
|
for (let i = 0; i < fromList.length; i++) {
|
|
7907
|
-
if (
|
|
7767
|
+
if (localFromMatched[i]) continue;
|
|
7908
7768
|
for (let j = 0; j < toList.length; j++) {
|
|
7909
|
-
if (
|
|
7769
|
+
if (localToMatched[j]) continue;
|
|
7910
7770
|
if (distances[i][j] < minDist) {
|
|
7911
7771
|
minDist = distances[i][j];
|
|
7912
7772
|
minI = i;
|
|
@@ -7915,64 +7775,111 @@ var Chessboard = (function (exports) {
|
|
|
7915
7775
|
}
|
|
7916
7776
|
}
|
|
7917
7777
|
if (minI === -1 || minJ === -1) break;
|
|
7918
|
-
// Se la posizione è la stessa, non fare nulla (pezzo unchanged)
|
|
7919
|
-
if (fromList[minI].square === toList[minJ].square) {
|
|
7920
|
-
|
|
7921
|
-
|
|
7778
|
+
// Se la posizione è la stessa E il Piece è lo stesso oggetto, non fare nulla (pezzo unchanged)
|
|
7779
|
+
if (fromList[minI].square === toList[minJ].square && squares[toList[minJ].square.id].piece === fromList[minI].piece) {
|
|
7780
|
+
unchanged.push({ square: fromList[minI].square, piece: fromList[minI].piece });
|
|
7781
|
+
localFromMatched[minI] = true;
|
|
7782
|
+
localToMatched[minJ] = true;
|
|
7783
|
+
fromMatched[fromList[minI].square.id] = true;
|
|
7784
|
+
toMatched[toList[minJ].square.id] = true;
|
|
7922
7785
|
continue;
|
|
7923
7786
|
}
|
|
7924
7787
|
// Altrimenti, sposta il pezzo
|
|
7925
|
-
moves.push({ from: fromList[minI].square, to: toList[minJ].square, piece: fromList[minI].
|
|
7926
|
-
|
|
7927
|
-
|
|
7788
|
+
moves.push({ from: fromList[minI].square, to: toList[minJ].square, piece: fromList[minI].piece });
|
|
7789
|
+
localFromMatched[minI] = true;
|
|
7790
|
+
localToMatched[minJ] = true;
|
|
7791
|
+
fromMatched[fromList[minI].square.id] = true;
|
|
7792
|
+
toMatched[toList[minJ].square.id] = true;
|
|
7928
7793
|
}
|
|
7794
|
+
});
|
|
7929
7795
|
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7796
|
+
// 2. Rimozione: pezzi presenti solo in attuale (non matched)
|
|
7797
|
+
const removes = [];
|
|
7798
|
+
Object.keys(currentMap).forEach(key => {
|
|
7799
|
+
currentMap[key].forEach(({ square, piece }) => {
|
|
7800
|
+
if (!fromMatched[square.id]) {
|
|
7801
|
+
removes.push({ square, piece });
|
|
7802
|
+
}
|
|
7803
|
+
});
|
|
7804
|
+
});
|
|
7805
|
+
|
|
7806
|
+
// 3. Aggiunta: pezzi presenti solo in atteso (non matched)
|
|
7807
|
+
const adds = [];
|
|
7808
|
+
Object.keys(expectedMap).forEach(key => {
|
|
7809
|
+
expectedMap[key].forEach(({ square, id }) => {
|
|
7810
|
+
if (!toMatched[square.id]) {
|
|
7811
|
+
adds.push({ square, pieceId: key });
|
|
7943
7812
|
}
|
|
7813
|
+
});
|
|
7814
|
+
});
|
|
7815
|
+
|
|
7816
|
+
totalAnimations = moves.length + removes.length + adds.length;
|
|
7817
|
+
if (totalAnimations === 0) {
|
|
7818
|
+
this._addListeners();
|
|
7819
|
+
const gameStateAfter = this.positionService.getGame().fen();
|
|
7820
|
+
if (gameStateBefore !== gameStateAfter) {
|
|
7821
|
+
this.config.onChange(gameStateAfter);
|
|
7944
7822
|
}
|
|
7823
|
+
return;
|
|
7824
|
+
}
|
|
7945
7825
|
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7826
|
+
// Debug: logga i pezzi unchanged
|
|
7827
|
+
if (unchanged.length > 0) {
|
|
7828
|
+
console.debug('[Chessboard] Unchanged pieces:', unchanged.map(u => u.piece.id + '@' + u.square.id));
|
|
7829
|
+
}
|
|
7830
|
+
|
|
7831
|
+
const onAnimationComplete = () => {
|
|
7832
|
+
animationsCompleted++;
|
|
7833
|
+
if (animationsCompleted === totalAnimations) {
|
|
7834
|
+
// Pulizia finale robusta: rimuovi tutti i pezzi orfani dal DOM e dal riferimento JS
|
|
7835
|
+
Object.values(this.boardService.getAllSquares()).forEach(square => {
|
|
7836
|
+
const expectedPieceId = this.positionService.getGamePieceId(square.id);
|
|
7837
|
+
if (!expectedPieceId && typeof square.forceRemoveAllPieces === 'function') {
|
|
7838
|
+
square.forceRemoveAllPieces();
|
|
7839
|
+
}
|
|
7840
|
+
});
|
|
7841
|
+
this._addListeners();
|
|
7842
|
+
const gameStateAfter = this.positionService.getGame().fen();
|
|
7843
|
+
if (gameStateBefore !== gameStateAfter) {
|
|
7844
|
+
this.config.onChange(gameStateAfter);
|
|
7960
7845
|
}
|
|
7961
7846
|
}
|
|
7847
|
+
};
|
|
7962
7848
|
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7849
|
+
// 4. Esegui tutte le animazioni con delay
|
|
7850
|
+
let idx = 0;
|
|
7851
|
+
moves.forEach(move => {
|
|
7852
|
+
setTimeout(() => {
|
|
7853
|
+
this.pieceService.translatePiece(
|
|
7854
|
+
move,
|
|
7855
|
+
false,
|
|
7856
|
+
animation,
|
|
7857
|
+
this._createDragFunction.bind(this),
|
|
7858
|
+
onAnimationComplete
|
|
7859
|
+
);
|
|
7860
|
+
}, idx++ * animationDelay);
|
|
7861
|
+
});
|
|
7862
|
+
removes.forEach(op => {
|
|
7863
|
+
setTimeout(() => {
|
|
7864
|
+
if (typeof op.square.forceRemoveAllPieces === 'function') {
|
|
7865
|
+
op.square.forceRemoveAllPieces();
|
|
7866
|
+
onAnimationComplete();
|
|
7867
|
+
} else {
|
|
7868
|
+
this.pieceService.removePieceFromSquare(op.square, animation, onAnimationComplete);
|
|
7869
|
+
}
|
|
7870
|
+
}, idx++ * animationDelay);
|
|
7871
|
+
});
|
|
7872
|
+
adds.forEach(op => {
|
|
7873
|
+
setTimeout(() => {
|
|
7874
|
+
const newPiece = this.pieceService.convertPiece(op.pieceId);
|
|
7875
|
+
this.pieceService.addPieceOnSquare(
|
|
7876
|
+
op.square,
|
|
7877
|
+
newPiece,
|
|
7878
|
+
animation,
|
|
7879
|
+
this._createDragFunction.bind(this),
|
|
7880
|
+
onAnimationComplete
|
|
7881
|
+
);
|
|
7882
|
+
}, idx++ * animationDelay);
|
|
7976
7883
|
});
|
|
7977
7884
|
}
|
|
7978
7885
|
|
|
@@ -8909,23 +8816,6 @@ var Chessboard = (function (exports) {
|
|
|
8909
8816
|
}
|
|
8910
8817
|
}
|
|
8911
8818
|
|
|
8912
|
-
/**
|
|
8913
|
-
* Gets or sets the animation style
|
|
8914
|
-
* @param {string} [style] - New animation style ('sequential' or 'simultaneous')
|
|
8915
|
-
* @returns {string} Current animation style
|
|
8916
|
-
*/
|
|
8917
|
-
animationStyle(style) {
|
|
8918
|
-
if (style === undefined) {
|
|
8919
|
-
return this.config.animationStyle;
|
|
8920
|
-
}
|
|
8921
|
-
|
|
8922
|
-
if (this.validationService.isValidAnimationStyle(style)) {
|
|
8923
|
-
this.config.animationStyle = style;
|
|
8924
|
-
}
|
|
8925
|
-
|
|
8926
|
-
return this.config.animationStyle;
|
|
8927
|
-
}
|
|
8928
|
-
|
|
8929
8819
|
/**
|
|
8930
8820
|
* Gets or sets the simultaneous animation delay
|
|
8931
8821
|
* @param {number} [delay] - New delay in milliseconds
|
|
@@ -9493,7 +9383,6 @@ var Chessboard = (function (exports) {
|
|
|
9493
9383
|
hints: true,
|
|
9494
9384
|
clickable: true,
|
|
9495
9385
|
moveHighlight: true,
|
|
9496
|
-
animationStyle: 'simultaneous'
|
|
9497
9386
|
});
|
|
9498
9387
|
|
|
9499
9388
|
// Tournament template
|
|
@@ -9504,7 +9393,6 @@ var Chessboard = (function (exports) {
|
|
|
9504
9393
|
clickable: true,
|
|
9505
9394
|
moveHighlight: true,
|
|
9506
9395
|
onlyLegalMoves: true,
|
|
9507
|
-
animationStyle: 'sequential'
|
|
9508
9396
|
});
|
|
9509
9397
|
|
|
9510
9398
|
// Analysis template
|
|
@@ -9515,7 +9403,6 @@ var Chessboard = (function (exports) {
|
|
|
9515
9403
|
clickable: true,
|
|
9516
9404
|
moveHighlight: true,
|
|
9517
9405
|
mode: 'analysis',
|
|
9518
|
-
animationStyle: 'simultaneous'
|
|
9519
9406
|
});
|
|
9520
9407
|
|
|
9521
9408
|
// Puzzle template
|
|
@@ -9526,7 +9413,6 @@ var Chessboard = (function (exports) {
|
|
|
9526
9413
|
clickable: true,
|
|
9527
9414
|
moveHighlight: true,
|
|
9528
9415
|
onlyLegalMoves: true,
|
|
9529
|
-
animationStyle: 'sequential'
|
|
9530
9416
|
});
|
|
9531
9417
|
|
|
9532
9418
|
// Demo template
|
|
@@ -9536,7 +9422,6 @@ var Chessboard = (function (exports) {
|
|
|
9536
9422
|
hints: false,
|
|
9537
9423
|
clickable: false,
|
|
9538
9424
|
moveHighlight: true,
|
|
9539
|
-
animationStyle: 'simultaneous'
|
|
9540
9425
|
});
|
|
9541
9426
|
}
|
|
9542
9427
|
|
|
@@ -10344,11 +10229,7 @@ var Chessboard = (function (exports) {
|
|
|
10344
10229
|
if (config.moveAnimation && !isValidEasing(config.moveAnimation)) {
|
|
10345
10230
|
errors.push('Invalid moveAnimation. Must be a valid easing function');
|
|
10346
10231
|
}
|
|
10347
|
-
|
|
10348
|
-
if (config.animationStyle && !['sequential', 'simultaneous'].includes(config.animationStyle)) {
|
|
10349
|
-
errors.push('Invalid animationStyle. Must be "sequential" or "simultaneous"');
|
|
10350
|
-
}
|
|
10351
|
-
|
|
10232
|
+
|
|
10352
10233
|
return {
|
|
10353
10234
|
success: errors.length === 0,
|
|
10354
10235
|
errors
|