@alepot55/chessboardjs 2.2.1 → 2.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/README.md +125 -401
- package/assets/themes/alepot/theme.json +42 -0
- package/assets/themes/default/theme.json +42 -0
- package/dist/chessboard.cjs.js +11785 -0
- package/dist/chessboard.css +243 -0
- package/dist/chessboard.esm.js +11716 -0
- package/dist/chessboard.iife.js +11791 -0
- package/dist/chessboard.umd.js +11791 -0
- package/package.json +33 -3
- package/{chessboard.move.js → src/components/Move.js} +3 -3
- package/src/components/Piece.js +771 -0
- package/{chessboard.square.js → src/components/Square.js} +61 -8
- package/src/constants/index.js +15 -0
- package/src/constants/positions.js +62 -0
- package/src/core/Chessboard.js +2346 -0
- package/src/core/ChessboardConfig.js +707 -0
- package/src/core/ChessboardFactory.js +385 -0
- package/src/core/index.js +141 -0
- package/src/errors/ChessboardError.js +133 -0
- package/src/errors/index.js +15 -0
- package/src/errors/messages.js +189 -0
- package/src/index.js +103 -0
- package/src/services/AnimationService.js +180 -0
- package/src/services/BoardService.js +156 -0
- package/src/services/CoordinateService.js +355 -0
- package/src/services/EventService.js +955 -0
- package/src/services/MoveService.js +567 -0
- package/src/services/PieceService.js +339 -0
- package/src/services/PositionService.js +237 -0
- package/src/services/ValidationService.js +673 -0
- package/src/services/index.js +14 -0
- package/src/styles/animations.css +46 -0
- package/{chessboard.css → src/styles/board.css} +30 -7
- package/src/styles/index.css +4 -0
- package/src/styles/pieces.css +70 -0
- package/src/utils/animations.js +37 -0
- package/{chess.js → src/utils/chess.js} +16 -16
- package/src/utils/coordinates.js +62 -0
- package/src/utils/cross-browser.js +150 -0
- package/src/utils/logger.js +422 -0
- package/src/utils/performance.js +311 -0
- package/src/utils/validation.js +458 -0
- package/.babelrc +0 -4
- package/chessboard.bundle.js +0 -3422
- package/chessboard.config.js +0 -147
- package/chessboard.js +0 -979
- package/chessboard.piece.js +0 -115
- package/jest.config.js +0 -7
- package/rollup.config.js +0 -11
- package/test/chessboard.test.js +0 -128
- /package/{alepot_theme → assets/themes/alepot}/bb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/bw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/kb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/kw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/nb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/nw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/pb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/pw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/qb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/qw.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/rb.svg +0 -0
- /package/{alepot_theme → assets/themes/alepot}/rw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/bb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/bw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/kb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/kw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/nb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/nw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/pb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/pw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/qb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/qw.svg +0 -0
- /package/{default_pieces → assets/themes/default}/rb.svg +0 -0
- /package/{default_pieces → assets/themes/default}/rw.svg +0 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service for managing coordinate conversions and board orientation
|
|
3
|
+
* @module services/CoordinateService
|
|
4
|
+
* @since 2.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { BOARD_LETTERS } from '../constants/positions.js';
|
|
8
|
+
import { ValidationError } from '../errors/ChessboardError.js';
|
|
9
|
+
import { ERROR_MESSAGES } from '../errors/messages.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Service responsible for coordinate conversions and board orientation
|
|
13
|
+
* @class
|
|
14
|
+
*/
|
|
15
|
+
export class CoordinateService {
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new CoordinateService instance
|
|
18
|
+
* @param {ChessboardConfig} config - Board configuration
|
|
19
|
+
*/
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Converts logical coordinates to real coordinates based on board orientation
|
|
26
|
+
* @param {number} row - Row index (0-7)
|
|
27
|
+
* @param {number} col - Column index (0-7)
|
|
28
|
+
* @returns {Array<number>} Real coordinates [row, col] (1-8)
|
|
29
|
+
*/
|
|
30
|
+
realCoord(row, col) {
|
|
31
|
+
let realRow = row;
|
|
32
|
+
let realCol = col;
|
|
33
|
+
|
|
34
|
+
if (this.isWhiteOriented()) {
|
|
35
|
+
realRow = 7 - row;
|
|
36
|
+
} else {
|
|
37
|
+
realCol = 7 - col;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return [realRow + 1, realCol + 1];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Converts board coordinates to square ID
|
|
45
|
+
* @param {number} row - Row index (0-7)
|
|
46
|
+
* @param {number} col - Column index (0-7)
|
|
47
|
+
* @returns {string} Square ID (e.g., 'e4')
|
|
48
|
+
*/
|
|
49
|
+
getSquareID(row, col) {
|
|
50
|
+
row = parseInt(row);
|
|
51
|
+
col = parseInt(col);
|
|
52
|
+
|
|
53
|
+
if (this.isWhiteOriented()) {
|
|
54
|
+
row = 8 - row;
|
|
55
|
+
col = col + 1;
|
|
56
|
+
} else {
|
|
57
|
+
row = row + 1;
|
|
58
|
+
col = 8 - col;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (col < 1 || col > 8 || row < 1 || row > 8) {
|
|
62
|
+
throw new ValidationError(
|
|
63
|
+
`Invalid board coordinates: row=${row}, col=${col}`,
|
|
64
|
+
'coordinates',
|
|
65
|
+
{ row, col }
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const letter = BOARD_LETTERS[col - 1];
|
|
70
|
+
return letter + row;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Converts square ID to board coordinates
|
|
75
|
+
* @param {string} squareId - Square ID (e.g., 'e4')
|
|
76
|
+
* @returns {Array<number>} Board coordinates [row, col] (0-7)
|
|
77
|
+
*/
|
|
78
|
+
getCoordinatesFromSquareID(squareId) {
|
|
79
|
+
if (typeof squareId !== 'string' || squareId.length !== 2) {
|
|
80
|
+
throw new ValidationError(
|
|
81
|
+
ERROR_MESSAGES.invalid_square + squareId,
|
|
82
|
+
'squareId',
|
|
83
|
+
squareId
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const letter = squareId[0];
|
|
88
|
+
const number = parseInt(squareId[1]);
|
|
89
|
+
|
|
90
|
+
const col = BOARD_LETTERS.indexOf(letter);
|
|
91
|
+
if (col === -1) {
|
|
92
|
+
throw new ValidationError(
|
|
93
|
+
ERROR_MESSAGES.invalid_square + squareId,
|
|
94
|
+
'squareId',
|
|
95
|
+
squareId
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (number < 1 || number > 8) {
|
|
100
|
+
throw new ValidationError(
|
|
101
|
+
ERROR_MESSAGES.invalid_square + squareId,
|
|
102
|
+
'squareId',
|
|
103
|
+
squareId
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let row, boardCol;
|
|
108
|
+
|
|
109
|
+
if (this.isWhiteOriented()) {
|
|
110
|
+
row = 8 - number;
|
|
111
|
+
boardCol = col;
|
|
112
|
+
} else {
|
|
113
|
+
row = number - 1;
|
|
114
|
+
boardCol = 7 - col;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return [row, boardCol];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Converts pixel coordinates to square ID
|
|
122
|
+
* @param {number} x - X coordinate in pixels
|
|
123
|
+
* @param {number} y - Y coordinate in pixels
|
|
124
|
+
* @param {HTMLElement} boardElement - Board DOM element
|
|
125
|
+
* @returns {string|null} Square ID or null if outside board
|
|
126
|
+
*/
|
|
127
|
+
pixelToSquareID(x, y, boardElement) {
|
|
128
|
+
if (!boardElement) return null;
|
|
129
|
+
|
|
130
|
+
const rect = boardElement.getBoundingClientRect();
|
|
131
|
+
const { width, height } = rect;
|
|
132
|
+
|
|
133
|
+
// Check if coordinates are within board bounds
|
|
134
|
+
if (x < 0 || x >= width || y < 0 || y >= height) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const squareWidth = width / 8;
|
|
139
|
+
const squareHeight = height / 8;
|
|
140
|
+
|
|
141
|
+
const col = Math.floor(x / squareWidth);
|
|
142
|
+
const row = Math.floor(y / squareHeight);
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
return this.getSquareID(row, col);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Converts square ID to pixel coordinates
|
|
153
|
+
* @param {string} squareId - Square ID (e.g., 'e4')
|
|
154
|
+
* @param {HTMLElement} boardElement - Board DOM element
|
|
155
|
+
* @returns {Object|null} Pixel coordinates {x, y} or null if invalid
|
|
156
|
+
*/
|
|
157
|
+
squareIDToPixel(squareId, boardElement) {
|
|
158
|
+
if (!boardElement) return null;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const [row, col] = this.getCoordinatesFromSquareID(squareId);
|
|
162
|
+
const rect = boardElement.getBoundingClientRect();
|
|
163
|
+
const { width, height } = rect;
|
|
164
|
+
|
|
165
|
+
const squareWidth = width / 8;
|
|
166
|
+
const squareHeight = height / 8;
|
|
167
|
+
|
|
168
|
+
const x = col * squareWidth;
|
|
169
|
+
const y = row * squareHeight;
|
|
170
|
+
|
|
171
|
+
return { x, y };
|
|
172
|
+
} catch (error) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Gets the center pixel coordinates of a square
|
|
179
|
+
* @param {string} squareId - Square ID (e.g., 'e4')
|
|
180
|
+
* @param {HTMLElement} boardElement - Board DOM element
|
|
181
|
+
* @returns {Object|null} Center coordinates {x, y} or null if invalid
|
|
182
|
+
*/
|
|
183
|
+
getSquareCenter(squareId, boardElement) {
|
|
184
|
+
const coords = this.squareIDToPixel(squareId, boardElement);
|
|
185
|
+
if (!coords) return null;
|
|
186
|
+
|
|
187
|
+
const rect = boardElement.getBoundingClientRect();
|
|
188
|
+
const squareWidth = rect.width / 8;
|
|
189
|
+
const squareHeight = rect.height / 8;
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
x: coords.x + squareWidth / 2,
|
|
193
|
+
y: coords.y + squareHeight / 2
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Calculates the distance between two squares
|
|
199
|
+
* @param {string} fromSquare - Source square ID
|
|
200
|
+
* @param {string} toSquare - Target square ID
|
|
201
|
+
* @returns {number} Distance between squares
|
|
202
|
+
*/
|
|
203
|
+
getSquareDistance(fromSquare, toSquare) {
|
|
204
|
+
try {
|
|
205
|
+
const [fromRow, fromCol] = this.getCoordinatesFromSquareID(fromSquare);
|
|
206
|
+
const [toRow, toCol] = this.getCoordinatesFromSquareID(toSquare);
|
|
207
|
+
|
|
208
|
+
const rowDiff = Math.abs(toRow - fromRow);
|
|
209
|
+
const colDiff = Math.abs(toCol - fromCol);
|
|
210
|
+
|
|
211
|
+
return Math.sqrt(rowDiff * rowDiff + colDiff * colDiff);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Checks if the board is oriented from white's perspective
|
|
219
|
+
* @returns {boolean} True if white-oriented
|
|
220
|
+
*/
|
|
221
|
+
isWhiteOriented() {
|
|
222
|
+
return this.config.orientation === 'w';
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Checks if the board is oriented from black's perspective
|
|
227
|
+
* @returns {boolean} True if black-oriented
|
|
228
|
+
*/
|
|
229
|
+
isBlackOriented() {
|
|
230
|
+
return this.config.orientation === 'b';
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Flips the board orientation
|
|
235
|
+
*/
|
|
236
|
+
flipOrientation() {
|
|
237
|
+
this.config.orientation = this.isWhiteOriented() ? 'b' : 'w';
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Sets the board orientation
|
|
242
|
+
* @param {string} orientation - 'w' for white, 'b' for black
|
|
243
|
+
* @throws {ValidationError} When orientation is invalid
|
|
244
|
+
*/
|
|
245
|
+
setOrientation(orientation) {
|
|
246
|
+
if (orientation !== 'w' && orientation !== 'b') {
|
|
247
|
+
throw new ValidationError(
|
|
248
|
+
ERROR_MESSAGES.invalid_orientation + orientation,
|
|
249
|
+
'orientation',
|
|
250
|
+
orientation
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
this.config.orientation = orientation;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Gets the current orientation
|
|
259
|
+
* @returns {string} Current orientation ('w' or 'b')
|
|
260
|
+
*/
|
|
261
|
+
getOrientation() {
|
|
262
|
+
return this.config.orientation;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Sets the orientation
|
|
267
|
+
* @param {string} orientation - New orientation ('w', 'b', 'white', 'black')
|
|
268
|
+
*/
|
|
269
|
+
setOrientation(orientation) {
|
|
270
|
+
// Normalize orientation
|
|
271
|
+
const normalizedOrientation = orientation === 'white' ? 'w' :
|
|
272
|
+
orientation === 'black' ? 'b' : orientation;
|
|
273
|
+
|
|
274
|
+
if (normalizedOrientation !== 'w' && normalizedOrientation !== 'b') {
|
|
275
|
+
throw new ValidationError(
|
|
276
|
+
ERROR_MESSAGES.invalid_orientation + orientation,
|
|
277
|
+
'orientation',
|
|
278
|
+
orientation
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
this.config.orientation = normalizedOrientation;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Flips the board orientation
|
|
287
|
+
*/
|
|
288
|
+
flipOrientation() {
|
|
289
|
+
this.config.orientation = this.isWhiteOriented() ? 'b' : 'w';
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Gets all square IDs in order
|
|
294
|
+
* @returns {Array<string>} Array of all square IDs
|
|
295
|
+
*/
|
|
296
|
+
getAllSquareIDs() {
|
|
297
|
+
const squares = [];
|
|
298
|
+
|
|
299
|
+
for (let row = 0; row < 8; row++) {
|
|
300
|
+
for (let col = 0; col < 8; col++) {
|
|
301
|
+
squares.push(this.getSquareID(row, col));
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return squares;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Gets squares in a specific rank (row)
|
|
310
|
+
* @param {number} rank - Rank number (1-8)
|
|
311
|
+
* @returns {Array<string>} Array of square IDs in the rank
|
|
312
|
+
*/
|
|
313
|
+
getSquaresByRank(rank) {
|
|
314
|
+
if (rank < 1 || rank > 8) {
|
|
315
|
+
throw new ValidationError(
|
|
316
|
+
`Invalid rank: ${rank}`,
|
|
317
|
+
'rank',
|
|
318
|
+
rank
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const squares = [];
|
|
323
|
+
|
|
324
|
+
for (let col = 0; col < 8; col++) {
|
|
325
|
+
const row = this.isWhiteOriented() ? 8 - rank : rank - 1;
|
|
326
|
+
squares.push(this.getSquareID(row, col));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return squares;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Gets squares in a specific file (column)
|
|
334
|
+
* @param {string} file - File letter (a-h)
|
|
335
|
+
* @returns {Array<string>} Array of square IDs in the file
|
|
336
|
+
*/
|
|
337
|
+
getSquaresByFile(file) {
|
|
338
|
+
const col = BOARD_LETTERS.indexOf(file);
|
|
339
|
+
if (col === -1) {
|
|
340
|
+
throw new ValidationError(
|
|
341
|
+
`Invalid file: ${file}`,
|
|
342
|
+
'file',
|
|
343
|
+
file
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const squares = [];
|
|
348
|
+
|
|
349
|
+
for (let row = 0; row < 8; row++) {
|
|
350
|
+
squares.push(this.getSquareID(row, col));
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return squares;
|
|
354
|
+
}
|
|
355
|
+
}
|