cm-chessboard 7.2.7 → 7.3.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
CHANGED
|
@@ -25,7 +25,7 @@ The core of cm-chessboard is small, fast and reduced to the essentials. You can
|
|
|
25
25
|
- [Accessibility Extension](https://shaack.com/projekte/cm-chessboard/examples/extensions/accessibility-extension.html) - makes the chessboard more accessible
|
|
26
26
|
- [Arrows Extension](https://shaack.com/projekte/cm-chessboard/examples/extensions/arrows-extension.html) - renders arrows on the chessboard
|
|
27
27
|
- [Markers Extension](https://shaack.com/projekte/cm-chessboard/examples/extensions/markers-extension.html) 🆕 - create markers on specific squares
|
|
28
|
-
- [PromotionDialog Extension](https://shaack.com/projekte/cm-chessboard/examples/extensions/promotion-dialog-extension.html) - shows a dialog to select the piece to promote to
|
|
28
|
+
- [PromotionDialog Extension](https://shaack.com/projekte/cm-chessboard/examples/extensions/promotion-dialog-extension.html) 🆕 - shows a dialog to select the piece to promote to
|
|
29
29
|
- [RenderVideo Extension](https://shaack.com/projekte/cm-chessboard/examples/extensions/render-video-extension.html) 🆕 - renders a video from the pieces movement on the board
|
|
30
30
|
|
|
31
31
|
## Demo and repository
|
package/index.html
CHANGED
|
@@ -31,7 +31,7 @@ It works, it is cool and it is easy to use. 👍</p>
|
|
|
31
31
|
<li><a href="examples/extensions/accessibility-extension.html">Accessibility extension</a></li>
|
|
32
32
|
<li><a href="examples/extensions/arrows-extension.html">Arrows extension</a></li>
|
|
33
33
|
<li><a href="examples/extensions/markers-extension.html">Markers extension</a> 🆕</li>
|
|
34
|
-
<li><a href="examples/extensions/promotion-dialog-extension.html">PromotionDialog extension</a
|
|
34
|
+
<li><a href="examples/extensions/promotion-dialog-extension.html">PromotionDialog extension</a> 🆕</li>
|
|
35
35
|
<li><a href="examples/extensions/render-video-extension.html">RenderVideo extension</a> 🆕</li>
|
|
36
36
|
</ul>
|
|
37
37
|
</div>
|
package/package.json
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
42
|
-
|
|
71
|
+
while (this.promotionDialogGroup.firstChild) {
|
|
72
|
+
this.promotionDialogGroup.removeChild(this.promotionDialogGroup.firstChild)
|
|
43
73
|
}
|
|
44
|
-
|
|
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
|
-
|
|
52
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
}
|
|
132
|
+
}
|
|
108
133
|
}
|
|
109
134
|
|
|
110
135
|
promotionDialogOnClickPiece(event) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
118
|
-
this.state.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
() => {
|