cm-chessboard 7.2.7 → 7.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cm-chessboard",
3
- "version": "7.2.7",
3
+ "version": "7.3.0",
4
4
  "description": "A JavaScript chessboard which is lightweight, ES6 module based, responsive, SVG rendered and without dependencies.",
5
5
  "keywords": [
6
6
  "chess",
@@ -7,24 +7,54 @@ import {Extension, EXTENSION_POINT} from "../../model/Extension.js"
7
7
  import {COLOR, PIECE} from "../../Chessboard.js"
8
8
  import {Svg} from "../../lib/Svg.js"
9
9
  import {Utils} from "../../lib/Utils.js"
10
+ import {ANIMATION_EVENT_TYPE} from "../../view/PositionAnimationsQueue.js"
11
+
12
+ const DISPLAY_STATE = {
13
+ hidden: "hidden",
14
+ displayRequested: "displayRequested",
15
+ shown: "shown"
16
+ }
10
17
 
11
18
  export class PromotionDialog extends Extension {
12
19
 
13
20
  constructor(chessboard, props = {}) {
14
21
  super(chessboard, props)
15
- this.registerExtensionPoint(EXTENSION_POINT.redrawBoard, this.redrawDialog.bind(this))
22
+ this.registerExtensionPoint(EXTENSION_POINT.redrawBoard, this.extensionPointRedrawBoard.bind(this))
23
+ this.registerExtensionPoint(EXTENSION_POINT.animation, this.extensionPointAnimation.bind(this))
16
24
  this.registerMethod("showPromotionDialog", this.showPromotionDialog)
17
25
  this.promotionDialogGroup = Svg.addElement(chessboard.view.markersTopLayer, "g", {class: "promotion-dialog-group"})
18
- Utils.delegate(this.promotionDialogGroup, "click", ".promotion-dialog-button",
19
- this.promotionDialogOnClickPiece.bind(this))
20
26
  this.state = {
21
- isShown: false,
22
- color: undefined,
23
- square: undefined,
24
- callback: undefined
27
+ displayState: DISPLAY_STATE.hidden,
28
+ callback: undefined,
29
+ dialogParams: {
30
+ square: undefined,
31
+ color: undefined
32
+ }
33
+ }
34
+ }
35
+
36
+ // public (registerMethod)
37
+ showPromotionDialog(square, color, callback) {
38
+ this.state.dialogParams.square = square
39
+ this.state.dialogParams.color = color
40
+ this.state.callback = callback
41
+ this.setDisplayState(DISPLAY_STATE.displayRequested)
42
+ }
43
+
44
+ // private
45
+ extensionPointRedrawBoard() {
46
+ this.redrawDialog()
47
+ }
48
+
49
+ extensionPointAnimation(event) {
50
+ if (event.type === ANIMATION_EVENT_TYPE.end) {
51
+ if (this.state.displayState === DISPLAY_STATE.displayRequested) {
52
+ this.setDisplayState(DISPLAY_STATE.shown)
53
+ }
25
54
  }
26
55
  }
27
56
 
57
+
28
58
  drawPieceButton(piece, point) {
29
59
  const squareWidth = this.chessboard.view.squareWidth
30
60
  const squareHeight = this.chessboard.view.squareHeight
@@ -38,96 +68,109 @@ export class PromotionDialog extends Extension {
38
68
  }
39
69
 
40
70
  redrawDialog() {
41
- if (!this.state.square) {
42
- return
71
+ while (this.promotionDialogGroup.firstChild) {
72
+ this.promotionDialogGroup.removeChild(this.promotionDialogGroup.firstChild)
43
73
  }
44
- clearTimeout(this.redrawDialogDebounce)
45
- this.redrawDialogDebounce = setTimeout(() => {
74
+ if (this.state.displayState === DISPLAY_STATE.shown) {
46
75
  const squareWidth = this.chessboard.view.squareWidth
47
76
  const squareHeight = this.chessboard.view.squareHeight
48
- const squareCenterPoint = this.chessboard.view.squareToPoint(this.state.square)
77
+ const squareCenterPoint = this.chessboard.view.squareToPoint(this.state.dialogParams.square)
49
78
  squareCenterPoint.x = squareCenterPoint.x + squareWidth / 2
50
79
  squareCenterPoint.y = squareCenterPoint.y + squareHeight / 2
51
- while (this.promotionDialogGroup.firstChild) {
52
- this.promotionDialogGroup.removeChild(this.promotionDialogGroup.firstChild)
80
+ let turned = false
81
+ const rank = parseInt(this.state.dialogParams.square.charAt(1), 10)
82
+ if (this.chessboard.getOrientation() === COLOR.white && rank < 5 ||
83
+ this.chessboard.getOrientation() === COLOR.black && rank >= 5) {
84
+ turned = true
53
85
  }
54
- if (this.state.isShown) {
55
- let turned = false
56
- const rank = parseInt(this.state.square.charAt(1), 10)
57
- if (this.chessboard.getOrientation() === COLOR.white && rank < 5 ||
58
- this.chessboard.getOrientation() === COLOR.black && rank >= 5) {
59
- turned = true
60
- }
61
- const offsetY = turned ? -4 * squareHeight : 0
62
- const offsetX = squareCenterPoint.x + squareWidth > this.chessboard.view.width ? -squareWidth : 0
63
- Svg.addElement(this.promotionDialogGroup,
64
- "rect", {
65
- x: squareCenterPoint.x + offsetX,
66
- y: squareCenterPoint.y + offsetY,
67
- width: squareWidth,
68
- height: squareHeight * 4,
69
- class: "promotion-dialog"
70
- })
71
- if (turned) {
72
- this.drawPieceButton(PIECE[this.state.color + "q"], {
73
- x: squareCenterPoint.x + offsetX,
74
- y: squareCenterPoint.y - squareHeight
75
- })
76
- this.drawPieceButton(PIECE[this.state.color + "r"], {
77
- x: squareCenterPoint.x + offsetX,
78
- y: squareCenterPoint.y - squareHeight * 2
79
- })
80
- this.drawPieceButton(PIECE[this.state.color + "b"], {
81
- x: squareCenterPoint.x + offsetX,
82
- y: squareCenterPoint.y - squareHeight * 3
83
- })
84
- this.drawPieceButton(PIECE[this.state.color + "n"], {
85
- x: squareCenterPoint.x + offsetX,
86
- y: squareCenterPoint.y - squareHeight * 4
87
- })
88
- } else {
89
- this.drawPieceButton(PIECE[this.state.color + "q"], {
90
- x: squareCenterPoint.x + offsetX,
91
- y: squareCenterPoint.y
92
- })
93
- this.drawPieceButton(PIECE[this.state.color + "r"], {
94
- x: squareCenterPoint.x + offsetX,
95
- y: squareCenterPoint.y + squareHeight
96
- })
97
- this.drawPieceButton(PIECE[this.state.color + "b"], {
98
- x: squareCenterPoint.x + offsetX,
99
- y: squareCenterPoint.y + squareHeight * 2
100
- })
101
- this.drawPieceButton(PIECE[this.state.color + "n"], {
102
- x: squareCenterPoint.x + offsetX,
103
- y: squareCenterPoint.y + squareHeight * 3
104
- })
105
- }
86
+ const offsetY = turned ? -4 * squareHeight : 0
87
+ const offsetX = squareCenterPoint.x + squareWidth > this.chessboard.view.width ? -squareWidth : 0
88
+ Svg.addElement(this.promotionDialogGroup,
89
+ "rect", {
90
+ x: squareCenterPoint.x + offsetX,
91
+ y: squareCenterPoint.y + offsetY,
92
+ width: squareWidth,
93
+ height: squareHeight * 4,
94
+ class: "promotion-dialog"
95
+ })
96
+ const dialogParams = this.state.dialogParams
97
+ if (turned) {
98
+ this.drawPieceButton(PIECE[dialogParams.color + "q"], {
99
+ x: squareCenterPoint.x + offsetX,
100
+ y: squareCenterPoint.y - squareHeight
101
+ })
102
+ this.drawPieceButton(PIECE[dialogParams.color + "r"], {
103
+ x: squareCenterPoint.x + offsetX,
104
+ y: squareCenterPoint.y - squareHeight * 2
105
+ })
106
+ this.drawPieceButton(PIECE[dialogParams.color + "b"], {
107
+ x: squareCenterPoint.x + offsetX,
108
+ y: squareCenterPoint.y - squareHeight * 3
109
+ })
110
+ this.drawPieceButton(PIECE[dialogParams.color + "n"], {
111
+ x: squareCenterPoint.x + offsetX,
112
+ y: squareCenterPoint.y - squareHeight * 4
113
+ })
114
+ } else {
115
+ this.drawPieceButton(PIECE[dialogParams.color + "q"], {
116
+ x: squareCenterPoint.x + offsetX,
117
+ y: squareCenterPoint.y
118
+ })
119
+ this.drawPieceButton(PIECE[dialogParams.color + "r"], {
120
+ x: squareCenterPoint.x + offsetX,
121
+ y: squareCenterPoint.y + squareHeight
122
+ })
123
+ this.drawPieceButton(PIECE[dialogParams.color + "b"], {
124
+ x: squareCenterPoint.x + offsetX,
125
+ y: squareCenterPoint.y + squareHeight * 2
126
+ })
127
+ this.drawPieceButton(PIECE[dialogParams.color + "n"], {
128
+ x: squareCenterPoint.x + offsetX,
129
+ y: squareCenterPoint.y + squareHeight * 3
130
+ })
106
131
  }
107
- }, 200)
132
+ }
108
133
  }
109
134
 
110
135
  promotionDialogOnClickPiece(event) {
111
- this.state.isShown = false
112
- this.chessboard.disableSquareSelect()
113
- this.state.callback({square: this.state.square, piece: event.target.dataset.piece})
114
- this.redrawDialog()
136
+ if(event.button !== 2) {
137
+ if (event.target.dataset.piece) {
138
+ this.state.callback({square: this.state.dialogParams.square, piece: event.target.dataset.piece})
139
+ this.setDisplayState(DISPLAY_STATE.hidden)
140
+ } else {
141
+ this.promotionDialogOnCancel(event)
142
+ }
143
+ }
115
144
  }
116
145
 
117
- showPromotionDialog(square, color, callback) {
118
- this.state.isShown = true
119
- this.state.square = square
120
- this.state.color = color
121
- this.state.callback = callback
122
- const mousedownListener = (event) => {
123
- if (!event.target.dataset.piece && this.state.isShown) {
124
- this.state.isShown = false
125
- this.state.callback({square: this.state.square, piece: null})
126
- this.redrawDialog()
127
- }
128
- this.chessboard.view.svg.removeEventListener("mousedown", mousedownListener)
146
+ promotionDialogOnCancel(event) {
147
+ if(this.state.displayState === DISPLAY_STATE.shown) {
148
+ event.preventDefault()
149
+ this.setDisplayState(DISPLAY_STATE.hidden)
150
+ this.state.callback({square: this.state.square, piece: null})
151
+ }
152
+ }
153
+
154
+ contextMenu(event) {
155
+ event.preventDefault()
156
+ this.setDisplayState(DISPLAY_STATE.hidden)
157
+ this.state.callback({square: this.state.square, piece: null})
158
+ }
159
+
160
+ setDisplayState(displayState) {
161
+ this.state.displayState = displayState
162
+ if(displayState === DISPLAY_STATE.shown) {
163
+ this.clickDelegate = Utils.delegate(this.chessboard.context,
164
+ "mousedown",
165
+ "*",
166
+ this.promotionDialogOnClickPiece.bind(this))
167
+ this.contextMenuListener = this.contextMenu.bind(this)
168
+ this.chessboard.context.addEventListener("contextmenu", this.contextMenuListener)
169
+ } else if(displayState === DISPLAY_STATE.hidden) {
170
+ this.clickDelegate.remove()
171
+ console.log("e16536 removeEventListener")
172
+ this.chessboard.context.removeEventListener("contextmenu", this.contextMenuListener)
129
173
  }
130
- this.chessboard.view.svg.addEventListener("mousedown", mousedownListener)
131
174
  this.redrawDialog()
132
175
  }
133
176
 
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import {Extension, EXTENSION_POINT} from "../../model/Extension.js"
8
+ import {ANIMATION_EVENT_TYPE} from "../../view/PositionAnimationsQueue.js"
8
9
 
9
10
  export class RenderVideo extends Extension {
10
11
 
@@ -31,7 +32,7 @@ export class RenderVideo extends Extension {
31
32
  console.log("recorder mediaType", this.props.mediaType)
32
33
  this.makeSpriteInline()
33
34
  this.registerExtensionPoint(EXTENSION_POINT.animation, async (event) => {
34
- if(event.event === "frame") {
35
+ if(event.type === ANIMATION_EVENT_TYPE.frame) {
35
36
  if (this.recorder && this.recorder.state === "recording") {
36
37
  await this.cloneImageAndRender()
37
38
  }
@@ -12,7 +12,7 @@ import {EXTENSION_POINT} from "../model/Extension.js"
12
12
  * https://medium.com/@karenmarkosyan/how-to-manage-promises-into-dynamic-queue-with-vanilla-javascript-9d0d1f8d4df5
13
13
  */
14
14
 
15
- export const ANIMATION_EVENT = {
15
+ export const ANIMATION_EVENT_TYPE = {
16
16
  start: "start",
17
17
  frame: "frame",
18
18
  end: "end"
@@ -174,7 +174,7 @@ export class PositionsAnimation {
174
174
  if (!this.startTime) {
175
175
  this.startTime = time
176
176
  this.view.chessboard.state.invokeExtensionPoints(EXTENSION_POINT.animation, {
177
- event: ANIMATION_EVENT.start
177
+ type: ANIMATION_EVENT_TYPE.start
178
178
  })
179
179
  }
180
180
  const timeDiff = time - this.startTime
@@ -189,7 +189,7 @@ export class PositionsAnimation {
189
189
  }
190
190
  })
191
191
  this.view.chessboard.state.invokeExtensionPoints(EXTENSION_POINT.animation, {
192
- event: ANIMATION_EVENT.end
192
+ type: ANIMATION_EVENT_TYPE.end
193
193
  })
194
194
  this.callback()
195
195
  return
@@ -200,7 +200,6 @@ export class PositionsAnimation {
200
200
  progress = 1
201
201
  }
202
202
  this.animatedElements.forEach((animatedItem) => {
203
- // console.log("animatedItem", animatedItem)
204
203
  if (animatedItem.element) {
205
204
  switch (animatedItem.type) {
206
205
  case CHANGE_TYPE.move:
@@ -223,7 +222,7 @@ export class PositionsAnimation {
223
222
  }
224
223
  })
225
224
  this.view.chessboard.state.invokeExtensionPoints(EXTENSION_POINT.animation, {
226
- event: ANIMATION_EVENT.frame,
225
+ type: ANIMATION_EVENT_TYPE.frame,
227
226
  progress: progress
228
227
  })
229
228
  }
@@ -254,7 +253,6 @@ export class PositionAnimationsQueue extends PromiseQueue {
254
253
  if (this.queue.length > 0) {
255
254
  duration = duration / (1 + Math.pow(this.queue.length / 5, 2))
256
255
  }
257
- // console.log("duration", duration, animated, "this.chessboard.props.animationDuration", this.chessboard.props.animationDuration)
258
256
  new PositionsAnimation(this.chessboard.view,
259
257
  positionFrom, positionTo, animated ? duration : 0,
260
258
  () => {