cm-chessboard 7.5.0 → 7.6.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 +2 -2
- package/examples/validate-moves.html +9 -4
- package/package.json +1 -1
- package/src/Chessboard.js +3 -2
- package/src/extensions/promotion-dialog/PromotionDialog.js +3 -3
- package/src/model/Position.js +8 -18
- package/src/view/ChessboardView.js +17 -7
- package/src/view/PositionAnimationsQueue.js +1 -1
- package/src/view/VisualMoveInput.js +28 -23
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ this.props = {
|
|
|
91
91
|
borderType: BORDER_TYPE.none, // "thin" thin border, "frame" wide border with coordinates in it, "none" no border
|
|
92
92
|
aspectRatio: 1, // height/width of the board
|
|
93
93
|
pieces: {
|
|
94
|
-
type: PIECES_FILE_TYPE.svgSprite, // pieces are in
|
|
94
|
+
type: PIECES_FILE_TYPE.svgSprite, // pieces are in an SVG sprite, no other type supported for now
|
|
95
95
|
file: "standard.svg", // the filename of the sprite in `assets/pieces/`
|
|
96
96
|
tileSize: 40 // the tile size in the sprite
|
|
97
97
|
},
|
|
@@ -119,7 +119,7 @@ after the animation finished.
|
|
|
119
119
|
|
|
120
120
|
### getPiece(square)
|
|
121
121
|
|
|
122
|
-
Returns the piece on a square or `
|
|
122
|
+
Returns the piece on a square or `null` if the square is empty.
|
|
123
123
|
|
|
124
124
|
### movePiece(squareFrom, squareTo, animated = false)
|
|
125
125
|
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function inputHandler(event) {
|
|
42
|
+
console.log("inputHandler", event)
|
|
43
|
+
console.log("fen", event.chessboard.getPosition())
|
|
42
44
|
event.chessboard.removeMarkers(MARKER_TYPE.dot)
|
|
43
45
|
event.chessboard.removeMarkers(MARKER_TYPE.bevel)
|
|
44
46
|
if (event.type === INPUT_EVENT_TYPE.moveInputStarted) {
|
|
@@ -58,7 +60,6 @@
|
|
|
58
60
|
const move = {from: event.squareFrom, to: event.squareTo, promotion: event.promotion}
|
|
59
61
|
const result = chess.move(move)
|
|
60
62
|
if (result) {
|
|
61
|
-
event.chessboard.disableMoveInput()
|
|
62
63
|
this.chessboard.state.moveInputProcess.then(() => { // wait for the move input process has finished
|
|
63
64
|
this.chessboard.setPosition(chess.fen(), true).then(() => { // update position, maybe castled and wait for animation has finished
|
|
64
65
|
makeEngineMove(event.chessboard)
|
|
@@ -74,11 +75,11 @@
|
|
|
74
75
|
if (result) {
|
|
75
76
|
chess.move({from: event.squareFrom, to: event.squareTo, promotion: result.piece.charAt(1)})
|
|
76
77
|
event.chessboard.setPosition(chess.fen(), true)
|
|
77
|
-
event.chessboard.disableMoveInput()
|
|
78
78
|
makeEngineMove(event.chessboard)
|
|
79
79
|
} else {
|
|
80
|
-
|
|
80
|
+
// promotion canceled
|
|
81
81
|
event.chessboard.enableMoveInput(inputHandler, COLOR.white)
|
|
82
|
+
event.chessboard.setPosition(chess.fen(), true)
|
|
82
83
|
}
|
|
83
84
|
})
|
|
84
85
|
return true
|
|
@@ -86,13 +87,17 @@
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
return result
|
|
90
|
+
} else if (event.type === INPUT_EVENT_TYPE.moveInputFinished) {
|
|
91
|
+
if(event.legalMove) {
|
|
92
|
+
event.chessboard.disableMoveInput()
|
|
93
|
+
}
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
const board = new Chessboard(document.getElementById("board"), {
|
|
93
98
|
position: chess.fen(),
|
|
94
99
|
assetsUrl: "../assets/",
|
|
95
|
-
style: {borderType: BORDER_TYPE.none, pieces: {file: "staunty.svg"}},
|
|
100
|
+
style: {borderType: BORDER_TYPE.none, pieces: {file: "staunty.svg"}, animationDuration: 300},
|
|
96
101
|
orientation: COLOR.white,
|
|
97
102
|
extensions: [
|
|
98
103
|
{class: Markers, props: {autoMarkers: MARKER_TYPE.square}},
|
package/package.json
CHANGED
package/src/Chessboard.js
CHANGED
|
@@ -19,7 +19,8 @@ export const INPUT_EVENT_TYPE = {
|
|
|
19
19
|
moveInputStarted: "moveInputStarted",
|
|
20
20
|
movingOverSquare: "movingOverSquare", // while dragging or hover after click
|
|
21
21
|
validateMoveInput: "validateMoveInput",
|
|
22
|
-
moveInputCanceled: "moveInputCanceled"
|
|
22
|
+
moveInputCanceled: "moveInputCanceled",
|
|
23
|
+
moveInputFinished: "moveInputFinished"
|
|
23
24
|
}
|
|
24
25
|
export const SQUARE_SELECT_TYPE = {
|
|
25
26
|
primary: "primary",
|
|
@@ -63,7 +64,7 @@ export class Chessboard {
|
|
|
63
64
|
borderType: BORDER_TYPE.none, // "thin" thin border, "frame" wide border with coordinates in it, "none" no border
|
|
64
65
|
aspectRatio: 1, // height/width of the board
|
|
65
66
|
pieces: {
|
|
66
|
-
type: PIECES_FILE_TYPE.svgSprite, // pieces are in
|
|
67
|
+
type: PIECES_FILE_TYPE.svgSprite, // pieces are in an SVG sprite, no other type supported for now
|
|
67
68
|
file: "standard.svg", // the filename of the sprite in `assets/pieces/`
|
|
68
69
|
tileSize: 40 // the tile size in the sprite
|
|
69
70
|
},
|
|
@@ -25,10 +25,10 @@ export class PromotionDialog extends Extension {
|
|
|
25
25
|
this.promotionDialogGroup = Svg.addElement(chessboard.view.interactiveTopLayer, "g", {class: "promotion-dialog-group"})
|
|
26
26
|
this.state = {
|
|
27
27
|
displayState: DISPLAY_STATE.hidden,
|
|
28
|
-
callback:
|
|
28
|
+
callback: null,
|
|
29
29
|
dialogParams: {
|
|
30
|
-
square:
|
|
31
|
-
color:
|
|
30
|
+
square: null,
|
|
31
|
+
color: null
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/model/Position.js
CHANGED
|
@@ -10,23 +10,13 @@ export const FEN = {
|
|
|
10
10
|
|
|
11
11
|
export class Position {
|
|
12
12
|
|
|
13
|
-
constructor(fen =
|
|
13
|
+
constructor(fen = FEN.empty) {
|
|
14
14
|
this.squares = new Array(64).fill(null)
|
|
15
15
|
this.setFen(fen)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
setFen(fen = FEN.empty) {
|
|
19
|
-
|
|
20
|
-
if (fen === "start") {
|
|
21
|
-
console.warn("setting the position with the strings 'start' or 'empty' is deprecated, use FEN.start or FEN.empty", "used:", fen)
|
|
22
|
-
fenNormalized = FEN.start
|
|
23
|
-
} else if (fen === "empty" || fen === undefined) {
|
|
24
|
-
console.warn("setting the position with the strings 'start' or 'empty' is deprecated, use FEN.start or FEN.empty", "used:", fen)
|
|
25
|
-
fenNormalized = FEN.empty
|
|
26
|
-
} else {
|
|
27
|
-
fenNormalized = fen
|
|
28
|
-
}
|
|
29
|
-
const parts = fenNormalized.replace(/^\s*/, "").replace(/\s*$/, "").split(/\/|\s/)
|
|
19
|
+
const parts = fen.replace(/^\s*/, "").replace(/\s*$/, "").split(/\/|\s/)
|
|
30
20
|
for (let part = 0; part < 8; part++) {
|
|
31
21
|
const row = parts[7 - part].replace(/\d/g, (str) => {
|
|
32
22
|
const numSpaces = parseInt(str)
|
|
@@ -86,29 +76,29 @@ export class Position {
|
|
|
86
76
|
const sort = (a, b) => {
|
|
87
77
|
return sortBy.indexOf(a.name) - sortBy.indexOf(b.name)
|
|
88
78
|
}
|
|
89
|
-
for(let i=0; i<64; i++) {
|
|
79
|
+
for (let i = 0; i < 64; i++) {
|
|
90
80
|
const piece = this.squares[i]
|
|
91
|
-
if(piece) {
|
|
81
|
+
if (piece) {
|
|
92
82
|
pieces.push({
|
|
93
83
|
name: piece.charAt(1),
|
|
94
|
-
color:
|
|
84
|
+
color: piece.charAt(0),
|
|
95
85
|
position: Position.indexToSquare(i)
|
|
96
86
|
})
|
|
97
87
|
}
|
|
98
88
|
}
|
|
99
|
-
if(sortBy) {
|
|
89
|
+
if (sortBy) {
|
|
100
90
|
pieces.sort(sort)
|
|
101
91
|
}
|
|
102
92
|
return pieces
|
|
103
93
|
}
|
|
104
94
|
|
|
105
95
|
movePiece(squareFrom, squareTo) {
|
|
106
|
-
if(!this.squares[Position.squareToIndex(squareFrom)]) {
|
|
96
|
+
if (!this.squares[Position.squareToIndex(squareFrom)]) {
|
|
107
97
|
console.warn("no piece on", squareFrom)
|
|
108
98
|
return
|
|
109
99
|
}
|
|
110
100
|
this.squares[Position.squareToIndex(squareTo)] = this.squares[Position.squareToIndex(squareFrom)]
|
|
111
|
-
this.squares[Position.squareToIndex(squareFrom)] =
|
|
101
|
+
this.squares[Position.squareToIndex(squareFrom)] = null
|
|
112
102
|
}
|
|
113
103
|
|
|
114
104
|
setPiece(square, piece) {
|
|
@@ -13,11 +13,7 @@ import {Svg} from "../lib/Svg.js"
|
|
|
13
13
|
export class ChessboardView {
|
|
14
14
|
constructor(chessboard) {
|
|
15
15
|
this.chessboard = chessboard
|
|
16
|
-
this.visualMoveInput = new VisualMoveInput(this
|
|
17
|
-
this.moveInputStartedCallback.bind(this),
|
|
18
|
-
this.movingOverSquareCallback.bind(this),
|
|
19
|
-
this.validateMoveInputCallback.bind(this),
|
|
20
|
-
this.moveInputCanceledCallback.bind(this))
|
|
16
|
+
this.visualMoveInput = new VisualMoveInput(this)
|
|
21
17
|
if (chessboard.props.assetsCache) {
|
|
22
18
|
this.cacheSpriteToDiv("cm-chessboard-sprite", this.getSpriteUrl())
|
|
23
19
|
}
|
|
@@ -306,7 +302,7 @@ export class ChessboardView {
|
|
|
306
302
|
|
|
307
303
|
// enable and disable move input //
|
|
308
304
|
|
|
309
|
-
enableMoveInput(eventHandler, color =
|
|
305
|
+
enableMoveInput(eventHandler, color = null) {
|
|
310
306
|
if (this.moveInputCallback) {
|
|
311
307
|
throw Error("moveInput already enabled")
|
|
312
308
|
}
|
|
@@ -328,7 +324,7 @@ export class ChessboardView {
|
|
|
328
324
|
this.chessboard.state.inputWhiteEnabled = false
|
|
329
325
|
this.chessboard.state.inputBlackEnabled = false
|
|
330
326
|
this.chessboard.state.inputEnabled = false
|
|
331
|
-
this.moveInputCallback =
|
|
327
|
+
this.moveInputCallback = null
|
|
332
328
|
this.chessboard.state.invokeExtensionPoints(EXTENSION_POINT.moveInputToggled, {enabled: false})
|
|
333
329
|
this.visualizeInputState()
|
|
334
330
|
}
|
|
@@ -395,6 +391,20 @@ export class ChessboardView {
|
|
|
395
391
|
}
|
|
396
392
|
}
|
|
397
393
|
|
|
394
|
+
moveInputFinishedCallback(squareFrom, squareTo, legalMove) {
|
|
395
|
+
const data = {
|
|
396
|
+
chessboard: this.chessboard,
|
|
397
|
+
type: INPUT_EVENT_TYPE.moveInputFinished,
|
|
398
|
+
squareFrom: squareFrom,
|
|
399
|
+
squareTo: squareTo,
|
|
400
|
+
legalMove: legalMove
|
|
401
|
+
}
|
|
402
|
+
this.chessboard.state.invokeExtensionPoints(EXTENSION_POINT.moveInput, data)
|
|
403
|
+
if (this.moveInputCallback) {
|
|
404
|
+
this.moveInputCallback(data)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
398
408
|
// Helpers //
|
|
399
409
|
|
|
400
410
|
visualizeInputState() {
|
|
@@ -110,7 +110,7 @@ export class PositionsAnimation {
|
|
|
110
110
|
}
|
|
111
111
|
appearedList.forEach((appeared) => {
|
|
112
112
|
let shortestDistance = 8
|
|
113
|
-
let foundMoved =
|
|
113
|
+
let foundMoved = null
|
|
114
114
|
disappearedList.forEach((disappeared) => {
|
|
115
115
|
if (appeared.piece === disappeared.piece) {
|
|
116
116
|
const moveDistance = PositionsAnimation.squareDistance(appeared.index, disappeared.index)
|
|
@@ -30,27 +30,32 @@ const DRAG_THRESHOLD = 4
|
|
|
30
30
|
|
|
31
31
|
export class VisualMoveInput {
|
|
32
32
|
|
|
33
|
-
constructor(view
|
|
33
|
+
constructor(view) {
|
|
34
34
|
this.view = view
|
|
35
35
|
this.chessboard = view.chessboard
|
|
36
36
|
this.moveInputState = null
|
|
37
|
+
this.fromSquare = null
|
|
38
|
+
this.toSquare = null
|
|
37
39
|
this.moveInputStartedCallback = (square) => {
|
|
38
|
-
const result = moveInputStartedCallback(square)
|
|
40
|
+
const result = view.moveInputStartedCallback(square)
|
|
39
41
|
if (result) {
|
|
40
42
|
this.chessboard.state.moveInputProcess = Utils.createTask()
|
|
43
|
+
this.chessboard.state.moveInputProcess.then((result) => {
|
|
44
|
+
view.moveInputFinishedCallback(this.fromSquare, this.toSquare, result)
|
|
45
|
+
})
|
|
41
46
|
}
|
|
42
47
|
return result
|
|
43
48
|
}
|
|
44
49
|
this.movingOverSquareCallback = (fromSquare, toSquare) => {
|
|
45
|
-
movingOverSquareCallback(fromSquare, toSquare)
|
|
50
|
+
view.movingOverSquareCallback(fromSquare, toSquare)
|
|
46
51
|
}
|
|
47
52
|
this.validateMoveInputCallback = (fromSquare, toSquare) => {
|
|
48
|
-
const result = validateMoveInputCallback(fromSquare, toSquare)
|
|
53
|
+
const result = view.validateMoveInputCallback(fromSquare, toSquare)
|
|
49
54
|
this.chessboard.state.moveInputProcess.resolve(result)
|
|
50
55
|
return result
|
|
51
56
|
}
|
|
52
57
|
this.moveInputCanceledCallback = (fromSquare, toSquare, reason) => {
|
|
53
|
-
moveInputCanceledCallback(fromSquare, toSquare, reason)
|
|
58
|
+
view.moveInputCanceledCallback(fromSquare, toSquare, reason)
|
|
54
59
|
this.chessboard.state.moveInputProcess.resolve()
|
|
55
60
|
}
|
|
56
61
|
this.setMoveInputState(MOVE_INPUT_STATE.waitForInputStart)
|
|
@@ -74,14 +79,14 @@ export class VisualMoveInput {
|
|
|
74
79
|
}
|
|
75
80
|
if (this.pointerMoveListener) {
|
|
76
81
|
removeEventListener(this.pointerMoveListener.type, this.pointerMoveListener)
|
|
77
|
-
this.pointerMoveListener =
|
|
82
|
+
this.pointerMoveListener = null
|
|
78
83
|
}
|
|
79
84
|
if (this.pointerUpListener) {
|
|
80
85
|
removeEventListener(this.pointerUpListener.type, this.pointerUpListener)
|
|
81
|
-
this.pointerUpListener =
|
|
86
|
+
this.pointerUpListener = null
|
|
82
87
|
}
|
|
83
88
|
this.fromSquare = params.square
|
|
84
|
-
this.toSquare =
|
|
89
|
+
this.toSquare = null
|
|
85
90
|
this.movedPiece = params.piece
|
|
86
91
|
this.startPoint = params.point
|
|
87
92
|
if (!this.pointerMoveListener && !this.pointerUpListener) {
|
|
@@ -114,7 +119,7 @@ export class VisualMoveInput {
|
|
|
114
119
|
case MOVE_INPUT_STATE.clickTo:
|
|
115
120
|
if (this.draggablePiece) {
|
|
116
121
|
Svg.removeElement(this.draggablePiece)
|
|
117
|
-
this.draggablePiece =
|
|
122
|
+
this.draggablePiece = null
|
|
118
123
|
}
|
|
119
124
|
if (prevState === MOVE_INPUT_STATE.dragTo) {
|
|
120
125
|
this.view.setPieceVisibility(params.square, true)
|
|
@@ -174,24 +179,24 @@ export class VisualMoveInput {
|
|
|
174
179
|
if (this.fromSquare && !this.toSquare && this.movedPiece) {
|
|
175
180
|
this.chessboard.state.position.setPiece(this.fromSquare, this.movedPiece)
|
|
176
181
|
}
|
|
177
|
-
this.fromSquare =
|
|
178
|
-
this.toSquare =
|
|
179
|
-
this.movedPiece =
|
|
182
|
+
this.fromSquare = null
|
|
183
|
+
this.toSquare = null
|
|
184
|
+
this.movedPiece = null
|
|
180
185
|
if (this.draggablePiece) {
|
|
181
186
|
Svg.removeElement(this.draggablePiece)
|
|
182
|
-
this.draggablePiece =
|
|
187
|
+
this.draggablePiece = null
|
|
183
188
|
}
|
|
184
189
|
if (this.pointerMoveListener) {
|
|
185
190
|
removeEventListener(this.pointerMoveListener.type, this.pointerMoveListener)
|
|
186
|
-
this.pointerMoveListener =
|
|
191
|
+
this.pointerMoveListener = null
|
|
187
192
|
}
|
|
188
193
|
if (this.pointerUpListener) {
|
|
189
194
|
removeEventListener(this.pointerUpListener.type, this.pointerUpListener)
|
|
190
|
-
this.pointerUpListener =
|
|
195
|
+
this.pointerUpListener = null
|
|
191
196
|
}
|
|
192
197
|
if (this.contextMenuListener) {
|
|
193
198
|
removeEventListener("contextmenu", this.contextMenuListener)
|
|
194
|
-
this.contextMenuListener =
|
|
199
|
+
this.contextMenuListener = null
|
|
195
200
|
}
|
|
196
201
|
this.setMoveInputState(MOVE_INPUT_STATE.waitForInputStart)
|
|
197
202
|
break
|
|
@@ -235,7 +240,7 @@ export class VisualMoveInput {
|
|
|
235
240
|
// console.log("onPointerDown", square, pieceName)
|
|
236
241
|
let color
|
|
237
242
|
if (pieceName) {
|
|
238
|
-
color = pieceName ? pieceName.substring(0, 1) :
|
|
243
|
+
color = pieceName ? pieceName.substring(0, 1) : null
|
|
239
244
|
// allow scrolling, if not pointed on draggable piece
|
|
240
245
|
if (color === "w" && this.chessboard.state.inputWhiteEnabled ||
|
|
241
246
|
color === "b" && this.chessboard.state.inputBlackEnabled) {
|
|
@@ -268,9 +273,9 @@ export class VisualMoveInput {
|
|
|
268
273
|
})
|
|
269
274
|
} else {
|
|
270
275
|
const pieceName = this.chessboard.getPiece(square)
|
|
271
|
-
const pieceColor = pieceName ? pieceName.substring(0, 1) :
|
|
276
|
+
const pieceColor = pieceName ? pieceName.substring(0, 1) : null
|
|
272
277
|
const startPieceName = this.chessboard.getPiece(this.fromSquare)
|
|
273
|
-
const startPieceColor = startPieceName ? startPieceName.substring(0, 1) :
|
|
278
|
+
const startPieceColor = startPieceName ? startPieceName.substring(0, 1) : null
|
|
274
279
|
if (color && startPieceColor === pieceColor) {
|
|
275
280
|
this.moveInputCanceledCallback(this.fromSquare, square, MOVE_CANCELED_REASON.clickedAnotherPiece)
|
|
276
281
|
if (this.moveInputStartedCallback(square)) {
|
|
@@ -325,13 +330,13 @@ export class VisualMoveInput {
|
|
|
325
330
|
if (square !== this.fromSquare && square !== this.toSquare) {
|
|
326
331
|
this.toSquare = square
|
|
327
332
|
this.movingOverSquareCallback(this.fromSquare, this.toSquare)
|
|
328
|
-
} else if (square === this.fromSquare && this.toSquare !==
|
|
329
|
-
this.toSquare =
|
|
333
|
+
} else if (square === this.fromSquare && this.toSquare !== null) {
|
|
334
|
+
this.toSquare = null
|
|
330
335
|
this.movingOverSquareCallback(this.fromSquare, null)
|
|
331
336
|
}
|
|
332
337
|
} else {
|
|
333
|
-
if (this.toSquare !==
|
|
334
|
-
this.toSquare =
|
|
338
|
+
if (this.toSquare !== null) {
|
|
339
|
+
this.toSquare = null
|
|
335
340
|
this.movingOverSquareCallback(this.fromSquare, null)
|
|
336
341
|
}
|
|
337
342
|
}
|