cm-chessboard 4.0.4 → 4.0.8

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.
@@ -4,8 +4,7 @@
4
4
  * License: MIT, see file 'LICENSE'
5
5
  */
6
6
 
7
- import {Svg} from "./ChessboardView.js"
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 ChessboardMoveInput {
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
- const prevSquares = this.chessboard.state.position.clone().squares
143
- this.chessboard.state.position.setPiece(this.fromSquare, undefined)
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.view.drawPieces(this.chessboard.state.position.squares)
152
- // this.view.animationQueue = [] // todo remove all animations (See PR #59)
153
- this.setMoveInputState(STATE.reset)
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.drawPieces()
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) { // https://github.com/shaack/cm-chessboard/issues/40
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.drawPieces()
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.drawPieces()
362
+ this.view.redrawPieces()
366
363
  this.setMoveInputState(STATE.reset)
367
364
  }
368
365
  }
@@ -12,8 +12,17 @@ export class Position {
12
12
  this.squares = new Array(64).fill(null)
13
13
  this.setFen(fen)
14
14
  }
15
- setFen(fen = FEN_START_POSITION) {
16
- const parts = fen.replace(/^\s*/, "").replace(/\s*$/, "").split(/\/|\s/)
15
+
16
+ setFen(fen = FEN_EMPTY_POSITION) {
17
+ let fenNormalized
18
+ if (fen === "start") {
19
+ fenNormalized = FEN_START_POSITION
20
+ } else if (fen === "empty" || fen === undefined) {
21
+ fenNormalized = FEN_EMPTY_POSITION
22
+ } else {
23
+ fenNormalized = fen
24
+ }
25
+ const parts = fenNormalized.replace(/^\s*/, "").replace(/\s*$/, "").split(/\/|\s/)
17
26
  for (let part = 0; part < 8; part++) {
18
27
  const row = parts[7 - part].replace(/\d/g, (str) => {
19
28
  const numSpaces = parseInt(str)
@@ -37,6 +46,7 @@ export class Position {
37
46
  }
38
47
  }
39
48
  }
49
+
40
50
  getFen() {
41
51
  let parts = new Array(8).fill("")
42
52
  for (let part = 0; part < 8; part++) {
@@ -66,9 +76,9 @@ export class Position {
66
76
  }
67
77
  return parts.join("/")
68
78
  }
69
- getPieces() {
79
+
80
+ getPieces(sortBy = ['k', 'q', 'r', 'b', 'n', 'p']) {
70
81
  const pieces = []
71
- const sortBy = ['k', 'q', 'r', 'b', 'n', 'p']
72
82
  const sort = (a, b) => {
73
83
  return sortBy.indexOf(a.name) - sortBy.indexOf(b.name)
74
84
  }
@@ -82,10 +92,21 @@ export class Position {
82
92
  })
83
93
  }
84
94
  }
85
- pieces.sort(sort)
95
+ if(sortBy) {
96
+ pieces.sort(sort)
97
+ }
86
98
  return pieces
87
99
  }
88
100
 
101
+ movePiece(squareFrom, squareTo) {
102
+ if(!this.squares[Position.squareToIndex(squareFrom)]) {
103
+ console.error("movePiece, no piece on square", squareFrom)
104
+ return
105
+ }
106
+ this.squares[Position.squareToIndex(squareTo)] = this.squares[Position.squareToIndex(squareFrom)]
107
+ this.squares[Position.squareToIndex(squareFrom)] = undefined
108
+ }
109
+
89
110
  setPiece(square, piece) {
90
111
  this.squares[Position.squareToIndex(square)] = piece
91
112
  }
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Author and copyright: Stefan Haack (https://shaack.com)
3
+ * Repository: https://github.com/shaack/cm-chessboard
4
+ * License: MIT, see file 'LICENSE'
5
+ */
6
+ import {FEN_EMPTY_POSITION, Position} from "./Position.js"
7
+ import {Svg} from "./View.js"
8
+
9
+ /*
10
+ * Thanks to markosyan for the idea to the PromiseQueue
11
+ * https://medium.com/@karenmarkosyan/how-to-manage-promises-into-dynamic-queue-with-vanilla-javascript-9d0d1f8d4df5
12
+ */
13
+
14
+ export class PromiseQueue {
15
+
16
+ constructor() {
17
+ this.queue = []
18
+ this.workingOnPromise = false
19
+ this.stop = false
20
+ }
21
+
22
+ async enqueue(promise) {
23
+ return new Promise((resolve, reject) => {
24
+ this.queue.push({
25
+ promise, resolve, reject,
26
+ })
27
+ this.dequeue()
28
+ })
29
+ }
30
+
31
+ dequeue() {
32
+ if (this.workingOnPromise) {
33
+ return
34
+ }
35
+ if (this.stop) {
36
+ this.queue = []
37
+ this.stop = false
38
+ return
39
+ }
40
+ const entry = this.queue.shift()
41
+ if (!entry) {
42
+ return
43
+ }
44
+ try {
45
+ this.workingOnPromise = true
46
+ entry.promise().then((value) => {
47
+ this.workingOnPromise = false
48
+ entry.resolve(value)
49
+ this.dequeue()
50
+ }).catch(err => {
51
+ this.workingOnPromise = false
52
+ entry.reject(err)
53
+ this.dequeue()
54
+ })
55
+ } catch (err) {
56
+ this.workingOnPromise = false
57
+ entry.reject(err)
58
+ this.dequeue()
59
+ }
60
+ return true
61
+ }
62
+
63
+ destroy() {
64
+ console.log("PAQ destroy")
65
+ this.stop = true
66
+ }
67
+
68
+
69
+ }
70
+
71
+
72
+ const CHANGE_TYPE = {
73
+ move: 0,
74
+ appear: 1,
75
+ disappear: 2
76
+ }
77
+
78
+ export class PositionsAnimation {
79
+
80
+ constructor(view, fromPosition, toPosition, duration, callback) {
81
+ this.view = view
82
+ if (fromPosition && toPosition) {
83
+ this.animatedElements = this.createAnimation(fromPosition.squares, toPosition.squares)
84
+ this.duration = duration
85
+ this.callback = callback
86
+ this.frameHandle = requestAnimationFrame(this.animationStep.bind(this))
87
+ } else {
88
+ console.error("fromPosition", fromPosition, "toPosition", toPosition)
89
+ }
90
+ }
91
+
92
+ static seekChanges(fromSquares, toSquares) {
93
+ const appearedList = [], disappearedList = [], changes = []
94
+ for (let i = 0; i < 64; i++) {
95
+ const previousSquare = fromSquares[i]
96
+ const newSquare = toSquares[i]
97
+ if (newSquare !== previousSquare) {
98
+ if (newSquare) {
99
+ appearedList.push({piece: newSquare, index: i})
100
+ }
101
+ if (previousSquare) {
102
+ disappearedList.push({piece: previousSquare, index: i})
103
+ }
104
+ }
105
+ }
106
+ appearedList.forEach((appeared) => {
107
+ let shortestDistance = 8
108
+ let foundMoved = undefined
109
+ disappearedList.forEach((disappeared) => {
110
+ if (appeared.piece === disappeared.piece) {
111
+ const moveDistance = PositionsAnimation.squareDistance(appeared.index, disappeared.index)
112
+ if (moveDistance < shortestDistance) {
113
+ foundMoved = disappeared
114
+ shortestDistance = moveDistance
115
+ }
116
+ }
117
+ })
118
+ if (foundMoved) {
119
+ disappearedList.splice(disappearedList.indexOf(foundMoved), 1) // remove from disappearedList, because it is moved now
120
+ changes.push({
121
+ type: CHANGE_TYPE.move,
122
+ piece: appeared.piece,
123
+ atIndex: foundMoved.index,
124
+ toIndex: appeared.index
125
+ })
126
+ } else {
127
+ changes.push({type: CHANGE_TYPE.appear, piece: appeared.piece, atIndex: appeared.index})
128
+ }
129
+ })
130
+ disappearedList.forEach((disappeared) => {
131
+ changes.push({type: CHANGE_TYPE.disappear, piece: disappeared.piece, atIndex: disappeared.index})
132
+ })
133
+ return changes
134
+ }
135
+
136
+ createAnimation(fromSquares, toSquares) {
137
+ const changes = PositionsAnimation.seekChanges(fromSquares, toSquares)
138
+ // console.log("changes", changes)
139
+ const animatedElements = []
140
+ changes.forEach((change) => {
141
+ const animatedItem = {
142
+ type: change.type
143
+ }
144
+ switch (change.type) {
145
+ case CHANGE_TYPE.move:
146
+ animatedItem.element = this.view.getPieceElement(Position.indexToSquare(change.atIndex))
147
+ animatedItem.element.parentNode.appendChild(animatedItem.element) // move element to top layer
148
+ animatedItem.atPoint = this.view.indexToPoint(change.atIndex)
149
+ animatedItem.toPoint = this.view.indexToPoint(change.toIndex)
150
+ break
151
+ case CHANGE_TYPE.appear:
152
+ animatedItem.element = this.view.drawPiece(Position.indexToSquare(change.atIndex), change.piece)
153
+ animatedItem.element.style.opacity = 0
154
+ break
155
+ case CHANGE_TYPE.disappear:
156
+ animatedItem.element = this.view.getPieceElement(Position.indexToSquare(change.atIndex))
157
+ break
158
+ }
159
+ animatedElements.push(animatedItem)
160
+ })
161
+ return animatedElements
162
+ }
163
+
164
+ animationStep(time) {
165
+ // console.log("animationStep", time)
166
+ if (!this.startTime) {
167
+ this.startTime = time
168
+ }
169
+ const timeDiff = time - this.startTime
170
+ if (timeDiff <= this.duration) {
171
+ this.frameHandle = requestAnimationFrame(this.animationStep.bind(this))
172
+ } else {
173
+ cancelAnimationFrame(this.frameHandle)
174
+ // console.log("ANIMATION FINISHED")
175
+ this.animatedElements.forEach((animatedItem) => {
176
+ if (animatedItem.type === CHANGE_TYPE.disappear) {
177
+ Svg.removeElement(animatedItem.element)
178
+ }
179
+ })
180
+ this.callback()
181
+ return
182
+ }
183
+ const t = Math.min(1, timeDiff / this.duration)
184
+ let progress = t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t // easeInOut
185
+ if (isNaN(progress)) {
186
+ progress = 1
187
+ }
188
+ this.animatedElements.forEach((animatedItem) => {
189
+ // console.log("animatedItem", animatedItem)
190
+ if (animatedItem.element) {
191
+ switch (animatedItem.type) {
192
+ case CHANGE_TYPE.move:
193
+ animatedItem.element.transform.baseVal.removeItem(0)
194
+ const transform = (this.view.svg.createSVGTransform())
195
+ transform.setTranslate(
196
+ animatedItem.atPoint.x + (animatedItem.toPoint.x - animatedItem.atPoint.x) * progress,
197
+ animatedItem.atPoint.y + (animatedItem.toPoint.y - animatedItem.atPoint.y) * progress)
198
+ animatedItem.element.transform.baseVal.appendItem(transform)
199
+ break
200
+ case CHANGE_TYPE.appear:
201
+ animatedItem.element.style.opacity = Math.round(progress * 100) / 100
202
+ break
203
+ case CHANGE_TYPE.disappear:
204
+ animatedItem.element.style.opacity = Math.round((1 - progress) * 100) / 100
205
+ break
206
+ }
207
+ } else {
208
+ console.warn("animatedItem has no element", animatedItem)
209
+ }
210
+ })
211
+ }
212
+
213
+ static squareDistance(index1, index2) {
214
+ const file1 = index1 % 8
215
+ const rank1 = Math.floor(index1 / 8)
216
+ const file2 = index2 % 8
217
+ const rank2 = Math.floor(index2 / 8)
218
+ return Math.max(Math.abs(rank2 - rank1), Math.abs(file2 - file1))
219
+ }
220
+
221
+ }
222
+
223
+ export class PositionAnimationsQueue extends PromiseQueue {
224
+
225
+ constructor(chessboard) {
226
+ super()
227
+ this.chessboard = chessboard
228
+ }
229
+
230
+ async enqueuePositionChange(positionFrom, positionTo, animated) {
231
+ return super.enqueue(() => new Promise((resolve) => {
232
+ let duration = animated ? this.chessboard.props.animationDuration : 0
233
+ if(this.queue.length > 0) {
234
+ duration = duration / (1 + Math.pow(this.queue.length / 5, 2))
235
+ }
236
+ // console.log("duration", duration, animated, "this.chessboard.props.animationDuration", this.chessboard.props.animationDuration)
237
+ new PositionsAnimation(this.chessboard.view,
238
+ positionFrom, positionTo, animated ? duration : 0,
239
+ () => {
240
+ if(this.chessboard.view) { // if destroyed, no view anymore
241
+ this.chessboard.view.redrawPieces(positionTo.squares)
242
+ }
243
+ resolve()
244
+ }
245
+ )
246
+ }))
247
+ }
248
+
249
+ async enqueueTurnBoard(position, color, animated) {
250
+ return super.enqueue(() => new Promise((resolve) => {
251
+ const emptyPosition = new Position(FEN_EMPTY_POSITION)
252
+ let duration = animated ? this.chessboard.props.animationDuration : 0
253
+ if(this.queue.length > 0) {
254
+ duration = duration / (1 + Math.pow(this.queue.length / 5, 2))
255
+ }
256
+ new PositionsAnimation(this.chessboard.view,
257
+ position, emptyPosition, animated ? duration : 0,
258
+ () => {
259
+ this.chessboard.state.orientation = color
260
+ this.chessboard.view.redraw()
261
+ this.chessboard.view.redrawPieces(emptyPosition.squares)
262
+ new PositionsAnimation(this.chessboard.view,
263
+ emptyPosition, position, animated ? duration : 0,
264
+ () => {
265
+ this.chessboard.view.redrawPieces(position.squares)
266
+ resolve()
267
+ }
268
+ )
269
+ }
270
+ )
271
+ }))
272
+ }
273
+
274
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import {Position} from "./Position.js"
7
7
 
8
- export class ChessboardState {
8
+ export class State {
9
9
 
10
10
  constructor() {
11
11
  this.position = new Position()
@@ -16,21 +16,28 @@ export class ChessboardState {
16
16
  this.inputEnabled = false
17
17
  this.squareSelectEnabled = false
18
18
  }
19
- /*
20
- getPieces() {
21
- return this.position.getPieces()
22
- }
23
19
 
24
- setPiece(square, piece) {
25
- this.position.setPiece(square, piece)
20
+ setPosition(fen, animated = false) {
21
+ this.position = new Position(fen, animated)
26
22
  }
27
- */
28
- setPosition(fen) {
29
- this.position.setFen(fen)
23
+
24
+ movePiece(fromSquare, toSquare, animated = false) {
25
+ const position = this._position.clone()
26
+ position.animated = animated
27
+ const piece = position.getPiece(fromSquare)
28
+ if(!piece) {
29
+ console.error("no piece on", fromSquare)
30
+ }
31
+ position.setPiece(fromSquare, undefined)
32
+ position.setPiece(toSquare, piece)
33
+ this._position = position
30
34
  }
31
35
 
32
- getPosition() {
33
- return this.position.getFen()
36
+ setPiece(square, piece, animated = false) {
37
+ const position = this._position.clone()
38
+ position.animated = animated
39
+ position.setPiece(square, piece)
40
+ this._position = position
34
41
  }
35
42
 
36
43
  addMarker(square, type) {
@@ -4,9 +4,8 @@
4
4
  * License: MIT, see file 'LICENSE'
5
5
  */
6
6
 
7
- import {ChessboardMoveInput} from "./ChessboardMoveInput.js"
8
- import {COLOR, INPUT_EVENT_TYPE, BORDER_TYPE} from "./Chessboard.js"
9
- import {ChessboardPiecesAnimation} from "./ChessboardPiecesAnimation.js"
7
+ import {MoveInput} from "./MoveInput.js"
8
+ import {COLOR, INPUT_EVENT_TYPE, BORDER_TYPE} from "../Chessboard.js"
10
9
  import {Position} from "./Position.js"
11
10
 
12
11
  export const piecesTranslations = {
@@ -42,33 +41,28 @@ export const piecesTranslations = {
42
41
 
43
42
  export function renderPieceTitle(lang, name, color = undefined) {
44
43
  let title = piecesTranslations[lang].pieces_long[name]
45
- if(color) {
44
+ if (color) {
46
45
  title += " " + piecesTranslations[lang].colors_long[color]
47
46
  }
48
47
  return title
49
48
  }
50
49
 
51
- export class ChessboardView {
50
+ export class View {
52
51
 
53
52
  constructor(chessboard) {
54
- this.animationRunning = false
55
- this.currentAnimation = undefined
56
53
  this.chessboard = chessboard
57
- this.moveInput = new ChessboardMoveInput(this,
54
+ this.moveInput = new MoveInput(this,
58
55
  this.moveStartCallback.bind(this),
59
56
  this.moveDoneCallback.bind(this),
60
57
  this.moveCanceledCallback.bind(this)
61
58
  )
62
- this.animationQueue = []
63
59
  if (chessboard.props.sprite.cache) {
64
60
  this.cacheSprite()
65
61
  }
66
62
  this.context = document.createElement("div")
67
63
  this.chessboard.context.appendChild(this.context)
68
64
  if (chessboard.props.responsive) {
69
- // noinspection JSUnresolvedVariable
70
65
  if (typeof ResizeObserver !== "undefined") {
71
- // noinspection JSUnresolvedFunction
72
66
  this.resizeObserver = new ResizeObserver(() => {
73
67
  this.handleResize()
74
68
  })
@@ -104,11 +98,11 @@ export class ChessboardView {
104
98
  }
105
99
  this.chessboard.context.removeEventListener("mousedown", this.pointerDownListener)
106
100
  this.chessboard.context.removeEventListener("touchstart", this.pointerDownListener)
107
- Svg.removeElement(this.svg)
108
101
  this.animationQueue = []
109
102
  if (this.currentAnimation) {
110
103
  cancelAnimationFrame(this.currentAnimation.frameHandle)
111
104
  }
105
+ Svg.removeElement(this.svg)
112
106
  }
113
107
 
114
108
  // Sprite //
@@ -172,6 +166,7 @@ export class ChessboardView {
172
166
  this.context.clientHeight !== this.height) {
173
167
  this.updateMetrics()
174
168
  this.redraw()
169
+ this.redrawPieces()
175
170
  }
176
171
  this.svg.setAttribute("width", "100%") // safari bugfix
177
172
  this.svg.setAttribute("height", "100%")
@@ -182,7 +177,6 @@ export class ChessboardView {
182
177
  this.drawCoordinates()
183
178
  this.drawMarkers()
184
179
  this.visualizeInputState()
185
- this.drawPieces(this.chessboard.state.position.squares)
186
180
  }
187
181
 
188
182
  // Board //
@@ -191,20 +185,20 @@ export class ChessboardView {
191
185
  while (this.boardGroup.firstChild) {
192
186
  this.boardGroup.removeChild(this.boardGroup.lastChild)
193
187
  }
194
- if (this.chessboard.props.style.borderType !== BORDER_TYPE.none) {
195
- let boardBorder = Svg.addElement(this.boardGroup, "rect", {width: this.width, height: this.height})
196
- boardBorder.setAttribute("class", "border")
197
- if (this.chessboard.props.style.borderType === BORDER_TYPE.frame) {
198
- const innerPos = this.borderSize
199
- let borderInner = Svg.addElement(this.boardGroup, "rect", {
200
- x: innerPos,
201
- y: innerPos,
202
- width: this.width - innerPos * 2,
203
- height: this.height - innerPos * 2
204
- })
205
- borderInner.setAttribute("class", "border-inner")
206
- }
188
+
189
+ let boardBorder = Svg.addElement(this.boardGroup, "rect", {width: this.width, height: this.height})
190
+ boardBorder.setAttribute("class", "border")
191
+ if (this.chessboard.props.style.borderType === BORDER_TYPE.frame) {
192
+ const innerPos = this.borderSize
193
+ let borderInner = Svg.addElement(this.boardGroup, "rect", {
194
+ x: innerPos,
195
+ y: innerPos,
196
+ width: this.width - innerPos * 2,
197
+ height: this.height - innerPos * 2
198
+ })
199
+ borderInner.setAttribute("class", "border-inner")
207
200
  }
201
+
208
202
  for (let i = 0; i < 64; i++) {
209
203
  const index = this.chessboard.state.orientation === COLOR.white ? i : 63 - i
210
204
  const squareColor = ((9 * index) & 8) === 0 ? 'black' : 'white'
@@ -276,7 +270,7 @@ export class ChessboardView {
276
270
 
277
271
  // Pieces //
278
272
 
279
- drawPieces(squares = this.chessboard.state.position.squares) {
273
+ redrawPieces(squares = this.chessboard.state.position.squares) {
280
274
  const childNodes = Array.from(this.piecesGroup.childNodes)
281
275
  for (let i = 0; i < 64; i++) {
282
276
  const pieceName = squares[i]
@@ -314,7 +308,7 @@ export class ChessboardView {
314
308
  }
315
309
 
316
310
  setPieceVisibility(square, visible = true) {
317
- const piece = this.getPiece(square)
311
+ const piece = this.getPieceElement(square)
318
312
  if (visible) {
319
313
  piece.setAttribute("visibility", "visible")
320
314
  } else {
@@ -322,11 +316,15 @@ export class ChessboardView {
322
316
  }
323
317
  }
324
318
 
325
- getPiece(square) {
326
- if(square.length < 2) {
319
+ getPieceElement(square) {
320
+ if (square.length < 2) {
327
321
  throw new Error("980e03")
328
322
  }
329
- return this.piecesGroup.querySelector(`g[data-square='${square}']`)
323
+ const piece = this.piecesGroup.querySelector(`g[data-square='${square}']`)
324
+ if (!piece) {
325
+ console.error("no piece found on", square)
326
+ }
327
+ return piece
330
328
  }
331
329
 
332
330
  // Markers //
@@ -358,32 +356,6 @@ export class ChessboardView {
358
356
  return markerGroup
359
357
  }
360
358
 
361
- // animation queue //
362
-
363
- animatePieces(fromSquares, toSquares, callback) {
364
- this.animationQueue.push({fromSquares: fromSquares, toSquares: toSquares, callback: callback})
365
- if (!this.animationRunning) {
366
- this.nextPieceAnimationInQueue()
367
- }
368
- }
369
-
370
- nextPieceAnimationInQueue() {
371
- const nextAnimation = this.animationQueue.shift()
372
- if (nextAnimation !== undefined) {
373
- this.animationRunning = true
374
- this.currentAnimation = new ChessboardPiecesAnimation(this, nextAnimation.fromSquares, nextAnimation.toSquares, this.chessboard.props.animationDuration / (this.animationQueue.length + 1), () => {
375
- if (!this.moveInput.draggablePiece) {
376
- this.drawPieces(nextAnimation.toSquares)
377
- }
378
- this.animationRunning = false
379
- this.nextPieceAnimationInQueue()
380
- if (nextAnimation.callback) {
381
- nextAnimation.callback()
382
- }
383
- })
384
- }
385
- }
386
-
387
359
  // enable and disable move input //
388
360
 
389
361
  enableMoveInput(eventHandler, color = undefined) {
@@ -3,9 +3,9 @@
3
3
  * Repository: https://github.com/shaack/cm-chessboard
4
4
  * License: MIT, see file 'LICENSE'
5
5
  */
6
- import {ChessboardView, renderPieceTitle} from "./ChessboardView.js"
7
- import {COLOR, INPUT_EVENT_TYPE} from "./Chessboard.js"
8
- import {piecesTranslations} from "./ChessboardView.js"
6
+ import {View, renderPieceTitle} from "./View.js"
7
+ import {COLOR, INPUT_EVENT_TYPE} from "../Chessboard.js"
8
+ import {piecesTranslations} from "./View.js"
9
9
 
10
10
  const hlTranslations = {
11
11
  de: {
@@ -32,7 +32,7 @@ const hlTranslations = {
32
32
  }
33
33
  }
34
34
 
35
- export class ChessboardViewAccessible extends ChessboardView {
35
+ export class ViewAccessible extends View {
36
36
 
37
37
  constructor(chessboard, callbackAfterCreation) {
38
38
  super(chessboard, callbackAfterCreation)
@@ -103,8 +103,8 @@ export class ChessboardViewAccessible extends ChessboardView {
103
103
  }
104
104
  }
105
105
 
106
- drawPieces(squares = this.chessboard.state.position.squares) {
107
- super.drawPieces(squares)
106
+ redrawPieces(squares = this.chessboard.state.position.squares) {
107
+ super.redrawPieces(squares)
108
108
  setTimeout(() => {
109
109
  if(this.chessboard.props.accessibility.boardAsTable) {
110
110
  this.redrawBoardAsTable()