@alepot55/chessboardjs 2.2.1 → 2.2.2
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/.eslintrc.json +227 -0
- package/README.md +125 -401
- package/assets/themes/alepot/theme.json +42 -0
- package/assets/themes/default/theme.json +42 -0
- package/chessboard.bundle.js +708 -58
- package/config/jest.config.js +15 -0
- package/config/rollup.config.js +36 -0
- package/dist/chessboard.cjs.js +10690 -0
- package/dist/chessboard.css +228 -0
- package/dist/chessboard.esm.js +10621 -0
- package/dist/chessboard.iife.js +10696 -0
- package/dist/chessboard.umd.js +10696 -0
- package/jest.config.js +2 -7
- package/package.json +18 -3
- package/rollup.config.js +2 -11
- package/{chessboard.move.js → src/components/Move.js} +3 -3
- package/src/components/Piece.js +288 -0
- package/{chessboard.square.js → src/components/Square.js} +60 -7
- package/src/constants/index.js +15 -0
- package/src/constants/positions.js +62 -0
- package/src/core/Chessboard.js +1939 -0
- package/src/core/ChessboardConfig.js +458 -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 +629 -0
- package/src/services/PieceService.js +312 -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} +8 -4
- 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/tests/unit/chessboard-config-animations.test.js +106 -0
- package/tests/unit/chessboard-robust.test.js +163 -0
- package/tests/unit/chessboard.test.js +183 -0
- package/chessboard.config.js +0 -147
- package/chessboard.js +0 -979
- package/chessboard.piece.js +0 -115
- 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
- /package/{.babelrc → config/.babelrc} +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* Animation styles */
|
|
2
|
+
@keyframes fadeIn {
|
|
3
|
+
from { opacity: 0; }
|
|
4
|
+
to { opacity: 1; }
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@keyframes fadeOut {
|
|
8
|
+
from { opacity: 1; }
|
|
9
|
+
to { opacity: 0; }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@keyframes slideIn {
|
|
13
|
+
from { transform: translateY(-10px); opacity: 0; }
|
|
14
|
+
to { transform: translateY(0); opacity: 1; }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes bounce {
|
|
18
|
+
0%, 20%, 53%, 80%, 100% {
|
|
19
|
+
transform: translate3d(0, 0, 0);
|
|
20
|
+
}
|
|
21
|
+
40%, 43% {
|
|
22
|
+
transform: translate3d(0, -5px, 0);
|
|
23
|
+
}
|
|
24
|
+
70% {
|
|
25
|
+
transform: translate3d(0, -3px, 0);
|
|
26
|
+
}
|
|
27
|
+
90% {
|
|
28
|
+
transform: translate3d(0, -1px, 0);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.fade-in {
|
|
33
|
+
animation: fadeIn var(--fade-time, 150ms) var(--fade-animation, ease);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.fade-out {
|
|
37
|
+
animation: fadeOut var(--fade-time, 150ms) var(--fade-animation, ease);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.slide-in {
|
|
41
|
+
animation: slideIn var(--fade-time, 150ms) var(--fade-animation, ease);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.bounce {
|
|
45
|
+
animation: bounce 1s ease;
|
|
46
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
:root {
|
|
2
2
|
--dimBoard: 600px;
|
|
3
3
|
--pieceRatio: 0.9;
|
|
4
|
+
--square-size: calc(var(--dimBoard) / 8);
|
|
4
5
|
|
|
5
6
|
--blackSquare: #b58863;
|
|
6
7
|
--whiteSquare: #f0d9b5;
|
|
@@ -19,11 +20,14 @@
|
|
|
19
20
|
grid-template: repeat(8, 1fr) / repeat(8, 1fr);
|
|
20
21
|
width: var(--dimBoard);
|
|
21
22
|
height: var(--dimBoard);
|
|
23
|
+
/* Enable hardware acceleration for better performance */
|
|
24
|
+
transform: translateZ(0);
|
|
25
|
+
will-change: auto;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
.square {
|
|
25
|
-
width:
|
|
26
|
-
height:
|
|
29
|
+
width: var(--square-size);
|
|
30
|
+
height: var(--square-size);
|
|
27
31
|
display: flex;
|
|
28
32
|
justify-content: center;
|
|
29
33
|
align-items: center;
|
|
@@ -32,8 +36,8 @@
|
|
|
32
36
|
.piece {
|
|
33
37
|
position: absolute;
|
|
34
38
|
z-index: 10;
|
|
35
|
-
width: calc(
|
|
36
|
-
height: calc(
|
|
39
|
+
width: calc(var(--square-size) * var(--pieceRatio));
|
|
40
|
+
height: calc(var(--square-size) * var(--pieceRatio));
|
|
37
41
|
|
|
38
42
|
/* No selection */
|
|
39
43
|
-webkit-user-select: none;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* Piece-specific styles */
|
|
2
|
+
.piece {
|
|
3
|
+
position: absolute;
|
|
4
|
+
cursor: pointer;
|
|
5
|
+
/* Solo transizioni specifiche, non "all" */
|
|
6
|
+
transition: opacity var(--fade-time, 150ms) var(--fade-animation, ease);
|
|
7
|
+
z-index: 10;
|
|
8
|
+
/* Hint al browser per ottimizzazioni */
|
|
9
|
+
will-change: auto;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.piece.dragging {
|
|
13
|
+
z-index: 100;
|
|
14
|
+
/* Disabilita completamente le transizioni durante il drag */
|
|
15
|
+
transition: none !important;
|
|
16
|
+
/* Hint per ottimizzazione durante drag */
|
|
17
|
+
will-change: left, top, transform;
|
|
18
|
+
/* Mantiene le dimensioni originali del pezzo durante il drag */
|
|
19
|
+
width: calc(var(--square-size) * var(--pieceRatio)) !important;
|
|
20
|
+
height: calc(var(--square-size) * var(--pieceRatio)) !important;
|
|
21
|
+
/* Assicura che il pezzo mantenga le proporzioni corrette */
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.piece.fading {
|
|
26
|
+
opacity: 0;
|
|
27
|
+
transition: opacity var(--fade-time, 150ms) var(--fade-animation, ease);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.piece.moving {
|
|
31
|
+
/* Solo transizione per transform, non position */
|
|
32
|
+
transition: transform var(--move-time, 200ms) var(--move-animation, ease);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Piece replacement during promotion - no transitions to avoid flickering */
|
|
36
|
+
.piece.replacing {
|
|
37
|
+
transition: none !important;
|
|
38
|
+
opacity: 1;
|
|
39
|
+
transform: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Piece transformation during promotion - smooth scaling animation */
|
|
43
|
+
.piece.transforming {
|
|
44
|
+
transition: none !important;
|
|
45
|
+
transform-origin: center center;
|
|
46
|
+
will-change: transform, opacity;
|
|
47
|
+
z-index: 50;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Subtle bounce effect after transformation */
|
|
51
|
+
.piece.transform-complete {
|
|
52
|
+
animation: transformBounce 0.4s ease-out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@keyframes transformBounce {
|
|
56
|
+
0% { transform: scale(1); }
|
|
57
|
+
50% { transform: scale(1.1); }
|
|
58
|
+
100% { transform: scale(1); }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Piece sizing */
|
|
62
|
+
.piece img {
|
|
63
|
+
width: 100%;
|
|
64
|
+
height: 100%;
|
|
65
|
+
object-fit: contain;
|
|
66
|
+
/* Previene conflitti di drag dell'immagine */
|
|
67
|
+
pointer-events: none;
|
|
68
|
+
/* Migliore rendering */
|
|
69
|
+
image-rendering: crisp-edges;
|
|
70
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animation utilities for Chessboard.js
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get the CSS transition duration in milliseconds
|
|
7
|
+
* @param {string|number} time - Time value ('fast', 'slow', or number in ms)
|
|
8
|
+
* @returns {number} Duration in milliseconds
|
|
9
|
+
*/
|
|
10
|
+
export function parseTime(time) {
|
|
11
|
+
if (typeof time === 'number') return time;
|
|
12
|
+
|
|
13
|
+
switch (time) {
|
|
14
|
+
case 'fast': return 150;
|
|
15
|
+
case 'slow': return 500;
|
|
16
|
+
default: return 200;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the CSS transition function
|
|
22
|
+
* @param {string} animation - Animation type ('ease', 'linear', etc.)
|
|
23
|
+
* @returns {string} CSS transition function
|
|
24
|
+
*/
|
|
25
|
+
export function parseAnimation(animation) {
|
|
26
|
+
const validAnimations = ['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear'];
|
|
27
|
+
return validAnimations.includes(animation) ? animation : 'ease';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a promise that resolves after animation completion
|
|
32
|
+
* @param {number} duration - Duration in milliseconds
|
|
33
|
+
* @returns {Promise} Promise that resolves after the duration
|
|
34
|
+
*/
|
|
35
|
+
export function animationPromise(duration) {
|
|
36
|
+
return new Promise(resolve => setTimeout(resolve, duration));
|
|
37
|
+
}
|
|
@@ -914,8 +914,8 @@ export class Chess {
|
|
|
914
914
|
return true;
|
|
915
915
|
}
|
|
916
916
|
else if (
|
|
917
|
-
|
|
918
|
-
|
|
917
|
+
// k vs. kn .... or .... k vs. kb
|
|
918
|
+
numPieces === 3 &&
|
|
919
919
|
(pieces[BISHOP] === 1 || pieces[KNIGHT] === 1)) {
|
|
920
920
|
return true;
|
|
921
921
|
}
|
|
@@ -1548,14 +1548,14 @@ export class Chess {
|
|
|
1548
1548
|
function toHex(s) {
|
|
1549
1549
|
return Array.from(s)
|
|
1550
1550
|
.map(function (c) {
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1551
|
+
/*
|
|
1552
|
+
* encodeURI doesn't transform most ASCII characters, so we handle
|
|
1553
|
+
* these ourselves
|
|
1554
|
+
*/
|
|
1555
|
+
return c.charCodeAt(0) < 128
|
|
1556
|
+
? c.charCodeAt(0).toString(16)
|
|
1557
|
+
: encodeURIComponent(c).replace(/%/g, '').toLowerCase();
|
|
1558
|
+
})
|
|
1559
1559
|
.join('');
|
|
1560
1560
|
}
|
|
1561
1561
|
function fromHex(s) {
|
|
@@ -1576,12 +1576,12 @@ export class Chess {
|
|
|
1576
1576
|
let ms = pgn
|
|
1577
1577
|
.replace(headerString, '')
|
|
1578
1578
|
.replace(
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1579
|
+
// encode comments so they don't get deleted below
|
|
1580
|
+
new RegExp(`({[^}]*})+?|;([^${mask(newlineChar)}]*)`, 'g'), function (_match, bracket, semicolon) {
|
|
1581
|
+
return bracket !== undefined
|
|
1582
|
+
? encodeComment(bracket)
|
|
1583
|
+
: ' ' + encodeComment(`{${semicolon.slice(1)}}`);
|
|
1584
|
+
})
|
|
1585
1585
|
.replace(new RegExp(mask(newlineChar), 'g'), ' ');
|
|
1586
1586
|
// delete recursive annotation variations
|
|
1587
1587
|
const ravRegex = /(\([^()]+\))+?/g;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordinate utilities for Chessboard.js
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert algebraic notation to array coordinates
|
|
7
|
+
* @param {string} square - Square in algebraic notation (e.g., 'a1', 'h8')
|
|
8
|
+
* @returns {Object} Object with row and col properties
|
|
9
|
+
*/
|
|
10
|
+
export function algebraicToCoords(square) {
|
|
11
|
+
const file = square.charCodeAt(0) - 97; // 'a' = 0, 'b' = 1, etc.
|
|
12
|
+
const rank = parseInt(square[1]) - 1; // '1' = 0, '2' = 1, etc.
|
|
13
|
+
|
|
14
|
+
return { row: 7 - rank, col: file };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Convert array coordinates to algebraic notation
|
|
19
|
+
* @param {number} row - Row index (0-7)
|
|
20
|
+
* @param {number} col - Column index (0-7)
|
|
21
|
+
* @returns {string} Square in algebraic notation
|
|
22
|
+
*/
|
|
23
|
+
export function coordsToAlgebraic(row, col) {
|
|
24
|
+
const file = String.fromCharCode(97 + col); // 0 = 'a', 1 = 'b', etc.
|
|
25
|
+
const rank = (8 - row).toString(); // 0 = '8', 1 = '7', etc.
|
|
26
|
+
|
|
27
|
+
return file + rank;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get the color of a square
|
|
32
|
+
* @param {string} square - Square in algebraic notation
|
|
33
|
+
* @returns {string} 'light' or 'dark'
|
|
34
|
+
*/
|
|
35
|
+
export function getSquareColor(square) {
|
|
36
|
+
const { row, col } = algebraicToCoords(square);
|
|
37
|
+
return (row + col) % 2 === 0 ? 'dark' : 'light';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Check if coordinates are valid
|
|
42
|
+
* @param {number} row - Row index
|
|
43
|
+
* @param {number} col - Column index
|
|
44
|
+
* @returns {boolean} True if coordinates are valid
|
|
45
|
+
*/
|
|
46
|
+
export function isValidCoords(row, col) {
|
|
47
|
+
return row >= 0 && row <= 7 && col >= 0 && col <= 7;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if algebraic notation is valid
|
|
52
|
+
* @param {string} square - Square in algebraic notation
|
|
53
|
+
* @returns {boolean} True if square notation is valid
|
|
54
|
+
*/
|
|
55
|
+
export function isValidSquare(square) {
|
|
56
|
+
if (typeof square !== 'string' || square.length !== 2) return false;
|
|
57
|
+
|
|
58
|
+
const file = square[0];
|
|
59
|
+
const rank = square[1];
|
|
60
|
+
|
|
61
|
+
return file >= 'a' && file <= 'h' && rank >= '1' && rank <= '8';
|
|
62
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-browser utilities for consistent drag & drop behavior
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Detect browser type and version
|
|
7
|
+
* @returns {Object} Browser information
|
|
8
|
+
*/
|
|
9
|
+
export function getBrowserInfo() {
|
|
10
|
+
const ua = navigator.userAgent;
|
|
11
|
+
const isChrome = ua.includes('Chrome') && !ua.includes('Edg');
|
|
12
|
+
const isFirefox = ua.includes('Firefox');
|
|
13
|
+
const isSafari = ua.includes('Safari') && !ua.includes('Chrome');
|
|
14
|
+
const isEdge = ua.includes('Edg');
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
isChrome,
|
|
18
|
+
isFirefox,
|
|
19
|
+
isSafari,
|
|
20
|
+
isEdge,
|
|
21
|
+
devicePixelRatio: window.devicePixelRatio || 1,
|
|
22
|
+
userAgent: ua
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get accurate mouse coordinates accounting for browser differences
|
|
28
|
+
* @param {MouseEvent} event - Mouse event
|
|
29
|
+
* @returns {Object} Normalized coordinates
|
|
30
|
+
*/
|
|
31
|
+
export function getNormalizedCoordinates(event) {
|
|
32
|
+
const browserInfo = getBrowserInfo();
|
|
33
|
+
|
|
34
|
+
// Base coordinates
|
|
35
|
+
let x = event.clientX;
|
|
36
|
+
let y = event.clientY;
|
|
37
|
+
|
|
38
|
+
// Add scroll offset for absolute positioning
|
|
39
|
+
x += window.scrollX || window.pageXOffset || 0;
|
|
40
|
+
y += window.scrollY || window.pageYOffset || 0;
|
|
41
|
+
|
|
42
|
+
// Chrome-specific adjustments if needed
|
|
43
|
+
if (browserInfo.isChrome) {
|
|
44
|
+
// Chrome sometimes has sub-pixel rendering differences
|
|
45
|
+
x = Math.round(x);
|
|
46
|
+
y = Math.round(y);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { x, y };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Set element position using the most compatible method
|
|
54
|
+
* @param {HTMLElement} element - Element to position
|
|
55
|
+
* @param {number} x - X coordinate
|
|
56
|
+
* @param {number} y - Y coordinate
|
|
57
|
+
*/
|
|
58
|
+
export function setElementPosition(element, x, y) {
|
|
59
|
+
// Ensure pixel-perfect positioning
|
|
60
|
+
element.style.left = `${Math.round(x)}px`;
|
|
61
|
+
element.style.top = `${Math.round(y)}px`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Calculate offset from center for drag positioning
|
|
66
|
+
* @param {HTMLElement} element - Element being dragged
|
|
67
|
+
* @param {number} mouseX - Mouse X coordinate
|
|
68
|
+
* @param {number} mouseY - Mouse Y coordinate
|
|
69
|
+
* @returns {Object} Position coordinates
|
|
70
|
+
*/
|
|
71
|
+
export function calculateDragPosition(element, mouseX, mouseY) {
|
|
72
|
+
const rect = element.getBoundingClientRect();
|
|
73
|
+
const halfWidth = rect.width / 2;
|
|
74
|
+
const halfHeight = rect.height / 2;
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
x: mouseX - halfWidth,
|
|
78
|
+
y: mouseY - halfHeight
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Enhanced mouse coordinate tracking for cross-browser compatibility
|
|
84
|
+
*/
|
|
85
|
+
export class MouseTracker {
|
|
86
|
+
constructor() {
|
|
87
|
+
this.lastKnownPosition = { x: 0, y: 0 };
|
|
88
|
+
this.browserInfo = getBrowserInfo();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Update position from mouse event
|
|
93
|
+
* @param {MouseEvent} event - Mouse event
|
|
94
|
+
* @returns {Object} Normalized position
|
|
95
|
+
*/
|
|
96
|
+
updatePosition(event) {
|
|
97
|
+
const coords = getNormalizedCoordinates(event);
|
|
98
|
+
this.lastKnownPosition = coords;
|
|
99
|
+
return coords;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get element position for dragging
|
|
104
|
+
* @param {HTMLElement} element - Element to position
|
|
105
|
+
* @param {MouseEvent} event - Mouse event
|
|
106
|
+
* @returns {Object} Position for the element
|
|
107
|
+
*/
|
|
108
|
+
getDragPosition(element, event) {
|
|
109
|
+
const mousePos = this.updatePosition(event);
|
|
110
|
+
return calculateDragPosition(element, mousePos.x, mousePos.y);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Browser-specific drag optimizations
|
|
116
|
+
*/
|
|
117
|
+
export const DragOptimizations = {
|
|
118
|
+
/**
|
|
119
|
+
* Apply browser-specific optimizations to an element
|
|
120
|
+
* @param {HTMLElement} element - Element to optimize
|
|
121
|
+
*/
|
|
122
|
+
enableForDrag(element) {
|
|
123
|
+
const browserInfo = getBrowserInfo();
|
|
124
|
+
|
|
125
|
+
// Base optimizations for all browsers
|
|
126
|
+
element.style.willChange = 'left, top';
|
|
127
|
+
element.style.pointerEvents = 'none'; // Prevent conflicts
|
|
128
|
+
|
|
129
|
+
// Chrome-specific optimizations
|
|
130
|
+
if (browserInfo.isChrome) {
|
|
131
|
+
element.style.transform = 'translateZ(0)'; // Force hardware acceleration
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Firefox-specific optimizations
|
|
135
|
+
if (browserInfo.isFirefox) {
|
|
136
|
+
element.style.backfaceVisibility = 'hidden';
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Clean up optimizations after drag
|
|
142
|
+
* @param {HTMLElement} element - Element to clean up
|
|
143
|
+
*/
|
|
144
|
+
cleanupAfterDrag(element) {
|
|
145
|
+
element.style.willChange = 'auto';
|
|
146
|
+
element.style.pointerEvents = '';
|
|
147
|
+
element.style.transform = '';
|
|
148
|
+
element.style.backfaceVisibility = '';
|
|
149
|
+
}
|
|
150
|
+
};
|