@alepot55/chessboardjs 2.1.7 → 2.2.1
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/README.md +3 -3
- package/chessboard.bundle.js +99 -77
- package/chessboard.config.js +7 -5
- package/chessboard.js +69 -43
- package/chessboard.move.js +9 -21
- package/chessboard.piece.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Chessboard.js: Interactive and Customizable Chessboard Library
|
|
2
2
|
|
|
3
|
-
Chessboard.js is a lightweight and versatile NPM package that lets you easily integrate an interactive, customizable chessboard into your web applications. Use it for game displays, chess lessons, analysis tools, or any project that needs a visual chess interface.
|
|
3
|
+
[Chessboard.js](https://sites.google.com/view/chessboard-js/home) is a lightweight and versatile NPM package that lets you easily integrate an interactive, customizable chessboard into your web applications. Use it for game displays, chess lessons, analysis tools, or any project that needs a visual chess interface.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
|
-
Chessboard.js is designed with simplicity and flexibility in mind. Configure board appearance, piece sets, orientation, highlighting, animations, and more through a rich API. The board updates dynamically with user interactions and programmatic moves.
|
|
6
|
+
[Chessboard.js](https://sites.google.com/view/chessboard-js/home) is designed with simplicity and flexibility in mind. Configure board appearance, piece sets, orientation, highlighting, animations, and more through a rich API. The board updates dynamically with user interactions and programmatic moves.
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
```bash
|
|
@@ -384,7 +384,7 @@ This document details the functions available to users for interacting with the
|
|
|
384
384
|
Places a piece on the board.
|
|
385
385
|
_Example:_
|
|
386
386
|
```js
|
|
387
|
-
board.put(
|
|
387
|
+
board.put('pw', 'd4');
|
|
388
388
|
```
|
|
389
389
|
|
|
390
390
|
- **remove(squareId, animation = true)**
|
package/chessboard.bundle.js
CHANGED
|
@@ -1997,7 +1997,8 @@ var Chessboard = (function () {
|
|
|
1997
1997
|
'linear': 'linear',
|
|
1998
1998
|
'ease-in': 'ease-in',
|
|
1999
1999
|
'ease-out': 'ease-out',
|
|
2000
|
-
'ease-in-out': 'ease-in-out'
|
|
2000
|
+
'ease-in-out': 'ease-in-out',
|
|
2001
|
+
'none': null
|
|
2001
2002
|
};
|
|
2002
2003
|
|
|
2003
2004
|
class ChessboardConfig {
|
|
@@ -2051,9 +2052,6 @@ var Chessboard = (function () {
|
|
|
2051
2052
|
this.dropOffBoard = config.dropOffBoard;
|
|
2052
2053
|
this.size = config.size;
|
|
2053
2054
|
this.movableColors = config.movableColors;
|
|
2054
|
-
this.moveAnimation = config.moveAnimation;
|
|
2055
|
-
this.snapbackAnimation = config.snapbackAnimation;
|
|
2056
|
-
this.fadeAnimation = config.fadeAnimation;
|
|
2057
2055
|
this.piecesPath = config.piecesPath;
|
|
2058
2056
|
this.onMove = config.onMove;
|
|
2059
2057
|
this.onMoveEnd = config.onMoveEnd;
|
|
@@ -2063,6 +2061,10 @@ var Chessboard = (function () {
|
|
|
2063
2061
|
this.onDrop = config.onDrop;
|
|
2064
2062
|
this.onSnapbackEnd = config.onSnapbackEnd;
|
|
2065
2063
|
|
|
2064
|
+
this.moveAnimation = this.setTransitionFunction(config.moveAnimation);
|
|
2065
|
+
this.snapbackAnimation = this.setTransitionFunction(config.snapbackAnimation);
|
|
2066
|
+
this.fadeAnimation = this.setTransitionFunction(config.fadeAnimation);
|
|
2067
|
+
|
|
2066
2068
|
this.hints = this.setBoolean(config.hints);
|
|
2067
2069
|
this.clickable = this.setBoolean(config.clickable);
|
|
2068
2070
|
this.draggable = this.setBoolean(config.draggable);
|
|
@@ -2115,7 +2117,7 @@ var Chessboard = (function () {
|
|
|
2115
2117
|
}
|
|
2116
2118
|
|
|
2117
2119
|
setTransitionFunction(value) {
|
|
2118
|
-
if (transitionFunctions
|
|
2120
|
+
if (Object.keys(transitionFunctions).indexOf(value) !== -1) return transitionFunctions[value];
|
|
2119
2121
|
throw new Error('Invalid transition function');
|
|
2120
2122
|
}
|
|
2121
2123
|
}
|
|
@@ -2168,7 +2170,7 @@ var Chessboard = (function () {
|
|
|
2168
2170
|
}
|
|
2169
2171
|
|
|
2170
2172
|
setDrag(f) {
|
|
2171
|
-
this.element.ondragstart = () =>
|
|
2173
|
+
this.element.ondragstart = (e) => { e.preventDefault(); };
|
|
2172
2174
|
this.element.onmousedown = f;
|
|
2173
2175
|
}
|
|
2174
2176
|
|
|
@@ -2423,27 +2425,15 @@ var Chessboard = (function () {
|
|
|
2423
2425
|
}
|
|
2424
2426
|
|
|
2425
2427
|
check() {
|
|
2426
|
-
if (this.piece === null)
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
if (!(this.
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
if (
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
if (!(this.from instanceof Square)) {
|
|
2436
|
-
throw new Error("Invalid move: from is not an instance of Square");
|
|
2437
|
-
}
|
|
2438
|
-
if (!(this.to instanceof Square)) {
|
|
2439
|
-
throw new Error("Invalid move: to is not an instance of Square");
|
|
2440
|
-
}
|
|
2441
|
-
if (!this.to) {
|
|
2442
|
-
throw new Error("Invalid move: to is null or undefined");
|
|
2443
|
-
}
|
|
2444
|
-
if (!this.from) {
|
|
2445
|
-
throw new Error("Invalid move: from is null or undefined");
|
|
2446
|
-
}
|
|
2428
|
+
if (this.piece === null) return false;
|
|
2429
|
+
if (!(this.piece instanceof Piece)) return false;
|
|
2430
|
+
if (['q', 'r', 'b', 'n', null].indexOf(this.promotion) === -1) return false;
|
|
2431
|
+
if (!(this.from instanceof Square)) return false;
|
|
2432
|
+
if (!(this.to instanceof Square)) return false;
|
|
2433
|
+
if (!this.to) return false;
|
|
2434
|
+
if (!this.from) return false;
|
|
2435
|
+
if (this.from === this.to) return false;
|
|
2436
|
+
return true;
|
|
2447
2437
|
}
|
|
2448
2438
|
|
|
2449
2439
|
isLegal(game) {
|
|
@@ -2515,7 +2505,7 @@ var Chessboard = (function () {
|
|
|
2515
2505
|
}
|
|
2516
2506
|
|
|
2517
2507
|
initParams() {
|
|
2518
|
-
this.
|
|
2508
|
+
this.element = null;
|
|
2519
2509
|
this.squares = {};
|
|
2520
2510
|
this.promoting = false;
|
|
2521
2511
|
this.clicked = null;
|
|
@@ -2527,12 +2517,12 @@ var Chessboard = (function () {
|
|
|
2527
2517
|
// Board Setup
|
|
2528
2518
|
// -------------------
|
|
2529
2519
|
buildBoard() {
|
|
2530
|
-
this.
|
|
2531
|
-
if (!this.
|
|
2520
|
+
this.element = document.getElementById(this.config.id_div);
|
|
2521
|
+
if (!this.element) {
|
|
2532
2522
|
throw new Error(this.error_messages['invalid_id_div'] + this.config.id_div);
|
|
2533
2523
|
}
|
|
2534
2524
|
this.resize(this.config.size);
|
|
2535
|
-
this.
|
|
2525
|
+
this.element.className = "board";
|
|
2536
2526
|
}
|
|
2537
2527
|
|
|
2538
2528
|
buildSquares() {
|
|
@@ -2544,19 +2534,19 @@ var Chessboard = (function () {
|
|
|
2544
2534
|
let square = new Square(square_row, square_col);
|
|
2545
2535
|
this.squares[square.getId()] = square;
|
|
2546
2536
|
|
|
2547
|
-
this.
|
|
2537
|
+
this.element.appendChild(square.element);
|
|
2548
2538
|
}
|
|
2549
2539
|
}
|
|
2550
2540
|
}
|
|
2551
2541
|
|
|
2552
2542
|
removeBoard() {
|
|
2553
2543
|
|
|
2554
|
-
this.
|
|
2544
|
+
this.element.innerHTML = '';
|
|
2555
2545
|
}
|
|
2556
2546
|
|
|
2557
2547
|
removeSquares() {
|
|
2558
2548
|
for (const square of Object.values(this.squares)) {
|
|
2559
|
-
this.
|
|
2549
|
+
this.element.removeChild(square.element);
|
|
2560
2550
|
square.destroy();
|
|
2561
2551
|
|
|
2562
2552
|
}
|
|
@@ -2566,12 +2556,12 @@ var Chessboard = (function () {
|
|
|
2566
2556
|
resize(value) {
|
|
2567
2557
|
if (value === 'auto') {
|
|
2568
2558
|
let size;
|
|
2569
|
-
if (this.
|
|
2570
|
-
size = this.
|
|
2571
|
-
} else if (this.
|
|
2572
|
-
size = this.
|
|
2559
|
+
if (this.element.offsetWidth === 0) {
|
|
2560
|
+
size = this.element.offsetHeight;
|
|
2561
|
+
} else if (this.element.offsetHeight === 0) {
|
|
2562
|
+
size = this.element.offsetWidth;
|
|
2573
2563
|
} else {
|
|
2574
|
-
size = Math.min(this.
|
|
2564
|
+
size = Math.min(this.element.offsetWidth, this.element.offsetHeight);
|
|
2575
2565
|
}
|
|
2576
2566
|
this.resize(size);
|
|
2577
2567
|
} else if (typeof value !== 'number') {
|
|
@@ -2587,6 +2577,7 @@ var Chessboard = (function () {
|
|
|
2587
2577
|
// -------------------
|
|
2588
2578
|
convertFen(position) {
|
|
2589
2579
|
if (typeof position === 'string') {
|
|
2580
|
+
if (position == 'start') return 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
|
|
2590
2581
|
if (this.validateFen(position)) return position;
|
|
2591
2582
|
else if (this.standard_positions[position]) return this.standard_positions[position];
|
|
2592
2583
|
else throw new Error('Invalid position -' + position);
|
|
@@ -2613,15 +2604,15 @@ var Chessboard = (function () {
|
|
|
2613
2604
|
if (empty > 0) rowParts.push(empty);
|
|
2614
2605
|
parts.push(rowParts.join(''));
|
|
2615
2606
|
}
|
|
2616
|
-
return parts.join('/');
|
|
2617
|
-
} else {
|
|
2607
|
+
return parts.join('/') + ' w KQkq - 0 1'; } else {
|
|
2618
2608
|
throw new Error('Invalid position -' + position);
|
|
2619
2609
|
}
|
|
2620
2610
|
}
|
|
2621
2611
|
|
|
2622
|
-
setGame(position) {
|
|
2612
|
+
setGame(position, options = undefined) {
|
|
2623
2613
|
const fen = this.convertFen(position);
|
|
2624
|
-
this.game
|
|
2614
|
+
if (this.game) this.game.load(fen, options);
|
|
2615
|
+
else this.game = new Chess(fen);
|
|
2625
2616
|
}
|
|
2626
2617
|
|
|
2627
2618
|
// -------------------
|
|
@@ -2701,7 +2692,7 @@ var Chessboard = (function () {
|
|
|
2701
2692
|
|
|
2702
2693
|
}
|
|
2703
2694
|
|
|
2704
|
-
snapbackPiece(square, animate) {
|
|
2695
|
+
snapbackPiece(square, animate = this.config.snapbackAnimation) {
|
|
2705
2696
|
let move = new Move(square, square);
|
|
2706
2697
|
this.translatePiece(move, false, animate);
|
|
2707
2698
|
}
|
|
@@ -2712,11 +2703,15 @@ var Chessboard = (function () {
|
|
|
2712
2703
|
updateBoardPieces(animation = false) {
|
|
2713
2704
|
let { updatedFlags, escapeFlags, movableFlags, pendingTranslations } = this.prepareBoardUpdateData();
|
|
2714
2705
|
|
|
2706
|
+
let change = Object.values(updatedFlags).some(flag => !flag);
|
|
2707
|
+
|
|
2715
2708
|
this.identifyPieceTranslations(updatedFlags, escapeFlags, movableFlags, pendingTranslations);
|
|
2716
2709
|
|
|
2717
2710
|
this.executePieceTranslations(pendingTranslations, escapeFlags, animation);
|
|
2718
2711
|
|
|
2719
2712
|
this.processRemainingPieceUpdates(updatedFlags, animation);
|
|
2713
|
+
|
|
2714
|
+
if (change) this.config.onChange(this.fen());
|
|
2720
2715
|
}
|
|
2721
2716
|
|
|
2722
2717
|
prepareBoardUpdateData() {
|
|
@@ -2816,11 +2811,9 @@ var Chessboard = (function () {
|
|
|
2816
2811
|
updateSinglePiece(square, newPiece, updatedFlags, animation) {
|
|
2817
2812
|
if (!updatedFlags[square.id]) {
|
|
2818
2813
|
let lastMove = this.lastMove();
|
|
2819
|
-
console.log(lastMove);
|
|
2820
2814
|
|
|
2821
2815
|
if (lastMove?.promotion) {
|
|
2822
2816
|
if (lastMove['to'] === square.id) {
|
|
2823
|
-
console.log('Promotion detected');
|
|
2824
2817
|
|
|
2825
2818
|
let move = new Move(this.squares[lastMove['from']], square);
|
|
2826
2819
|
this.translatePiece(move, true, animation
|
|
@@ -2846,7 +2839,6 @@ var Chessboard = (function () {
|
|
|
2846
2839
|
event.preventDefault();
|
|
2847
2840
|
|
|
2848
2841
|
if (!this.config.draggable || !piece) return;
|
|
2849
|
-
if (!this.config.onDragStart(square, piece)) return;
|
|
2850
2842
|
|
|
2851
2843
|
let prec;
|
|
2852
2844
|
let from = square;
|
|
@@ -2856,7 +2848,7 @@ var Chessboard = (function () {
|
|
|
2856
2848
|
|
|
2857
2849
|
if (!this.canMove(from)) return;
|
|
2858
2850
|
if (!this.config.clickable) this.clicked = null;
|
|
2859
|
-
if (this.onClick(from)) return;
|
|
2851
|
+
if (this.onClick(from, true, true)) return;
|
|
2860
2852
|
|
|
2861
2853
|
img.style.position = 'absolute';
|
|
2862
2854
|
img.style.zIndex = 100;
|
|
@@ -2870,10 +2862,11 @@ var Chessboard = (function () {
|
|
|
2870
2862
|
};
|
|
2871
2863
|
|
|
2872
2864
|
const onMouseMove = (event) => {
|
|
2865
|
+
if (!this.config.onDragStart(square, piece)) return;
|
|
2873
2866
|
if (!moveAt(event.pageX, event.pageY)) ;
|
|
2874
2867
|
|
|
2875
|
-
const boardRect = this.
|
|
2876
|
-
const { offsetWidth: boardWidth, offsetHeight: boardHeight } = this.
|
|
2868
|
+
const boardRect = this.element.getBoundingClientRect();
|
|
2869
|
+
const { offsetWidth: boardWidth, offsetHeight: boardHeight } = this.element;
|
|
2877
2870
|
const x = event.clientX - boardRect.left;
|
|
2878
2871
|
const y = event.clientY - boardRect.top;
|
|
2879
2872
|
|
|
@@ -2908,9 +2901,9 @@ var Chessboard = (function () {
|
|
|
2908
2901
|
this.allSquares('removeHint');
|
|
2909
2902
|
from.deselect();
|
|
2910
2903
|
this.remove(from);
|
|
2911
|
-
} else if (!to || !this.onClick(to, true)) {
|
|
2912
|
-
this.snapbackPiece(from
|
|
2913
|
-
this.config.onSnapbackEnd(from, piece);
|
|
2904
|
+
} else if (!to || !this.onClick(to, true, true)) {
|
|
2905
|
+
this.snapbackPiece(from);
|
|
2906
|
+
if (to !== from) this.config.onSnapbackEnd(from, piece);
|
|
2914
2907
|
}
|
|
2915
2908
|
};
|
|
2916
2909
|
|
|
@@ -2937,14 +2930,14 @@ var Chessboard = (function () {
|
|
|
2937
2930
|
if (this.config.clickable && (!piece || this.config.onlyLegalMoves)) this.onClick(square);
|
|
2938
2931
|
};
|
|
2939
2932
|
|
|
2940
|
-
square.element.addEventListener("
|
|
2933
|
+
square.element.addEventListener("mousedown", handleClick);
|
|
2941
2934
|
square.element.addEventListener("touch", handleClick);
|
|
2942
2935
|
}
|
|
2943
2936
|
}
|
|
2944
2937
|
|
|
2945
|
-
onClick(square, animation = this.config.moveAnimation) {
|
|
2946
|
-
|
|
2947
|
-
if (
|
|
2938
|
+
onClick(square, animation = this.config.moveAnimation, dragged = false) {
|
|
2939
|
+
|
|
2940
|
+
if (this.clicked === square) return false;
|
|
2948
2941
|
|
|
2949
2942
|
let from = this.clicked;
|
|
2950
2943
|
this.clicked = null;
|
|
@@ -2963,19 +2956,22 @@ var Chessboard = (function () {
|
|
|
2963
2956
|
if (!from) {
|
|
2964
2957
|
|
|
2965
2958
|
if (this.canMove(square)) {
|
|
2966
|
-
|
|
2967
|
-
|
|
2959
|
+
if (this.config.clickable) {
|
|
2960
|
+
square.select();
|
|
2961
|
+
this.hintMoves(square);
|
|
2962
|
+
}
|
|
2968
2963
|
this.clicked = square;
|
|
2969
2964
|
}
|
|
2970
2965
|
|
|
2971
2966
|
return false;
|
|
2972
2967
|
}
|
|
2973
2968
|
|
|
2974
|
-
if (!this.canMove(from)) return false;
|
|
2975
|
-
|
|
2976
2969
|
let move = new Move(from, square, promotion);
|
|
2977
2970
|
|
|
2978
2971
|
move.from.deselect();
|
|
2972
|
+
|
|
2973
|
+
if (!move.check()) return false;
|
|
2974
|
+
|
|
2979
2975
|
this.allSquares("removeHint");
|
|
2980
2976
|
|
|
2981
2977
|
if (this.config.onlyLegalMoves && !move.isLegal(this.game)) return false;
|
|
@@ -3030,7 +3026,7 @@ var Chessboard = (function () {
|
|
|
3030
3026
|
return this.game.moves({ verbose: verb });
|
|
3031
3027
|
}
|
|
3032
3028
|
|
|
3033
|
-
move(move, animation) {
|
|
3029
|
+
move(move, animation = true) {
|
|
3034
3030
|
move = this.convertMove(move);
|
|
3035
3031
|
move.check();
|
|
3036
3032
|
|
|
@@ -3201,36 +3197,60 @@ var Chessboard = (function () {
|
|
|
3201
3197
|
}
|
|
3202
3198
|
|
|
3203
3199
|
setOrientation(color, animation = true) {
|
|
3204
|
-
if (
|
|
3205
|
-
this.config.orientation
|
|
3206
|
-
|
|
3200
|
+
if (['w', 'b'].includes(color)) {
|
|
3201
|
+
if (color !== this.config.orientation) {
|
|
3202
|
+
this.flip(animation);
|
|
3203
|
+
}
|
|
3207
3204
|
} else {
|
|
3208
3205
|
throw new Error(this.error_messages['invalid_orientation'] + color);
|
|
3209
3206
|
}
|
|
3210
3207
|
}
|
|
3211
3208
|
|
|
3209
|
+
highlight(squareId) {
|
|
3210
|
+
let square = this.convertSquare(squareId);
|
|
3211
|
+
square.check();
|
|
3212
|
+
square.highlight();
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
dehighlight(squareId) {
|
|
3216
|
+
let square = this.convertSquare(squareId);
|
|
3217
|
+
square.check();
|
|
3218
|
+
square.dehighlight();
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3212
3221
|
lastMove() {
|
|
3213
3222
|
const moves = this.history({ verbose: true });
|
|
3214
3223
|
return moves[moves.length - 1];
|
|
3215
3224
|
}
|
|
3216
3225
|
|
|
3217
|
-
flip(
|
|
3218
|
-
this.
|
|
3219
|
-
this.
|
|
3220
|
-
this.
|
|
3226
|
+
flip() {
|
|
3227
|
+
this.config.orientation = this.config.orientation === 'w' ? 'b' : 'w';
|
|
3228
|
+
this.destroy();
|
|
3229
|
+
this.initParams();
|
|
3230
|
+
this.build();
|
|
3221
3231
|
}
|
|
3222
3232
|
|
|
3223
3233
|
build() {
|
|
3224
|
-
if (this.
|
|
3234
|
+
if (this.element) this.destroy();
|
|
3225
3235
|
this.init();
|
|
3226
3236
|
}
|
|
3227
3237
|
|
|
3238
|
+
destroy() {
|
|
3239
|
+
this.removeSquares();
|
|
3240
|
+
this.removeBoard();
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3228
3243
|
ascii() {
|
|
3229
3244
|
return this.game.ascii();
|
|
3230
3245
|
}
|
|
3231
3246
|
|
|
3232
3247
|
board() {
|
|
3233
|
-
|
|
3248
|
+
let dict = {};
|
|
3249
|
+
for (let squareId in this.squares) {
|
|
3250
|
+
let piece = this.getGamePieceId(squareId);
|
|
3251
|
+
if (piece) dict[squareId] = piece;
|
|
3252
|
+
}
|
|
3253
|
+
return dict;
|
|
3234
3254
|
}
|
|
3235
3255
|
|
|
3236
3256
|
clear(options = {}, animation = true) {
|
|
@@ -3245,7 +3265,7 @@ var Chessboard = (function () {
|
|
|
3245
3265
|
get(squareId) {
|
|
3246
3266
|
const square = this.convertSquare(squareId);
|
|
3247
3267
|
square.check();
|
|
3248
|
-
return square.piece;
|
|
3268
|
+
return square.piece;
|
|
3249
3269
|
}
|
|
3250
3270
|
|
|
3251
3271
|
getCastlingRights(color) {
|
|
@@ -3292,9 +3312,9 @@ var Chessboard = (function () {
|
|
|
3292
3312
|
return this.game.isThreefoldRepetition();
|
|
3293
3313
|
}
|
|
3294
3314
|
|
|
3295
|
-
load(
|
|
3315
|
+
load(position, options = {}, animation = true) {
|
|
3296
3316
|
this.clearSquares();
|
|
3297
|
-
this.
|
|
3317
|
+
this.setGame(position, options);
|
|
3298
3318
|
this.updateBoardPieces(animation);
|
|
3299
3319
|
}
|
|
3300
3320
|
|
|
@@ -3317,7 +3337,8 @@ var Chessboard = (function () {
|
|
|
3317
3337
|
}
|
|
3318
3338
|
|
|
3319
3339
|
put(pieceId, squareId, animation = true) {
|
|
3320
|
-
const
|
|
3340
|
+
const [type, color] = pieceId.split('');
|
|
3341
|
+
const success = this.game.put({ type: type, color: color }, squareId);
|
|
3321
3342
|
if (success) this.updateBoardPieces(animation);
|
|
3322
3343
|
return success;
|
|
3323
3344
|
}
|
|
@@ -3356,7 +3377,7 @@ var Chessboard = (function () {
|
|
|
3356
3377
|
setHeader(key, value) {
|
|
3357
3378
|
return this.game.setHeader(key, value);
|
|
3358
3379
|
}
|
|
3359
|
-
|
|
3380
|
+
|
|
3360
3381
|
squareColor(squareId) {
|
|
3361
3382
|
return this.game.squareColor(squareId);
|
|
3362
3383
|
}
|
|
@@ -3397,4 +3418,5 @@ var Chessboard = (function () {
|
|
|
3397
3418
|
return Chessboard;
|
|
3398
3419
|
|
|
3399
3420
|
})();
|
|
3400
|
-
|
|
3421
|
+
|
|
3422
|
+
window.Chessboard.Chessboard = Chessboard;
|
package/chessboard.config.js
CHANGED
|
@@ -19,7 +19,8 @@ const transitionFunctions = {
|
|
|
19
19
|
'linear': 'linear',
|
|
20
20
|
'ease-in': 'ease-in',
|
|
21
21
|
'ease-out': 'ease-out',
|
|
22
|
-
'ease-in-out': 'ease-in-out'
|
|
22
|
+
'ease-in-out': 'ease-in-out',
|
|
23
|
+
'none': null
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
class ChessboardConfig {
|
|
@@ -73,9 +74,6 @@ class ChessboardConfig {
|
|
|
73
74
|
this.dropOffBoard = config.dropOffBoard;
|
|
74
75
|
this.size = config.size;
|
|
75
76
|
this.movableColors = config.movableColors;
|
|
76
|
-
this.moveAnimation = config.moveAnimation;
|
|
77
|
-
this.snapbackAnimation = config.snapbackAnimation;
|
|
78
|
-
this.fadeAnimation = config.fadeAnimation;
|
|
79
77
|
this.piecesPath = config.piecesPath;
|
|
80
78
|
this.onMove = config.onMove;
|
|
81
79
|
this.onMoveEnd = config.onMoveEnd;
|
|
@@ -85,6 +83,10 @@ class ChessboardConfig {
|
|
|
85
83
|
this.onDrop = config.onDrop;
|
|
86
84
|
this.onSnapbackEnd = config.onSnapbackEnd;
|
|
87
85
|
|
|
86
|
+
this.moveAnimation = this.setTransitionFunction(config.moveAnimation);
|
|
87
|
+
this.snapbackAnimation = this.setTransitionFunction(config.snapbackAnimation);
|
|
88
|
+
this.fadeAnimation = this.setTransitionFunction(config.fadeAnimation);
|
|
89
|
+
|
|
88
90
|
this.hints = this.setBoolean(config.hints);
|
|
89
91
|
this.clickable = this.setBoolean(config.clickable);
|
|
90
92
|
this.draggable = this.setBoolean(config.draggable);
|
|
@@ -137,7 +139,7 @@ class ChessboardConfig {
|
|
|
137
139
|
}
|
|
138
140
|
|
|
139
141
|
setTransitionFunction(value) {
|
|
140
|
-
if (transitionFunctions
|
|
142
|
+
if (Object.keys(transitionFunctions).indexOf(value) !== -1) return transitionFunctions[value];
|
|
141
143
|
throw new Error('Invalid transition function');
|
|
142
144
|
}
|
|
143
145
|
}
|
package/chessboard.js
CHANGED
|
@@ -65,7 +65,7 @@ class Chessboard {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
initParams() {
|
|
68
|
-
this.
|
|
68
|
+
this.element = null;
|
|
69
69
|
this.squares = {};
|
|
70
70
|
this.promoting = false;
|
|
71
71
|
this.clicked = null;
|
|
@@ -77,12 +77,12 @@ class Chessboard {
|
|
|
77
77
|
// Board Setup
|
|
78
78
|
// -------------------
|
|
79
79
|
buildBoard() {
|
|
80
|
-
this.
|
|
81
|
-
if (!this.
|
|
80
|
+
this.element = document.getElementById(this.config.id_div);
|
|
81
|
+
if (!this.element) {
|
|
82
82
|
throw new Error(this.error_messages['invalid_id_div'] + this.config.id_div);
|
|
83
83
|
}
|
|
84
84
|
this.resize(this.config.size);
|
|
85
|
-
this.
|
|
85
|
+
this.element.className = "board";
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
buildSquares() {
|
|
@@ -94,19 +94,19 @@ class Chessboard {
|
|
|
94
94
|
let square = new Square(square_row, square_col);
|
|
95
95
|
this.squares[square.getId()] = square;
|
|
96
96
|
|
|
97
|
-
this.
|
|
97
|
+
this.element.appendChild(square.element);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
removeBoard() {
|
|
103
103
|
|
|
104
|
-
this.
|
|
104
|
+
this.element.innerHTML = '';
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
removeSquares() {
|
|
108
108
|
for (const square of Object.values(this.squares)) {
|
|
109
|
-
this.
|
|
109
|
+
this.element.removeChild(square.element);
|
|
110
110
|
square.destroy();
|
|
111
111
|
|
|
112
112
|
}
|
|
@@ -116,12 +116,12 @@ class Chessboard {
|
|
|
116
116
|
resize(value) {
|
|
117
117
|
if (value === 'auto') {
|
|
118
118
|
let size;
|
|
119
|
-
if (this.
|
|
120
|
-
size = this.
|
|
121
|
-
} else if (this.
|
|
122
|
-
size = this.
|
|
119
|
+
if (this.element.offsetWidth === 0) {
|
|
120
|
+
size = this.element.offsetHeight;
|
|
121
|
+
} else if (this.element.offsetHeight === 0) {
|
|
122
|
+
size = this.element.offsetWidth;
|
|
123
123
|
} else {
|
|
124
|
-
size = Math.min(this.
|
|
124
|
+
size = Math.min(this.element.offsetWidth, this.element.offsetHeight);
|
|
125
125
|
}
|
|
126
126
|
this.resize(size);
|
|
127
127
|
} else if (typeof value !== 'number') {
|
|
@@ -137,7 +137,7 @@ class Chessboard {
|
|
|
137
137
|
// -------------------
|
|
138
138
|
convertFen(position) {
|
|
139
139
|
if (typeof position === 'string') {
|
|
140
|
-
|
|
140
|
+
if (position == 'start') return 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
|
|
141
141
|
if (this.validateFen(position)) return position;
|
|
142
142
|
else if (this.standard_positions[position]) return this.standard_positions[position];
|
|
143
143
|
else throw new Error('Invalid position -' + position);
|
|
@@ -164,15 +164,16 @@ class Chessboard {
|
|
|
164
164
|
if (empty > 0) rowParts.push(empty);
|
|
165
165
|
parts.push(rowParts.join(''));
|
|
166
166
|
}
|
|
167
|
-
return parts.join('/')
|
|
167
|
+
return parts.join('/') + ' w KQkq - 0 1';;
|
|
168
168
|
} else {
|
|
169
169
|
throw new Error('Invalid position -' + position);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
setGame(position) {
|
|
173
|
+
setGame(position, options = undefined) {
|
|
174
174
|
const fen = this.convertFen(position);
|
|
175
|
-
this.game
|
|
175
|
+
if (this.game) this.game.load(fen, options);
|
|
176
|
+
else this.game = new Chess(fen);
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
// -------------------
|
|
@@ -252,7 +253,7 @@ class Chessboard {
|
|
|
252
253
|
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
snapbackPiece(square, animate) {
|
|
256
|
+
snapbackPiece(square, animate = this.config.snapbackAnimation) {
|
|
256
257
|
let move = new Move(square, square);
|
|
257
258
|
this.translatePiece(move, false, animate);
|
|
258
259
|
}
|
|
@@ -263,11 +264,15 @@ class Chessboard {
|
|
|
263
264
|
updateBoardPieces(animation = false) {
|
|
264
265
|
let { updatedFlags, escapeFlags, movableFlags, pendingTranslations } = this.prepareBoardUpdateData();
|
|
265
266
|
|
|
267
|
+
let change = Object.values(updatedFlags).some(flag => !flag);
|
|
268
|
+
|
|
266
269
|
this.identifyPieceTranslations(updatedFlags, escapeFlags, movableFlags, pendingTranslations);
|
|
267
270
|
|
|
268
271
|
this.executePieceTranslations(pendingTranslations, escapeFlags, animation);
|
|
269
272
|
|
|
270
273
|
this.processRemainingPieceUpdates(updatedFlags, animation);
|
|
274
|
+
|
|
275
|
+
if (change) this.config.onChange(this.fen());
|
|
271
276
|
}
|
|
272
277
|
|
|
273
278
|
prepareBoardUpdateData() {
|
|
@@ -395,9 +400,8 @@ class Chessboard {
|
|
|
395
400
|
event.preventDefault();
|
|
396
401
|
|
|
397
402
|
if (!this.config.draggable || !piece) return;
|
|
398
|
-
if (!this.config.onDragStart(square, piece)) return;
|
|
399
403
|
|
|
400
|
-
let prec;
|
|
404
|
+
let prec, moved;
|
|
401
405
|
let from = square;
|
|
402
406
|
let to = square;
|
|
403
407
|
|
|
@@ -405,7 +409,7 @@ class Chessboard {
|
|
|
405
409
|
|
|
406
410
|
if (!this.canMove(from)) return;
|
|
407
411
|
if (!this.config.clickable) this.clicked = null;
|
|
408
|
-
if (this.onClick(from)) return;
|
|
412
|
+
if (this.onClick(from, true, true)) return;
|
|
409
413
|
|
|
410
414
|
img.style.position = 'absolute';
|
|
411
415
|
img.style.zIndex = 100;
|
|
@@ -419,10 +423,11 @@ class Chessboard {
|
|
|
419
423
|
};
|
|
420
424
|
|
|
421
425
|
const onMouseMove = (event) => {
|
|
426
|
+
if (!this.config.onDragStart(square, piece)) return;
|
|
422
427
|
if (!moveAt(event.pageX, event.pageY)) return;
|
|
423
428
|
|
|
424
|
-
const boardRect = this.
|
|
425
|
-
const { offsetWidth: boardWidth, offsetHeight: boardHeight } = this.
|
|
429
|
+
const boardRect = this.element.getBoundingClientRect();
|
|
430
|
+
const { offsetWidth: boardWidth, offsetHeight: boardHeight } = this.element;
|
|
426
431
|
const x = event.clientX - boardRect.left;
|
|
427
432
|
const y = event.clientY - boardRect.top;
|
|
428
433
|
|
|
@@ -457,9 +462,9 @@ class Chessboard {
|
|
|
457
462
|
this.allSquares('removeHint');
|
|
458
463
|
from.deselect();
|
|
459
464
|
this.remove(from);
|
|
460
|
-
} else if (!to || !this.onClick(to, true)) {
|
|
461
|
-
this.snapbackPiece(from
|
|
462
|
-
this.config.onSnapbackEnd(from, piece);
|
|
465
|
+
} else if (!to || !this.onClick(to, true, true)) {
|
|
466
|
+
this.snapbackPiece(from);
|
|
467
|
+
if (to !== from) this.config.onSnapbackEnd(from, piece);
|
|
463
468
|
}
|
|
464
469
|
};
|
|
465
470
|
|
|
@@ -486,14 +491,14 @@ class Chessboard {
|
|
|
486
491
|
if (this.config.clickable && (!piece || this.config.onlyLegalMoves)) this.onClick(square)
|
|
487
492
|
}
|
|
488
493
|
|
|
489
|
-
square.element.addEventListener("
|
|
494
|
+
square.element.addEventListener("mousedown", handleClick);
|
|
490
495
|
square.element.addEventListener("touch", handleClick);
|
|
491
496
|
}
|
|
492
497
|
}
|
|
493
498
|
|
|
494
|
-
onClick(square, animation = this.config.moveAnimation) {
|
|
495
|
-
|
|
496
|
-
if (
|
|
499
|
+
onClick(square, animation = this.config.moveAnimation, dragged = false) {
|
|
500
|
+
|
|
501
|
+
if (this.clicked === square) return false;
|
|
497
502
|
|
|
498
503
|
let from = this.clicked;
|
|
499
504
|
this.clicked = null;
|
|
@@ -512,19 +517,22 @@ class Chessboard {
|
|
|
512
517
|
if (!from) {
|
|
513
518
|
|
|
514
519
|
if (this.canMove(square)) {
|
|
515
|
-
|
|
516
|
-
|
|
520
|
+
if (this.config.clickable) {
|
|
521
|
+
square.select();
|
|
522
|
+
this.hintMoves(square);
|
|
523
|
+
}
|
|
517
524
|
this.clicked = square;
|
|
518
525
|
}
|
|
519
526
|
|
|
520
527
|
return false;
|
|
521
528
|
}
|
|
522
529
|
|
|
523
|
-
if (!this.canMove(from)) return false;
|
|
524
|
-
|
|
525
530
|
let move = new Move(from, square, promotion);
|
|
526
531
|
|
|
527
532
|
move.from.deselect();
|
|
533
|
+
|
|
534
|
+
if (!move.check()) return false;
|
|
535
|
+
|
|
528
536
|
this.allSquares("removeHint");
|
|
529
537
|
|
|
530
538
|
if (this.config.onlyLegalMoves && !move.isLegal(this.game)) return false;
|
|
@@ -579,7 +587,7 @@ class Chessboard {
|
|
|
579
587
|
return this.game.moves({ verbose: verb });
|
|
580
588
|
}
|
|
581
589
|
|
|
582
|
-
move(move, animation) {
|
|
590
|
+
move(move, animation = true) {
|
|
583
591
|
move = this.convertMove(move);
|
|
584
592
|
move.check();
|
|
585
593
|
|
|
@@ -750,14 +758,27 @@ class Chessboard {
|
|
|
750
758
|
}
|
|
751
759
|
|
|
752
760
|
setOrientation(color, animation = true) {
|
|
753
|
-
if (
|
|
754
|
-
this.config.orientation
|
|
755
|
-
|
|
761
|
+
if (['w', 'b'].includes(color)) {
|
|
762
|
+
if (color !== this.config.orientation) {
|
|
763
|
+
this.flip(animation);
|
|
764
|
+
}
|
|
756
765
|
} else {
|
|
757
766
|
throw new Error(this.error_messages['invalid_orientation'] + color);
|
|
758
767
|
}
|
|
759
768
|
}
|
|
760
769
|
|
|
770
|
+
highlight(squareId) {
|
|
771
|
+
let square = this.convertSquare(squareId);
|
|
772
|
+
square.check();
|
|
773
|
+
square.highlight();
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
dehighlight(squareId) {
|
|
777
|
+
let square = this.convertSquare(squareId);
|
|
778
|
+
square.check();
|
|
779
|
+
square.dehighlight();
|
|
780
|
+
}
|
|
781
|
+
|
|
761
782
|
lastMove() {
|
|
762
783
|
const moves = this.history({ verbose: true });
|
|
763
784
|
return moves[moves.length - 1];
|
|
@@ -771,7 +792,7 @@ class Chessboard {
|
|
|
771
792
|
}
|
|
772
793
|
|
|
773
794
|
build() {
|
|
774
|
-
if (this.
|
|
795
|
+
if (this.element) this.destroy();
|
|
775
796
|
this.init();
|
|
776
797
|
}
|
|
777
798
|
|
|
@@ -785,7 +806,12 @@ class Chessboard {
|
|
|
785
806
|
}
|
|
786
807
|
|
|
787
808
|
board() {
|
|
788
|
-
|
|
809
|
+
let dict = {};
|
|
810
|
+
for (let squareId in this.squares) {
|
|
811
|
+
let piece = this.getGamePieceId(squareId);
|
|
812
|
+
if (piece) dict[squareId] = piece;
|
|
813
|
+
}
|
|
814
|
+
return dict;
|
|
789
815
|
}
|
|
790
816
|
|
|
791
817
|
clear(options = {}, animation = true) {
|
|
@@ -800,7 +826,7 @@ class Chessboard {
|
|
|
800
826
|
get(squareId) {
|
|
801
827
|
const square = this.convertSquare(squareId);
|
|
802
828
|
square.check();
|
|
803
|
-
return square.piece;
|
|
829
|
+
return square.piece;
|
|
804
830
|
}
|
|
805
831
|
|
|
806
832
|
getCastlingRights(color) {
|
|
@@ -847,9 +873,9 @@ class Chessboard {
|
|
|
847
873
|
return this.game.isThreefoldRepetition();
|
|
848
874
|
}
|
|
849
875
|
|
|
850
|
-
load(
|
|
876
|
+
load(position, options = {}, animation = true) {
|
|
851
877
|
this.clearSquares();
|
|
852
|
-
this.
|
|
878
|
+
this.setGame(position, options);
|
|
853
879
|
this.updateBoardPieces(animation);
|
|
854
880
|
}
|
|
855
881
|
|
|
@@ -912,7 +938,7 @@ class Chessboard {
|
|
|
912
938
|
setHeader(key, value) {
|
|
913
939
|
return this.game.setHeader(key, value);
|
|
914
940
|
}
|
|
915
|
-
|
|
941
|
+
|
|
916
942
|
squareColor(squareId) {
|
|
917
943
|
return this.game.squareColor(squareId);
|
|
918
944
|
}
|
package/chessboard.move.js
CHANGED
|
@@ -21,27 +21,15 @@ class Move {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
check() {
|
|
24
|
-
if (this.piece === null)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (!(this.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!(this.from instanceof Square)) {
|
|
34
|
-
throw new Error("Invalid move: from is not an instance of Square");
|
|
35
|
-
}
|
|
36
|
-
if (!(this.to instanceof Square)) {
|
|
37
|
-
throw new Error("Invalid move: to is not an instance of Square");
|
|
38
|
-
}
|
|
39
|
-
if (!this.to) {
|
|
40
|
-
throw new Error("Invalid move: to is null or undefined");
|
|
41
|
-
}
|
|
42
|
-
if (!this.from) {
|
|
43
|
-
throw new Error("Invalid move: from is null or undefined");
|
|
44
|
-
}
|
|
24
|
+
if (this.piece === null) return false;
|
|
25
|
+
if (!(this.piece instanceof Piece)) return false;
|
|
26
|
+
if (['q', 'r', 'b', 'n', null].indexOf(this.promotion) === -1) return false;
|
|
27
|
+
if (!(this.from instanceof Square)) return false;
|
|
28
|
+
if (!(this.to instanceof Square)) return false;
|
|
29
|
+
if (!this.to) return false;
|
|
30
|
+
if (!this.from) return false;
|
|
31
|
+
if (this.from === this.to) return false;
|
|
32
|
+
return true;
|
|
45
33
|
}
|
|
46
34
|
|
|
47
35
|
isLegal(game) {
|
package/chessboard.piece.js
CHANGED