cm-chessboard 7.9.0 → 7.10.0
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
CHANGED
|
@@ -18,8 +18,8 @@ aspects of chess games.
|
|
|
18
18
|
- [Can handle moves input via click or drag](https://shaack.com/projekte/cm-chessboard/examples/validate-moves.html)
|
|
19
19
|
- [Styleable via css and supports multiple piece sets](https://shaack.com/projekte/cm-chessboard/examples/different-styles.html)
|
|
20
20
|
- Uses SVG for rendering
|
|
21
|
-
- [Allows adding **extensions
|
|
22
|
-
|
|
21
|
+
- [Allows adding **extensions** to extend the
|
|
22
|
+
functionality](https://shaack.com/projekte/cm-chessboard/examples/extensions/arrows-extension.html)
|
|
23
23
|
|
|
24
24
|
## Extensions
|
|
25
25
|
|
|
@@ -88,25 +88,26 @@ Below is the default configuration
|
|
|
88
88
|
|
|
89
89
|
```javascript
|
|
90
90
|
this.props = {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
107
|
-
animationDuration: 300 // pieces animation duration in milliseconds. Disable all animations with `0`.
|
|
91
|
+
position: FEN.empty, // set position as fen, use FEN.start or FEN.empty as shortcuts
|
|
92
|
+
orientation: COLOR.white, // white on bottom
|
|
93
|
+
responsive: true, // resize the board automatically to the size of the context element
|
|
94
|
+
language: navigator.language.substring(0, 2).toLowerCase(), // supports "de" and "en" for now, used for pieces naming
|
|
95
|
+
assetsUrl: "./assets/", // put all css and sprites in this folder, will be ignored for absolute urls of assets files
|
|
96
|
+
assetsCache: true, // cache sprites
|
|
97
|
+
style: {
|
|
98
|
+
cssClass: "default", // set the css theme of the board, try "green", "blue" or "chess-club"
|
|
99
|
+
showCoordinates: true, // show ranks and files
|
|
100
|
+
borderType: BORDER_TYPE.none, // "thin" thin border, "frame" wide border with coordinates in it, "none" no border
|
|
101
|
+
aspectRatio: 1, // height/width of the board
|
|
102
|
+
pieces: {
|
|
103
|
+
type: PIECES_FILE_TYPE.svgSprite, // pieces are in an SVG sprite, no other type supported for now
|
|
104
|
+
file: "pieces/standard.svg", // the filename of the sprite in `assets/pieces/` or an absolute url like `https://…` or `/…`
|
|
105
|
+
tileSize: 40 // the tile size in the sprite
|
|
108
106
|
},
|
|
109
|
-
|
|
107
|
+
// pieces animation duration in milliseconds. Disable all animations with `0`. Respects the operating system settings for reduced motion.
|
|
108
|
+
animationDuration: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? 0 : 300
|
|
109
|
+
},
|
|
110
|
+
extensions: [ /* {class: ExtensionClass, props: { ... }} */] // add extensions here
|
|
110
111
|
}
|
|
111
112
|
```
|
|
112
113
|
|
package/package.json
CHANGED
package/src/Chessboard.js
CHANGED
|
@@ -70,7 +70,8 @@ export class Chessboard {
|
|
|
70
70
|
file: "pieces/standard.svg", // the filename of the sprite in `assets/pieces/` or an absolute url like `https://…` or `/…`
|
|
71
71
|
tileSize: 40 // the tile size in the sprite
|
|
72
72
|
},
|
|
73
|
-
|
|
73
|
+
// pieces animation duration in milliseconds. Disable all animations with `0`. Respects the operating system settings for reduced motion.
|
|
74
|
+
animationDuration: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? 0 : 300
|
|
74
75
|
},
|
|
75
76
|
extensions: [ /* {class: ExtensionClass, props: { ... }} */] // add extensions here
|
|
76
77
|
}
|
|
@@ -122,7 +123,7 @@ export class Chessboard {
|
|
|
122
123
|
async setOrientation(color, animated = false) {
|
|
123
124
|
const position = this.state.position.clone()
|
|
124
125
|
if (this.boardTurning) {
|
|
125
|
-
console.
|
|
126
|
+
console.warn("setOrientation is only once in queue allowed")
|
|
126
127
|
return
|
|
127
128
|
}
|
|
128
129
|
this.boardTurning = true
|
|
@@ -78,10 +78,10 @@ export class Arrows extends Extension {
|
|
|
78
78
|
|
|
79
79
|
const width = ((view.scalingX + view.scalingY) / 2) * 4
|
|
80
80
|
let lineFill = Svg.addElement(arrowsGroup, "line")
|
|
81
|
-
lineFill.setAttribute('x1', x1)
|
|
82
|
-
lineFill.setAttribute('x2', x2)
|
|
83
|
-
lineFill.setAttribute('y1', y1)
|
|
84
|
-
lineFill.setAttribute('y2', y2)
|
|
81
|
+
lineFill.setAttribute('x1', x1.toString())
|
|
82
|
+
lineFill.setAttribute('x2', x2.toString())
|
|
83
|
+
lineFill.setAttribute('y1', y1.toString())
|
|
84
|
+
lineFill.setAttribute('y2', y2.toString())
|
|
85
85
|
lineFill.setAttribute('class', 'arrow-line')
|
|
86
86
|
lineFill.setAttribute("marker-end", "url(#" + id + ")")
|
|
87
87
|
lineFill.setAttribute('stroke-width', width + "px")
|
|
@@ -145,7 +145,6 @@ export class PositionsAnimation {
|
|
|
145
145
|
|
|
146
146
|
createAnimation(fromSquares, toSquares) {
|
|
147
147
|
const changes = PositionsAnimation.seekChanges(fromSquares, toSquares)
|
|
148
|
-
// console.log("changes", changes)
|
|
149
148
|
const animatedElements = []
|
|
150
149
|
changes.forEach((change) => {
|
|
151
150
|
const animatedItem = {
|
|
@@ -172,7 +171,6 @@ export class PositionsAnimation {
|
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
animationStep(time) {
|
|
175
|
-
// console.log("animationStep", time)
|
|
176
174
|
if(!this.view || !this.view.chessboard.state) { // board was destroyed
|
|
177
175
|
return
|
|
178
176
|
}
|
|
@@ -36,38 +36,40 @@ export class VisualMoveInput {
|
|
|
36
36
|
this.moveInputState = null
|
|
37
37
|
this.fromSquare = null
|
|
38
38
|
this.toSquare = null
|
|
39
|
-
|
|
40
|
-
const result = view.moveInputStartedCallback(square)
|
|
41
|
-
if (result) {
|
|
42
|
-
this.chessboard.state.moveInputProcess = Utils.createTask()
|
|
43
|
-
this.chessboard.state.moveInputProcess.then((result) => {
|
|
44
|
-
if (this.moveInputState === MOVE_INPUT_STATE.waitForInputStart ||
|
|
45
|
-
this.moveInputState === MOVE_INPUT_STATE.moveDone) {
|
|
46
|
-
view.moveInputFinishedCallback(this.fromSquare, this.toSquare, result)
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
return result
|
|
51
|
-
}
|
|
52
|
-
this.movingOverSquareCallback = (fromSquare, toSquare) => {
|
|
53
|
-
view.movingOverSquareCallback(fromSquare, toSquare)
|
|
54
|
-
}
|
|
55
|
-
this.validateMoveInputCallback = (fromSquare, toSquare) => {
|
|
56
|
-
const result = view.validateMoveInputCallback(fromSquare, toSquare)
|
|
57
|
-
this.chessboard.state.moveInputProcess.resolve(result)
|
|
58
|
-
return result
|
|
59
|
-
}
|
|
60
|
-
this.moveInputCanceledCallback = (fromSquare, toSquare, reason) => {
|
|
61
|
-
view.moveInputCanceledCallback(fromSquare, toSquare, reason)
|
|
62
|
-
this.chessboard.state.moveInputProcess.resolve()
|
|
63
|
-
}
|
|
39
|
+
|
|
64
40
|
this.setMoveInputState(MOVE_INPUT_STATE.waitForInputStart)
|
|
65
41
|
}
|
|
66
42
|
|
|
67
|
-
|
|
43
|
+
moveInputStartedCallback(square) {
|
|
44
|
+
const result = this.view.moveInputStartedCallback(square)
|
|
45
|
+
if (result) {
|
|
46
|
+
this.chessboard.state.moveInputProcess = Utils.createTask()
|
|
47
|
+
this.chessboard.state.moveInputProcess.then((result) => {
|
|
48
|
+
if (this.moveInputState === MOVE_INPUT_STATE.waitForInputStart ||
|
|
49
|
+
this.moveInputState === MOVE_INPUT_STATE.moveDone) {
|
|
50
|
+
this.view.moveInputFinishedCallback(this.fromSquare, this.toSquare, result)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
return result
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
movingOverSquareCallback(fromSquare, toSquare) {
|
|
58
|
+
this.view.movingOverSquareCallback(fromSquare, toSquare)
|
|
59
|
+
}
|
|
68
60
|
|
|
69
|
-
|
|
61
|
+
validateMoveInputCallback(fromSquare, toSquare) {
|
|
62
|
+
const result = this.view.validateMoveInputCallback(fromSquare, toSquare)
|
|
63
|
+
this.chessboard.state.moveInputProcess.resolve(result)
|
|
64
|
+
return result
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
moveInputCanceledCallback(fromSquare, toSquare, reason) {
|
|
68
|
+
this.view.moveInputCanceledCallback(fromSquare, toSquare, reason)
|
|
69
|
+
this.chessboard.state.moveInputProcess.resolve()
|
|
70
|
+
}
|
|
70
71
|
|
|
72
|
+
setMoveInputState(newState, params = undefined) {
|
|
71
73
|
const prevState = this.moveInputState
|
|
72
74
|
this.moveInputState = newState
|
|
73
75
|
|
|
@@ -162,16 +164,12 @@ export class VisualMoveInput {
|
|
|
162
164
|
}
|
|
163
165
|
this.toSquare = params.square
|
|
164
166
|
if (this.toSquare && this.validateMoveInputCallback(this.fromSquare, this.toSquare)) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
this.setMoveInputState(MOVE_INPUT_STATE.reset)
|
|
168
|
-
})
|
|
169
|
-
} else {
|
|
170
|
-
this.chessboard.movePiece(this.fromSquare, this.toSquare, false).then(() => {
|
|
167
|
+
this.chessboard.movePiece(this.fromSquare, this.toSquare, prevState === MOVE_INPUT_STATE.clickTo).then(() => {
|
|
168
|
+
if (prevState === MOVE_INPUT_STATE.clickTo) {
|
|
171
169
|
this.view.setPieceVisibility(this.toSquare, true)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
170
|
+
}
|
|
171
|
+
this.setMoveInputState(MOVE_INPUT_STATE.reset)
|
|
172
|
+
})
|
|
175
173
|
} else {
|
|
176
174
|
this.view.setPieceVisibility(this.fromSquare, true)
|
|
177
175
|
this.setMoveInputState(MOVE_INPUT_STATE.reset)
|
|
@@ -241,65 +239,68 @@ export class VisualMoveInput {
|
|
|
241
239
|
}
|
|
242
240
|
|
|
243
241
|
onPointerDown(e) {
|
|
244
|
-
if (e.type === "mousedown" && e.button === 0 || e.type === "touchstart") {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
242
|
+
if (!(e.type === "mousedown" && e.button === 0 || e.type === "touchstart")) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const square = e.target.getAttribute("data-square")
|
|
247
|
+
if (!square) { // pointer on square
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const pieceName = this.chessboard.getPiece(square)
|
|
252
|
+
let color
|
|
253
|
+
if (pieceName) {
|
|
254
|
+
color = pieceName ? pieceName.substring(0, 1) : null
|
|
255
|
+
// allow scrolling, if not pointed on draggable piece
|
|
256
|
+
if (color === "w" && this.chessboard.state.inputWhiteEnabled ||
|
|
257
|
+
color === "b" && this.chessboard.state.inputBlackEnabled) {
|
|
258
|
+
e.preventDefault()
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (this.moveInputState !== MOVE_INPUT_STATE.waitForInputStart ||
|
|
262
|
+
this.chessboard.state.inputWhiteEnabled && color === "w" ||
|
|
263
|
+
this.chessboard.state.inputBlackEnabled && color === "b") {
|
|
264
|
+
let point
|
|
265
|
+
if (e.type === "mousedown") {
|
|
266
|
+
point = {x: e.clientX, y: e.clientY}
|
|
267
|
+
} else if (e.type === "touchstart") {
|
|
268
|
+
point = {x: e.touches[0].clientX, y: e.touches[0].clientY}
|
|
269
|
+
}
|
|
270
|
+
if (this.moveInputState === MOVE_INPUT_STATE.waitForInputStart && pieceName && this.moveInputStartedCallback(square)) {
|
|
271
|
+
this.setMoveInputState(MOVE_INPUT_STATE.pieceClickedThreshold, {
|
|
272
|
+
square: square,
|
|
273
|
+
piece: pieceName,
|
|
274
|
+
point: point,
|
|
275
|
+
type: e.type
|
|
276
|
+
})
|
|
277
|
+
} else if (this.moveInputState === MOVE_INPUT_STATE.clickTo) {
|
|
278
|
+
if (square === this.fromSquare) {
|
|
279
|
+
this.setMoveInputState(MOVE_INPUT_STATE.secondClickThreshold, {
|
|
280
|
+
square: square,
|
|
281
|
+
piece: pieceName,
|
|
282
|
+
point: point,
|
|
283
|
+
type: e.type
|
|
284
|
+
})
|
|
285
|
+
} else {
|
|
286
|
+
const pieceName = this.chessboard.getPiece(square)
|
|
287
|
+
const pieceColor = pieceName ? pieceName.substring(0, 1) : null
|
|
288
|
+
const startPieceName = this.chessboard.getPiece(this.fromSquare)
|
|
289
|
+
const startPieceColor = startPieceName ? startPieceName.substring(0, 1) : null
|
|
290
|
+
if (color && startPieceColor === pieceColor) {
|
|
291
|
+
this.moveInputCanceledCallback(this.fromSquare, square, MOVE_CANCELED_REASON.clickedAnotherPiece)
|
|
292
|
+
if (this.moveInputStartedCallback(square)) {
|
|
293
|
+
this.setMoveInputState(MOVE_INPUT_STATE.pieceClickedThreshold, {
|
|
277
294
|
square: square,
|
|
278
295
|
piece: pieceName,
|
|
279
296
|
point: point,
|
|
280
297
|
type: e.type
|
|
281
298
|
})
|
|
282
299
|
} else {
|
|
283
|
-
|
|
284
|
-
const pieceColor = pieceName ? pieceName.substring(0, 1) : null
|
|
285
|
-
const startPieceName = this.chessboard.getPiece(this.fromSquare)
|
|
286
|
-
const startPieceColor = startPieceName ? startPieceName.substring(0, 1) : null
|
|
287
|
-
if (color && startPieceColor === pieceColor) {
|
|
288
|
-
this.moveInputCanceledCallback(this.fromSquare, square, MOVE_CANCELED_REASON.clickedAnotherPiece)
|
|
289
|
-
if (this.moveInputStartedCallback(square)) {
|
|
290
|
-
this.setMoveInputState(MOVE_INPUT_STATE.pieceClickedThreshold, {
|
|
291
|
-
square: square,
|
|
292
|
-
piece: pieceName,
|
|
293
|
-
point: point,
|
|
294
|
-
type: e.type
|
|
295
|
-
})
|
|
296
|
-
} else {
|
|
297
|
-
this.setMoveInputState(MOVE_INPUT_STATE.reset)
|
|
298
|
-
}
|
|
299
|
-
} else {
|
|
300
|
-
this.setMoveInputState(MOVE_INPUT_STATE.moveDone, {square: square})
|
|
301
|
-
}
|
|
300
|
+
this.setMoveInputState(MOVE_INPUT_STATE.reset)
|
|
302
301
|
}
|
|
302
|
+
} else {
|
|
303
|
+
this.setMoveInputState(MOVE_INPUT_STATE.moveDone, {square: square})
|
|
303
304
|
}
|
|
304
305
|
}
|
|
305
306
|
}
|
|
@@ -346,12 +347,11 @@ export class VisualMoveInput {
|
|
|
346
347
|
this.toSquare = null
|
|
347
348
|
this.movingOverSquareCallback(this.fromSquare, null)
|
|
348
349
|
}
|
|
349
|
-
} else {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
this.movingOverSquareCallback(this.fromSquare, null)
|
|
353
|
-
}
|
|
350
|
+
} else if (this.toSquare !== null) {
|
|
351
|
+
this.toSquare = null
|
|
352
|
+
this.movingOverSquareCallback(this.fromSquare, null)
|
|
354
353
|
}
|
|
354
|
+
|
|
355
355
|
if (this.view.chessboard.state.inputEnabled && (this.moveInputState === MOVE_INPUT_STATE.dragTo || this.moveInputState === MOVE_INPUT_STATE.clickDragTo)) {
|
|
356
356
|
this.moveDraggablePiece(pageX, pageY)
|
|
357
357
|
}
|