cm-chessboard 4.0.4 → 4.0.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/README.md +57 -33
- package/docs/PositionsAnimation.md +11 -0
- package/docs/PreMoves.md +1 -0
- package/examples/pieces-animation.html +25 -15
- package/examples/validate-moves.html +5 -7
- package/package.json +1 -1
- package/src/cm-chessboard/Chessboard.js +46 -86
- package/src/cm-chessboard/{ChessboardMoveInput.js → core/MoveInput.js} +14 -17
- package/src/cm-chessboard/{Position.js → core/Position.js} +26 -5
- package/src/cm-chessboard/core/PositionAnimationsQueue.js +274 -0
- package/src/cm-chessboard/{ChessboardState.js → core/State.js} +19 -12
- package/src/cm-chessboard/{ChessboardView.js → core/View.js} +16 -39
- package/src/cm-chessboard/{ChessboardViewAccessible.js → core/ViewAccessible.js} +6 -6
- package/test/TestPiecesAnimation.js +13 -16
- package/test/TestPosition.js +1 -1
- package/src/cm-chessboard/ChessboardPiecesAnimation.js +0 -142
- package/src/cm-chessboard/Observed.js +0 -40
package/README.md
CHANGED
|
@@ -36,13 +36,26 @@ aspects of chess games.
|
|
|
36
36
|
**Option 3:** Use it via CDN https://cdn.jsdelivr.net/npm/cm-chessboard@3.18.0/src/cm-chessboard/Chessboard.js
|
|
37
37
|
|
|
38
38
|
After installation, copy the sprite in `cm-chessboard/assets/images/` to your projects `assets/images/`
|
|
39
|
-
folder. If you put the sprite somewhere else you have to configure the location
|
|
39
|
+
folder. If you put the sprite somewhere else you have to configure the location
|
|
40
|
+
with `{sprite.url: "./url/of/chessboard-sprite.svg"}`
|
|
40
41
|
(see section 'Configuration' below).
|
|
41
42
|
|
|
42
43
|
To run the unit tests in `/test` you first have to `npm install` the dev dependencies. Without tests there are no
|
|
43
44
|
dependencies.
|
|
44
45
|
|
|
45
|
-
##
|
|
46
|
+
## Version 4.x has many changes
|
|
47
|
+
|
|
48
|
+
> With the new version 4 of cm-chessboard I completely redesigned the animation of positions with
|
|
49
|
+
> the use of promises.
|
|
50
|
+
|
|
51
|
+
The pieces animations are now smoother and less error-prone for race conditions.
|
|
52
|
+
|
|
53
|
+
As of version 4.x, the API functions `setPosition()`, `setPiece()` and `movePiece()` are **not animated** as default.
|
|
54
|
+
If you want some pieces animations you have to give the parameter `animated = true`.
|
|
55
|
+
|
|
56
|
+
Also in 4.x the chessboard will become more accessible for visually impaired people but this is in alpha stage for now.
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
46
59
|
|
|
47
60
|
Preconditions for using cm-chessboard in a web page:
|
|
48
61
|
|
|
@@ -69,23 +82,30 @@ examples.
|
|
|
69
82
|
Below is the default configuration
|
|
70
83
|
|
|
71
84
|
```javascript
|
|
72
|
-
|
|
85
|
+
let defaultProps = {
|
|
73
86
|
position: "empty", // set as fen, "start" or "empty"
|
|
74
87
|
orientation: COLOR.white, // white on bottom
|
|
88
|
+
responsive: true, // resizes the board based on element size
|
|
89
|
+
animationDuration: 300, // pieces animation duration in milliseconds. Disable all animation with `0`.
|
|
75
90
|
style: {
|
|
76
|
-
cssClass: "default",
|
|
91
|
+
cssClass: "default", // set the css theme of the board, try "green", "blue" or "chess-club"
|
|
77
92
|
showCoordinates: true, // show ranks and files
|
|
78
|
-
borderType: BORDER_TYPE.
|
|
79
|
-
aspectRatio: 1, // height/width
|
|
93
|
+
borderType: BORDER_TYPE.none, // "thin" thin border, "frame" wide border with coordinates in it, "none" no border
|
|
94
|
+
aspectRatio: 1, // height/width of the board
|
|
80
95
|
moveFromMarker: MARKER_TYPE.frame, // the marker used to mark the start square
|
|
81
|
-
moveToMarker: MARKER_TYPE.frame // the marker used to mark the square where the figure is moving to
|
|
96
|
+
moveToMarker: MARKER_TYPE.frame, // the marker used to mark the square where the figure is moving to
|
|
82
97
|
},
|
|
83
|
-
responsive: true, // resizes the board based on element size
|
|
84
|
-
animationDuration: 300, // pieces animation duration in milliseconds
|
|
85
98
|
sprite: {
|
|
86
|
-
url: "./assets/images/chessboard-sprite
|
|
87
|
-
size: 40, // the sprite size, defaults to 40x40px
|
|
88
|
-
cache: true // cache the sprite
|
|
99
|
+
url: "./assets/images/chessboard-sprite.svg", // pieces and markers are stored in a sprite file
|
|
100
|
+
size: 40, // the sprite tiles size, defaults to 40x40px
|
|
101
|
+
cache: true // cache the sprite
|
|
102
|
+
},
|
|
103
|
+
accessibility: { // accessibility functions are in "alpha" version for now, they might not work as expected
|
|
104
|
+
brailleNotationInAlt: true, // show the braille notation of the game in the alt attribute of the svg
|
|
105
|
+
movePieceForm: false, // display a form to move a piece (from, to, move)
|
|
106
|
+
boardAsTable: false, // display the board additionally as HTML table
|
|
107
|
+
piecesAsList: false, // display the pieces additionally as List
|
|
108
|
+
visuallyHidden: true // hide all those extra outputs visually but keep them accessible for screen readers and braille displays
|
|
89
109
|
}
|
|
90
110
|
}
|
|
91
111
|
```
|
|
@@ -94,32 +114,32 @@ props = {
|
|
|
94
114
|
|
|
95
115
|
### constructor
|
|
96
116
|
|
|
97
|
-
`new Chessboard(
|
|
117
|
+
`new Chessboard(context, props = {})`
|
|
98
118
|
|
|
99
|
-
- **`
|
|
119
|
+
- **`context`**: the HTML DOM element being the container of the widget
|
|
100
120
|
- **`props`**: The board configuration (properties)
|
|
101
121
|
|
|
102
|
-
### setPiece(square, piece)
|
|
122
|
+
### setPiece(square, piece, animated = false)
|
|
103
123
|
|
|
104
|
-
Sets a piece on a square. Example: `board.setPiece("e4", PIECE.blackKnight)` or
|
|
105
|
-
`board.setPiece("e4", "bn")`. Remove a Piece with `board.setPiece("e4", null)`.
|
|
124
|
+
Sets a piece on a square. Example: `board.setPiece("e4", PIECE.blackKnight, true)` or
|
|
125
|
+
`board.setPiece("e4", "bn")`. Remove a Piece with `board.setPiece("e4", null)`. Returns a **Promise**, which is
|
|
126
|
+
resolved,
|
|
127
|
+
after the animation finished.
|
|
106
128
|
|
|
107
129
|
### getPiece(square)
|
|
108
130
|
|
|
109
131
|
Returns the piece on a square or `undefined` if the square is empty.
|
|
110
132
|
|
|
111
|
-
### movePiece(squareFrom, squareTo, animated =
|
|
133
|
+
### movePiece(squareFrom, squareTo, animated = false)
|
|
112
134
|
|
|
113
|
-
Move a piece from `squareFrom` to `squareTo`. Returns a **Promise**, which is resolved,
|
|
135
|
+
Move a piece from `squareFrom` to `squareTo`. Returns a **Promise**, which is resolved, after the animation finished.
|
|
114
136
|
|
|
115
137
|
[Example for **movePiece**](https://shaack.com/projekte/cm-chessboard/examples/pieces-animation.html)
|
|
116
138
|
|
|
117
|
-
### setPosition(fen, animated =
|
|
118
|
-
|
|
119
|
-
Sets the position as `fen`. Special values are `"start"`, sets the chess start position and
|
|
120
|
-
`"empty"`, sets an empty board. When `animated` is set `false`, the new position will be shown instant.
|
|
139
|
+
### setPosition(fen, animated = false)
|
|
121
140
|
|
|
122
|
-
|
|
141
|
+
Sets the position as `fen`. Special values are "start", sets the chess start position and
|
|
142
|
+
"empty", sets an empty board. Returns a **Promise**, which is resolved, after the animation finished.
|
|
123
143
|
|
|
124
144
|
[Example for **setPosition**](https://shaack.com/projekte/cm-chessboard/examples/pieces-animation.html)
|
|
125
145
|
|
|
@@ -131,11 +151,13 @@ Returns the board position as `fen`.
|
|
|
131
151
|
|
|
132
152
|
Adds a marker on a square.
|
|
133
153
|
|
|
134
|
-
Default types are: `MARKER_TYPE.frame`, `MARKER_TYPE.square`, `MARKER_TYPE.dot`, `MARKER_TYPE.circle` exportet
|
|
154
|
+
Default types are: `MARKER_TYPE.frame`, `MARKER_TYPE.square`, `MARKER_TYPE.dot`, `MARKER_TYPE.circle` exportet
|
|
155
|
+
by `Chessboard.js`.
|
|
135
156
|
|
|
136
157
|
#### You can create your own marker types:
|
|
137
158
|
|
|
138
|
-
Just create an object like `const myMarker = {class: "markerCssClass", slice: "markerSliceId"}`, where `class` is the
|
|
159
|
+
Just create an object like `const myMarker = {class: "markerCssClass", slice: "markerSliceId"}`, where `class` is the
|
|
160
|
+
css class of the marker for styling
|
|
139
161
|
and `slice` is the `id` in `sprite.svg`. See also [Create your own custom markers](#create-your-own-custom-markers)
|
|
140
162
|
below.
|
|
141
163
|
|
|
@@ -271,7 +293,8 @@ It's a circle with the radius 18 and its center at 20/20.
|
|
|
271
293
|
|
|
272
294
|
Important is the id "markerCircle". You can set the marker
|
|
273
295
|
with `board.addMarker("e4", {class: "markerSquare", slice: "markerSquare"})`
|
|
274
|
-
"emphasize" is the css class, which defines the color and opacity of the marker. "slice" is the id of the marker in the
|
|
296
|
+
"emphasize" is the css class, which defines the color and opacity of the marker. "slice" is the id of the marker in the
|
|
297
|
+
SVG. This is
|
|
275
298
|
also demonstrated in the [mark squares example](https://shaack.com/projekte/cm-chessboard/examples/input-callbacks.html)
|
|
276
299
|
.
|
|
277
300
|
|
|
@@ -282,14 +305,15 @@ These are the css styles of the markers "markerSquare" and "markerCircleRed".
|
|
|
282
305
|
|
|
283
306
|
```css
|
|
284
307
|
marker.markerSquare {
|
|
285
|
-
|
|
286
|
-
|
|
308
|
+
fill: black;
|
|
309
|
+
opacity: 0.11;
|
|
287
310
|
}
|
|
311
|
+
|
|
288
312
|
marker.markerCircleRed {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
313
|
+
stroke: #aa0000;
|
|
314
|
+
stroke-width: 3px;
|
|
315
|
+
opacity: 0.4;
|
|
316
|
+
}
|
|
293
317
|
```
|
|
294
318
|
|
|
295
319
|
So you can simply add a marker with the id `myMarkerIdInSvg` to the SVG, and add the class `myMarkerCssClass` to the
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Positions Queue
|
|
2
|
+
|
|
3
|
+
- Extra Class
|
|
4
|
+
- Holds the Queue
|
|
5
|
+
- API
|
|
6
|
+
- `isRunning(): boolean`
|
|
7
|
+
- `pushPosition(position, animated)`
|
|
8
|
+
- `run(): Promise` // starts the animation, callback when finished, if running : Promis
|
|
9
|
+
- `skip(callback): Promise` // skips all running steps, displays the last position and returns to callback
|
|
10
|
+
- Positions are set immediately in the Model
|
|
11
|
+
- Then they are pushed into an Animations queue and run (if not running)
|
package/docs/PreMoves.md
CHANGED
|
@@ -13,16 +13,26 @@
|
|
|
13
13
|
<p>Animations are queued automatically.</p>
|
|
14
14
|
<div class="board" id="board"></div>
|
|
15
15
|
<br/>
|
|
16
|
-
<
|
|
16
|
+
<h3>Not animated</h3>
|
|
17
|
+
<button onclick="setPosition('empty').then(() => { console.log('empty finished')})">Empty Position</button>
|
|
17
18
|
<button onclick="setPosition('start')">Start Position</button>
|
|
18
19
|
<button onclick="setPosition('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR')">Position 1</button>
|
|
19
20
|
<button onclick="setPosition('rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R')">Position 2</button>
|
|
20
21
|
<button onclick="setPosition('rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR')">Position 3</button>
|
|
21
22
|
<button onclick="switchOrientation()">Switch Orientation</button>
|
|
23
|
+
<h3>Animated</h3>
|
|
24
|
+
<button onclick="setPosition('empty', true).then(() => { console.log('empty animated finished')})">Empty Position</button>
|
|
25
|
+
<button onclick="setPosition('start', true)">Start Position</button>
|
|
26
|
+
<button onclick="setPosition('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR', true)">Position 1</button>
|
|
27
|
+
<button onclick="setPosition('rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R', true)">Position 2</button>
|
|
28
|
+
<button onclick="setPosition('rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR', true)">Position 3</button>
|
|
29
|
+
<button onclick="switchOrientation(true)">Switch Orientation</button>
|
|
30
|
+
|
|
22
31
|
<pre><button onclick="window.board.setPosition('rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR')">Position 3</button></pre>
|
|
23
32
|
<br/>
|
|
24
|
-
Move piece from
|
|
25
|
-
|
|
33
|
+
Move piece <label for="moveFrom">from</label> <input id="moveFrom" type="text" size="2" value="e2"/> <label
|
|
34
|
+
for="moveTo">to</label> <input id="moveTo" type="text" size="2"
|
|
35
|
+
value="e4"/>
|
|
26
36
|
<button onclick="movePiece()">Do move</button>
|
|
27
37
|
<pre>board.movePiece(squareFrom, squareTo)</pre>
|
|
28
38
|
<br/>
|
|
@@ -43,27 +53,27 @@ await board.movePiece("d5", "f4")
|
|
|
43
53
|
animationDuration: 500
|
|
44
54
|
})
|
|
45
55
|
let i = 0
|
|
46
|
-
window.setPosition = (position) => {
|
|
56
|
+
window.setPosition = (position, animated) => {
|
|
47
57
|
i++
|
|
48
|
-
board.setPosition(position)
|
|
49
|
-
console.log("setPosition resolved", position, i)
|
|
50
|
-
})
|
|
58
|
+
return board.setPosition(position, animated)
|
|
51
59
|
}
|
|
52
|
-
window.switchOrientation = () => {
|
|
53
|
-
board.setOrientation(board.getOrientation() === 'w' ? 'b' : 'w')
|
|
60
|
+
window.switchOrientation = (animated) => {
|
|
61
|
+
board.setOrientation(board.getOrientation() === 'w' ? 'b' : 'w', animated)
|
|
54
62
|
}
|
|
55
63
|
window.movePiece = () => {
|
|
56
64
|
const squareFrom = document.getElementById("moveFrom").value
|
|
57
65
|
const squareTo = document.getElementById("moveTo").value
|
|
58
66
|
console.log("movePiece", squareFrom, squareTo)
|
|
59
|
-
board.movePiece(squareFrom, squareTo)
|
|
67
|
+
board.movePiece(squareFrom, squareTo, true)
|
|
60
68
|
}
|
|
61
69
|
window.knightMove = async () => {
|
|
62
|
-
|
|
63
|
-
board.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
board.setPiece("e5", PIECE.wn)
|
|
71
|
+
board.movePiece("e5", "c4", true)
|
|
72
|
+
board.movePiece("c4", "d6", true)
|
|
73
|
+
board.movePiece("d6", "f5", true)
|
|
74
|
+
board.movePiece("f5", "h4", true)
|
|
75
|
+
board.movePiece("h4", "g6", true)
|
|
76
|
+
board.movePiece("g6", "e5", true)
|
|
67
77
|
}
|
|
68
78
|
</script>
|
|
69
79
|
</body>
|
|
@@ -38,7 +38,7 @@ function inputHandler(event) {
|
|
|
38
38
|
if (event.type === INPUT_EVENT_TYPE.moveStart) {
|
|
39
39
|
const moves = chess.moves({square: event.square, verbose: true});
|
|
40
40
|
event.chessboard.addMarker(event.square, MARKER_TYPE.square)
|
|
41
|
-
for (const move of moves) {
|
|
41
|
+
for (const move of moves) { // draw dots on possible moves
|
|
42
42
|
event.chessboard.addMarker(move.to, MARKER_TYPE.dot)
|
|
43
43
|
}
|
|
44
44
|
return moves.length > 0
|
|
@@ -46,9 +46,7 @@ function inputHandler(event) {
|
|
|
46
46
|
const move = {from: event.squareFrom, to: event.squareTo}
|
|
47
47
|
const result = chess.move(move)
|
|
48
48
|
if (result) {
|
|
49
|
-
event.chessboard.removeMarkers(undefined, MARKER_TYPE.square)
|
|
50
49
|
event.chessboard.disableMoveInput()
|
|
51
|
-
event.chessboard.setPosition(chess.fen())
|
|
52
50
|
const possibleMoves = chess.moves({verbose: true})
|
|
53
51
|
if (possibleMoves.length > 0) {
|
|
54
52
|
const randomIndex = Math.floor(Math.random() * possibleMoves.length)
|
|
@@ -56,7 +54,7 @@ function inputHandler(event) {
|
|
|
56
54
|
setTimeout(() => { // smoother with 500ms delay
|
|
57
55
|
chess.move({from: randomMove.from, to: randomMove.to})
|
|
58
56
|
event.chessboard.enableMoveInput(inputHandler, COLOR.white)
|
|
59
|
-
event.chessboard.setPosition(chess.fen())
|
|
57
|
+
event.chessboard.setPosition(chess.fen(), true)
|
|
60
58
|
}, 500)
|
|
61
59
|
}
|
|
62
60
|
} else {
|
|
@@ -97,7 +95,6 @@ board.enableMoveInput(inputHandler, COLOR.white)
|
|
|
97
95
|
const result = chess.move(move)
|
|
98
96
|
if (result) {
|
|
99
97
|
event.chessboard.disableMoveInput()
|
|
100
|
-
event.chessboard.setPosition(chess.fen())
|
|
101
98
|
const possibleMoves = chess.moves({verbose: true})
|
|
102
99
|
if (possibleMoves.length > 0) {
|
|
103
100
|
const randomIndex = Math.floor(Math.random() * possibleMoves.length)
|
|
@@ -105,7 +102,7 @@ board.enableMoveInput(inputHandler, COLOR.white)
|
|
|
105
102
|
setTimeout(() => { // smoother with 500ms delay
|
|
106
103
|
chess.move({from: randomMove.from, to: randomMove.to})
|
|
107
104
|
event.chessboard.enableMoveInput(inputHandler, COLOR.white)
|
|
108
|
-
event.chessboard.setPosition(chess.fen())
|
|
105
|
+
event.chessboard.setPosition(chess.fen(), true)
|
|
109
106
|
}, 500)
|
|
110
107
|
}
|
|
111
108
|
} else {
|
|
@@ -119,7 +116,8 @@ board.enableMoveInput(inputHandler, COLOR.white)
|
|
|
119
116
|
position: chess.fen(),
|
|
120
117
|
sprite: {url: "../assets/images/chessboard-sprite-staunty.svg"},
|
|
121
118
|
style: {moveFromMarker: undefined, moveToMarker: undefined}, // disable standard markers
|
|
122
|
-
orientation: COLOR.white
|
|
119
|
+
orientation: COLOR.white,
|
|
120
|
+
animationDuration: 500
|
|
123
121
|
})
|
|
124
122
|
board.enableMoveInput(inputHandler, COLOR.white)
|
|
125
123
|
</script>
|
package/package.json
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* License: MIT, see file 'LICENSE'
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import {State} from "./core/State.js"
|
|
8
|
+
import {ViewAccessible} from "./core/ViewAccessible.js"
|
|
9
|
+
import {PositionAnimationsQueue} from "./core/PositionAnimationsQueue.js"
|
|
9
10
|
|
|
10
11
|
export const COLOR = {
|
|
11
12
|
white: "w",
|
|
@@ -35,8 +36,6 @@ export const PIECE = {
|
|
|
35
36
|
wp: "wp", wb: "wb", wn: "wn", wr: "wr", wq: "wq", wk: "wk",
|
|
36
37
|
bp: "bp", bb: "bb", bn: "bn", br: "br", bq: "bq", bk: "bk",
|
|
37
38
|
}
|
|
38
|
-
export const FEN_START_POSITION = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
|
39
|
-
export const FEN_EMPTY_POSITION = "8/8/8/8/8/8/8/8"
|
|
40
39
|
|
|
41
40
|
export class Chessboard {
|
|
42
41
|
|
|
@@ -45,29 +44,29 @@ export class Chessboard {
|
|
|
45
44
|
throw new Error("container element is " + context)
|
|
46
45
|
}
|
|
47
46
|
this.context = context
|
|
48
|
-
this.id = (Math.random() + 1).toString(36).
|
|
47
|
+
this.id = (Math.random() + 1).toString(36).substring(2, 8)
|
|
49
48
|
let defaultProps = {
|
|
50
49
|
position: "empty", // set as fen, "start" or "empty"
|
|
51
50
|
orientation: COLOR.white, // white on bottom
|
|
52
|
-
animationDuration: 300, // pieces animation duration in milliseconds
|
|
53
51
|
responsive: true, // resizes the board based on element size
|
|
52
|
+
animationDuration: 300, // pieces animation duration in milliseconds. Disable all animation with `0`.
|
|
54
53
|
style: {
|
|
55
|
-
cssClass: "default",
|
|
54
|
+
cssClass: "default", // set the css theme of the board, try "green", "blue" or "chess-club"
|
|
56
55
|
showCoordinates: true, // show ranks and files
|
|
57
|
-
borderType: BORDER_TYPE.none, // thin
|
|
56
|
+
borderType: BORDER_TYPE.none, // "thin" thin border, "frame" wide border with coordinates in it, "none" no border
|
|
58
57
|
aspectRatio: 1, // height/width of the board
|
|
59
58
|
moveFromMarker: MARKER_TYPE.frame, // the marker used to mark the start square
|
|
60
59
|
moveToMarker: MARKER_TYPE.frame, // the marker used to mark the square where the figure is moving to
|
|
61
60
|
},
|
|
62
61
|
sprite: {
|
|
63
|
-
url: "./assets/images/chessboard-sprite.svg", // pieces and markers are stored
|
|
64
|
-
size: 40, // the sprite size, defaults to 40x40px
|
|
62
|
+
url: "./assets/images/chessboard-sprite.svg", // pieces and markers are stored in a sprite file
|
|
63
|
+
size: 40, // the sprite tiles size, defaults to 40x40px
|
|
65
64
|
cache: true // cache the sprite
|
|
66
65
|
},
|
|
67
|
-
accessibility: {
|
|
66
|
+
accessibility: { // accessibility functions are in "alpha" version for now, they might not work as expected
|
|
68
67
|
brailleNotationInAlt: true, // show the braille notation of the game in the alt attribute of the svg
|
|
69
|
-
boardAsTable: false, // display the board additionally as HTML table
|
|
70
68
|
movePieceForm: false, // display a form to move a piece (from, to, move)
|
|
69
|
+
boardAsTable: false, // display the board additionally as HTML table
|
|
71
70
|
piecesAsList: false, // display the pieces additionally as List
|
|
72
71
|
visuallyHidden: true // hide all those extra outputs visually but keep them accessible for screen readers and braille displays
|
|
73
72
|
}
|
|
@@ -88,88 +87,57 @@ export class Chessboard {
|
|
|
88
87
|
Object.assign(this.props.accessibility, props.accessibility)
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
this.state = new
|
|
92
|
-
this.view = new
|
|
93
|
-
|
|
94
|
-
this.state.addObserver(() => {
|
|
95
|
-
if(this.view) {
|
|
96
|
-
this.view.drawPieces()
|
|
97
|
-
}
|
|
98
|
-
})
|
|
99
|
-
*/
|
|
100
|
-
if (this.props.position === "start") {
|
|
101
|
-
this.state.setPosition(FEN_START_POSITION)
|
|
102
|
-
} else if (this.props.position === "empty" || this.props.position === undefined) {
|
|
103
|
-
this.state.setPosition(FEN_EMPTY_POSITION)
|
|
104
|
-
} else {
|
|
105
|
-
this.state.setPosition(this.props.position)
|
|
106
|
-
}
|
|
90
|
+
this.state = new State()
|
|
91
|
+
this.view = new ViewAccessible(this)
|
|
92
|
+
this.positionAnimationsQueue = new PositionAnimationsQueue(this)
|
|
107
93
|
this.state.orientation = this.props.orientation
|
|
108
94
|
this.view.redraw()
|
|
95
|
+
// noinspection JSUnusedGlobalSymbols
|
|
96
|
+
this.initialized = this.setPosition(this.props.position)
|
|
109
97
|
}
|
|
110
98
|
|
|
111
99
|
// API //
|
|
112
100
|
|
|
113
|
-
setPiece(square, piece) {
|
|
101
|
+
async setPiece(square, piece, animated = false) {
|
|
102
|
+
const positionFrom = this.state.position.clone()
|
|
114
103
|
this.state.position.setPiece(square, piece)
|
|
115
|
-
this.
|
|
104
|
+
return this.positionAnimationsQueue.enqueuePositionChange(positionFrom, this.state.position.clone(), animated)
|
|
116
105
|
}
|
|
117
106
|
|
|
118
|
-
|
|
119
|
-
|
|
107
|
+
async movePiece(squareFrom, squareTo, animated = false) {
|
|
108
|
+
const positionFrom = this.state.position.clone()
|
|
109
|
+
this.state.position.movePiece(squareFrom, squareTo)
|
|
110
|
+
return this.positionAnimationsQueue.enqueuePositionChange(positionFrom, this.state.position.clone(), animated)
|
|
120
111
|
}
|
|
121
112
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if(!pieceFrom) {
|
|
127
|
-
reject("no piece on square " + squareFrom)
|
|
128
|
-
} else {
|
|
129
|
-
this.state.position.setPiece(squareFrom, null)
|
|
130
|
-
this.state.position.setPiece(squareTo, pieceFrom)
|
|
131
|
-
if (animated) {
|
|
132
|
-
this.view.animatePieces(prevSquares, this.state.position.squares, () => {
|
|
133
|
-
resolve()
|
|
134
|
-
})
|
|
135
|
-
} else {
|
|
136
|
-
this.view.drawPieces(this.state.position.squares)
|
|
137
|
-
resolve()
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
})
|
|
113
|
+
async setPosition(fen, animated = false) {
|
|
114
|
+
const positionFrom = this.state.position.clone()
|
|
115
|
+
this.state.position.setFen(fen)
|
|
116
|
+
return this.positionAnimationsQueue.enqueuePositionChange(positionFrom, this.state.position.clone(), animated)
|
|
141
117
|
}
|
|
142
118
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const fenNormalized = fenParts[0]
|
|
153
|
-
|
|
154
|
-
if (fenNormalized !== currentFen) {
|
|
155
|
-
const prevSquares = this.state.position.squares.slice(0) // clone
|
|
156
|
-
this.state.setPosition(fen)
|
|
157
|
-
if (animated) {
|
|
158
|
-
this.view.animatePieces(prevSquares, this.state.position.squares.slice(0), () => {
|
|
159
|
-
resolve()
|
|
160
|
-
})
|
|
161
|
-
} else {
|
|
162
|
-
this.view.drawPieces(this.state.position.squares)
|
|
163
|
-
resolve()
|
|
164
|
-
}
|
|
165
|
-
} else {
|
|
166
|
-
resolve()
|
|
167
|
-
}
|
|
119
|
+
async setOrientation(color, animated = false) {
|
|
120
|
+
const position = this.state.position.clone()
|
|
121
|
+
if(this.boardTurning) {
|
|
122
|
+
console.log("setOrientation is only once in queue allowed")
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
this.boardTurning = true
|
|
126
|
+
return this.positionAnimationsQueue.enqueueTurnBoard(position, color, animated).then(() => {
|
|
127
|
+
this.boardTurning = false
|
|
168
128
|
})
|
|
169
129
|
}
|
|
170
130
|
|
|
131
|
+
getPiece(square) {
|
|
132
|
+
return this.state.position.getPiece(square)
|
|
133
|
+
}
|
|
134
|
+
|
|
171
135
|
getPosition() {
|
|
172
|
-
return this.state.
|
|
136
|
+
return this.state.position.getFen()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
getOrientation() {
|
|
140
|
+
return this.state.orientation
|
|
173
141
|
}
|
|
174
142
|
|
|
175
143
|
addMarker(square, type) {
|
|
@@ -199,16 +167,8 @@ export class Chessboard {
|
|
|
199
167
|
this.view.drawMarkers()
|
|
200
168
|
}
|
|
201
169
|
|
|
202
|
-
setOrientation(color) {
|
|
203
|
-
this.state.orientation = color
|
|
204
|
-
return this.view.redraw()
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
getOrientation() {
|
|
208
|
-
return this.state.orientation
|
|
209
|
-
}
|
|
210
|
-
|
|
211
170
|
destroy() {
|
|
171
|
+
this.positionAnimationsQueue.destroy()
|
|
212
172
|
this.view.destroy()
|
|
213
173
|
this.view = undefined
|
|
214
174
|
this.state = undefined
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* License: MIT, see file 'LICENSE'
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {Svg} from "./
|
|
8
|
-
// import {Position} from "./Position.js"
|
|
7
|
+
import {Svg} from "./View.js"
|
|
9
8
|
|
|
10
9
|
const STATE = {
|
|
11
10
|
waitForInputStart: 0,
|
|
@@ -27,7 +26,7 @@ export const MOVE_CANCELED_REASON = {
|
|
|
27
26
|
|
|
28
27
|
const DRAG_THRESHOLD = 4
|
|
29
28
|
|
|
30
|
-
export class
|
|
29
|
+
export class MoveInput {
|
|
31
30
|
|
|
32
31
|
constructor(view, moveStartCallback, moveDoneCallback, moveCanceledCallback) {
|
|
33
32
|
this.view = view
|
|
@@ -102,7 +101,7 @@ export class ChessboardMoveInput {
|
|
|
102
101
|
this.draggablePiece = undefined
|
|
103
102
|
}
|
|
104
103
|
if (prevState === STATE.dragTo) {
|
|
105
|
-
this.view.setPieceVisibility(params.square)
|
|
104
|
+
this.view.setPieceVisibility(params.square, true)
|
|
106
105
|
}
|
|
107
106
|
break
|
|
108
107
|
|
|
@@ -139,21 +138,18 @@ export class ChessboardMoveInput {
|
|
|
139
138
|
}
|
|
140
139
|
this.toSquare = params.square
|
|
141
140
|
if (this.toSquare && this.moveDoneCallback(this.fromSquare, this.toSquare)) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
this.chessboard.state.position.setPiece(this.toSquare, this.movedPiece)
|
|
145
|
-
if (prevState === STATE.clickTo) {
|
|
146
|
-
this.updateStartEndMarkers()
|
|
147
|
-
this.view.animatePieces(prevSquares, this.chessboard.state.position.clone().squares, () => {
|
|
141
|
+
if(prevState === STATE.clickTo) {
|
|
142
|
+
this.chessboard.movePiece(this.fromSquare, this.toSquare, true).then(() => {
|
|
148
143
|
this.setMoveInputState(STATE.reset)
|
|
149
144
|
})
|
|
150
145
|
} else {
|
|
151
|
-
this.
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
this.chessboard.movePiece(this.fromSquare, this.toSquare, false).then(() => {
|
|
147
|
+
this.view.setPieceVisibility(this.toSquare, true)
|
|
148
|
+
this.setMoveInputState(STATE.reset)
|
|
149
|
+
})
|
|
154
150
|
}
|
|
155
151
|
} else {
|
|
156
|
-
this.view.
|
|
152
|
+
this.view.setPieceVisibility(this.fromSquare, true)
|
|
157
153
|
this.setMoveInputState(STATE.reset)
|
|
158
154
|
}
|
|
159
155
|
break
|
|
@@ -187,6 +183,7 @@ export class ChessboardMoveInput {
|
|
|
187
183
|
}
|
|
188
184
|
|
|
189
185
|
createDraggablePiece(pieceName) {
|
|
186
|
+
// TODO use the existing piece from the board and don't create an new one
|
|
190
187
|
if (this.draggablePiece) {
|
|
191
188
|
throw Error("draggablePiece exists")
|
|
192
189
|
}
|
|
@@ -255,7 +252,7 @@ export class ChessboardMoveInput {
|
|
|
255
252
|
const pieceColor = pieceName ? pieceName.substring(0, 1) : undefined
|
|
256
253
|
const startPieceName = this.chessboard.getPiece(this.fromSquare)
|
|
257
254
|
const startPieceColor = startPieceName ? startPieceName.substring(0, 1) : undefined
|
|
258
|
-
if (color && startPieceColor === pieceColor) {
|
|
255
|
+
if (color && startPieceColor === pieceColor) {
|
|
259
256
|
this.moveCanceledCallback(MOVE_CANCELED_REASON.clickedAnotherPiece, this.fromSquare, square)
|
|
260
257
|
if (this.moveStartCallback(square)) {
|
|
261
258
|
this.setMoveInputState(STATE.pieceClickedThreshold, {
|
|
@@ -356,13 +353,13 @@ export class ChessboardMoveInput {
|
|
|
356
353
|
this.moveCanceledCallback(MOVE_CANCELED_REASON.secondClick, square, square)
|
|
357
354
|
}
|
|
358
355
|
} else {
|
|
359
|
-
this.view.
|
|
356
|
+
this.view.redrawPieces()
|
|
360
357
|
const moveStartSquare = this.fromSquare
|
|
361
358
|
this.setMoveInputState(STATE.reset)
|
|
362
359
|
this.moveCanceledCallback(MOVE_CANCELED_REASON.movedOutOfBoard, moveStartSquare, undefined)
|
|
363
360
|
}
|
|
364
361
|
} else {
|
|
365
|
-
this.view.
|
|
362
|
+
this.view.redrawPieces()
|
|
366
363
|
this.setMoveInputState(STATE.reset)
|
|
367
364
|
}
|
|
368
365
|
}
|