kokopu-react 1.8.0 → 1.9.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/dist/lib/ArrowMarkerIcon.js +1 -29
- package/dist/lib/Chessboard.js +152 -298
- package/dist/lib/ErrorBox.js +7 -24
- package/dist/lib/Movetext.js +74 -178
- package/dist/lib/SquareMarkerIcon.js +2 -10
- package/dist/lib/TextMarkerIcon.js +0 -11
- package/dist/lib/css/movetext.css +4 -0
- package/dist/lib/formatmove.js +2 -14
- package/dist/lib/i18n.js +1 -1
- package/dist/lib/impl/ArrowTip.js +2 -8
- package/dist/lib/impl/HtmlSanitizer.js +13 -46
- package/dist/lib/impl/Motion.js +107 -0
- package/dist/lib/impl/TextSymbol.js +2 -11
- package/dist/lib/impl/colorsets.js +0 -2
- package/dist/lib/impl/piecesets.js +0 -87
- package/dist/lib/impl/util.js +1 -11
- package/dist/lib/index.js +0 -10
- package/dist/lib/markers.js +18 -38
- package/graphic_test_src/05_chessboard_move.js +2 -2
- package/graphic_test_src/06a_chessboard_animated_move.js +36 -0
- package/graphic_test_src/06b_chessboard_animated_move.js +36 -0
- package/graphic_test_src/06c_chessboard_animated_move.js +36 -0
- package/graphic_test_src/{06_chessboard_theme.js → 07_chessboard_theme.js} +0 -0
- package/graphic_test_src/{07_chessboard_click_squares.js → 08_chessboard_click_squares.js} +0 -0
- package/graphic_test_src/{08_chessboard_move_pieces.js → 09_chessboard_move_pieces.js} +0 -0
- package/graphic_test_src/{09_chessboard_edit_arrows.js → 10_chessboard_edit_arrows.js} +0 -0
- package/graphic_test_src/{10_chessboard_play_moves.js → 11_chessboard_play_moves.js} +0 -0
- package/graphic_test_src/{11_chessboard_play_promotions.js → 12_chessboard_play_promotions.js} +0 -0
- package/graphic_test_src/{12_movetext_simple.js → 13_movetext_simple.js} +0 -0
- package/graphic_test_src/{13_movetext_error.js → 14_movetext_error.js} +0 -0
- package/graphic_test_src/{14_movetext_html.js → 15_movetext_html.js} +0 -0
- package/graphic_test_src/{15_movetext_options.js → 16_movetext_options.js} +0 -0
- package/graphic_test_src/{16_movetext_interaction.js → 17_movetext_interaction.js} +0 -0
- package/package.json +19 -21
- package/scripts/docker-compose.yml +1 -1
- package/src/Chessboard.js +24 -20
- package/src/css/movetext.css +4 -0
- package/src/impl/ArrowTip.js +2 -2
- package/src/impl/Motion.js +99 -0
- package/test/4_chessboard_graphic.js +4 -1
- package/test/5_chessboard_interaction.js +5 -5
- package/test/6_chessboard_play_moves.js +4 -4
- package/test/7_movetext_graphic.js +4 -4
- package/test/8_movetext_interaction.js +2 -2
- package/test/common/graphic.js +6 -0
- package/test/references/06a_chessboard_animated_move/0.png +0 -0
- package/test/references/06a_chessboard_animated_move/1.png +0 -0
- package/test/references/06a_chessboard_animated_move/2.png +0 -0
- package/test/references/06a_chessboard_animated_move/3.png +0 -0
- package/test/references/06a_chessboard_animated_move/4.png +0 -0
- package/test/references/06a_chessboard_animated_move/5.png +0 -0
- package/test/references/06b_chessboard_animated_move/0.png +0 -0
- package/test/references/06b_chessboard_animated_move/1.png +0 -0
- package/test/references/06b_chessboard_animated_move/2.png +0 -0
- package/test/references/06b_chessboard_animated_move/3.png +0 -0
- package/test/references/06b_chessboard_animated_move/4.png +0 -0
- package/test/references/06b_chessboard_animated_move/5.png +0 -0
- package/test/references/06c_chessboard_animated_move/0.png +0 -0
- package/test/references/06c_chessboard_animated_move/1.png +0 -0
- package/test/references/06c_chessboard_animated_move/2.png +0 -0
- package/test/references/06c_chessboard_animated_move/3.png +0 -0
- package/test/references/06c_chessboard_animated_move/4.png +0 -0
- package/test/references/06c_chessboard_animated_move/5.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/0.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/1.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/2.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/3.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/4.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/5.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/6.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/7.png +0 -0
- package/test/references/{06_chessboard_theme → 07_chessboard_theme}/8.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/after_move.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/empty_square.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/null_vector.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/out_of_board.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_arrow_marker.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_empty.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_non_empty_1.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_non_empty_2.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_square_marker.png +0 -0
- package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_text_marker.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/base_1.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/base_2.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/edit_color_not_set.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/null_vector.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/out_of_board.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/over_arrow_marker.png +0 -0
- package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/over_square_marker.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/castling_move.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/chess960_ambiguous_king_move.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/chess960_castling_move_1.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/chess960_castling_move_2.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/chess960_non_kxr_castling.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/illegal_move.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/illegal_position.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/null_vector.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/out_of_board.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/regular_move_1.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/regular_move_2.png +0 -0
- package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/wrong_color.png +0 -0
- package/test/references/{11_chessboard_play_promotions → 12_chessboard_play_promotions}/antichess_promotion.png +0 -0
- package/test/references/{11_chessboard_play_promotions → 12_chessboard_play_promotions}/cancel_promotion.png +0 -0
- package/test/references/{11_chessboard_play_promotions → 12_chessboard_play_promotions}/regular_promotion_1.png +0 -0
- package/test/references/{11_chessboard_play_promotions → 12_chessboard_play_promotions}/regular_promotion_2.png +0 -0
- package/test/references/{12_movetext_simple → 13_movetext_simple}/0.png +0 -0
- package/test/references/{12_movetext_simple → 13_movetext_simple}/1.png +0 -0
- package/test/references/{12_movetext_simple → 13_movetext_simple}/2.png +0 -0
- package/test/references/{12_movetext_simple → 13_movetext_simple}/3.png +0 -0
- package/test/references/{13_movetext_error → 14_movetext_error}/0.png +0 -0
- package/test/references/{13_movetext_error → 14_movetext_error}/1.png +0 -0
- package/test/references/{13_movetext_error → 14_movetext_error}/2.png +0 -0
- package/test/references/{13_movetext_error → 14_movetext_error}/3.png +0 -0
- package/test/references/{13_movetext_error → 14_movetext_error}/4.png +0 -0
- package/test/references/{14_movetext_html → 15_movetext_html}/0.png +0 -0
- package/test/references/{14_movetext_html → 15_movetext_html}/1.png +0 -0
- package/test/references/{14_movetext_html → 15_movetext_html}/2.png +0 -0
- package/test/references/{15_movetext_options → 16_movetext_options}/0.png +0 -0
- package/test/references/{15_movetext_options → 16_movetext_options}/1.png +0 -0
- package/test/references/{15_movetext_options → 16_movetext_options}/2.png +0 -0
- package/test/references/{15_movetext_options → 16_movetext_options}/3.png +0 -0
- package/test/references/{16_movetext_interaction → 17_movetext_interaction}/0.png +0 -0
- package/test/references/{16_movetext_interaction → 17_movetext_interaction}/1.png +0 -0
- package/test/references/{16_movetext_interaction → 17_movetext_interaction}/2.png +0 -0
- package/CHANGELOG.md +0 -141
- package/graphics/chess_sprites/cburnett/bb.svg +0 -45
- package/graphics/chess_sprites/cburnett/bk.svg +0 -47
- package/graphics/chess_sprites/cburnett/bn.svg +0 -37
- package/graphics/chess_sprites/cburnett/bp.svg +0 -19
- package/graphics/chess_sprites/cburnett/bq.svg +0 -58
- package/graphics/chess_sprites/cburnett/br.svg +0 -60
- package/graphics/chess_sprites/cburnett/bx.svg +0 -56
- package/graphics/chess_sprites/cburnett/wb.svg +0 -48
- package/graphics/chess_sprites/cburnett/wk.svg +0 -26
- package/graphics/chess_sprites/cburnett/wn.svg +0 -37
- package/graphics/chess_sprites/cburnett/wp.svg +0 -19
- package/graphics/chess_sprites/cburnett/wq.svg +0 -60
- package/graphics/chess_sprites/cburnett/wr.svg +0 -44
- package/graphics/chess_sprites/cburnett/wx.svg +0 -56
- package/graphics/chess_sprites/generate_sprites.sh +0 -135
- package/graphics/chess_sprites/mmonge/celtic-bx.svg +0 -112
- package/graphics/chess_sprites/mmonge/celtic-wx.svg +0 -111
- package/graphics/chess_sprites/mmonge/celtic.svg +0 -1576
- package/graphics/chess_sprites/mmonge/eyes-spatial-bx.svg +0 -101
- package/graphics/chess_sprites/mmonge/eyes-spatial-wx.svg +0 -100
- package/graphics/chess_sprites/mmonge/eyes.svg +0 -2538
- package/graphics/chess_sprites/mmonge/fantasy-bx.svg +0 -112
- package/graphics/chess_sprites/mmonge/fantasy-wx.svg +0 -111
- package/graphics/chess_sprites/mmonge/fantasy.svg +0 -5497
- package/graphics/chess_sprites/mmonge/fantasy_alt.svg +0 -3742
- package/graphics/chess_sprites/mmonge/freak.svg +0 -3479
- package/graphics/chess_sprites/mmonge/prmi.svg +0 -6776
- package/graphics/chess_sprites/mmonge/skulls-bx.svg +0 -124
- package/graphics/chess_sprites/mmonge/skulls-wx.svg +0 -111
- package/graphics/chess_sprites/mmonge/skulls.svg +0 -12978
- package/graphics/chess_sprites/mmonge/spatial.svg +0 -1223
- package/graphics/logo-small.svg +0 -14
- package/graphics/logo.svg +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kokopu-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "A React-based library to create and display chessboard and chess-related components.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chess",
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"dist/lib",
|
|
20
20
|
"doc_src",
|
|
21
21
|
"graphic_test_src",
|
|
22
|
-
"graphics",
|
|
23
22
|
"scripts/clean-graphic-output.js",
|
|
24
23
|
"scripts/docker-compose.yml",
|
|
25
24
|
"scripts/test-graphic.webpack.config.js",
|
|
@@ -37,39 +36,38 @@
|
|
|
37
36
|
"dependencies": {
|
|
38
37
|
"htmlparser2": "^8.0.1",
|
|
39
38
|
"prop-types": "^15.8.1",
|
|
40
|
-
"react-draggable": "^4.4.5"
|
|
41
|
-
"react-motion": "^0.5.2"
|
|
39
|
+
"react-draggable": "^4.4.5"
|
|
42
40
|
},
|
|
43
41
|
"devDependencies": {
|
|
44
|
-
"@babel/cli": "^7.
|
|
45
|
-
"@babel/core": "^7.
|
|
46
|
-
"@babel/preset-env": "^7.
|
|
42
|
+
"@babel/cli": "^7.19.3",
|
|
43
|
+
"@babel/core": "^7.20.2",
|
|
44
|
+
"@babel/preset-env": "^7.20.2",
|
|
47
45
|
"@babel/preset-react": "^7.18.6",
|
|
48
|
-
"@emotion/react": "^11.10.
|
|
49
|
-
"@emotion/styled": "^11.10.
|
|
50
|
-
"@mui/material": "^5.10.
|
|
51
|
-
"babel-loader": "^
|
|
46
|
+
"@emotion/react": "^11.10.5",
|
|
47
|
+
"@emotion/styled": "^11.10.5",
|
|
48
|
+
"@mui/material": "^5.10.14",
|
|
49
|
+
"babel-loader": "^9.1.0",
|
|
52
50
|
"babel-plugin-istanbul": "^6.1.1",
|
|
53
51
|
"copy-webpack-plugin": "^11.0.0",
|
|
54
52
|
"coveralls": "^3.1.1",
|
|
55
|
-
"css-loader": "^6.7.
|
|
56
|
-
"eslint": "^8.
|
|
57
|
-
"eslint-plugin-react": "^7.31.
|
|
53
|
+
"css-loader": "^6.7.2",
|
|
54
|
+
"eslint": "^8.27.0",
|
|
55
|
+
"eslint-plugin-react": "^7.31.10",
|
|
58
56
|
"html-webpack-plugin": "^5.5.0",
|
|
59
57
|
"img-diff-js": "^0.5.2",
|
|
60
|
-
"kokopu": "^3.
|
|
61
|
-
"mocha": "^10.
|
|
58
|
+
"kokopu": "^3.3.0",
|
|
59
|
+
"mocha": "^10.1.0",
|
|
62
60
|
"null-loader": "^4.0.1",
|
|
63
61
|
"nyc": "^15.1.0",
|
|
64
62
|
"react": "^18.2.0",
|
|
65
63
|
"react-dom": "^18.2.0",
|
|
66
|
-
"react-styleguidist": "^
|
|
67
|
-
"selenium-webdriver": "^4.
|
|
68
|
-
"ssh2-sftp-client": "^9.0.
|
|
64
|
+
"react-styleguidist": "^13.0.0",
|
|
65
|
+
"selenium-webdriver": "^4.6.1",
|
|
66
|
+
"ssh2-sftp-client": "^9.0.4",
|
|
69
67
|
"style-loader": "^3.3.1",
|
|
70
68
|
"unit.js": "^2.1.1",
|
|
71
|
-
"webpack": "^5.
|
|
72
|
-
"webpack-cli": "^
|
|
69
|
+
"webpack": "^5.75.0",
|
|
70
|
+
"webpack-cli": "^5.0.0"
|
|
73
71
|
},
|
|
74
72
|
"scripts": {
|
|
75
73
|
"lint": "eslint doc_src graphic_test_src src test",
|
package/src/Chessboard.js
CHANGED
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
import PropTypes from 'prop-types';
|
|
24
24
|
import React from 'react';
|
|
25
25
|
import Draggable from 'react-draggable';
|
|
26
|
-
import { Motion, spring } from 'react-motion';
|
|
27
26
|
import { exception, MoveDescriptor, Position, coordinatesToSquare, forEachSquare, oppositeColor, squareColor, squareToCoordinates } from 'kokopu';
|
|
28
27
|
|
|
29
28
|
import colorsets from './impl/colorsets';
|
|
30
29
|
import piecesets from './impl/piecesets';
|
|
31
30
|
import ArrowTip from './impl/ArrowTip';
|
|
31
|
+
import Motion from './impl/Motion';
|
|
32
32
|
import TextSymbol from './impl/TextSymbol';
|
|
33
33
|
import ErrorBox from './ErrorBox';
|
|
34
34
|
import i18n from './i18n';
|
|
@@ -45,7 +45,7 @@ const HOVER_MARKER_THICKNESS_FACTOR = 0.1;
|
|
|
45
45
|
const STROKE_THICKNESS_FACTOR = 0.15;
|
|
46
46
|
const ARROW_TIP_OFFSET_FACTOR = 0.3;
|
|
47
47
|
|
|
48
|
-
const
|
|
48
|
+
const MOTION_DURATION = 150;
|
|
49
49
|
|
|
50
50
|
const RANK_LABELS = '12345678';
|
|
51
51
|
const FILE_LABELS = 'abcdefgh';
|
|
@@ -67,15 +67,18 @@ export default class Chessboard extends React.Component {
|
|
|
67
67
|
windowWidth: window.innerWidth,
|
|
68
68
|
};
|
|
69
69
|
this.arrowTipIdSuffix = generateRandomId();
|
|
70
|
-
this.windowResizeListener = () => this.handleWindowResize();
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
componentDidMount() {
|
|
73
|
+
this.windowResizeListener = () => this.handleWindowResize();
|
|
74
74
|
window.addEventListener('resize', this.windowResizeListener);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
componentWillUnmount() {
|
|
78
|
-
|
|
78
|
+
if (this.windowResizeListener) {
|
|
79
|
+
window.removeEventListener('resize', this.windowResizeListener);
|
|
80
|
+
this.windowResizeListener = null;
|
|
81
|
+
}
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
render() {
|
|
@@ -138,10 +141,11 @@ export default class Chessboard extends React.Component {
|
|
|
138
141
|
|
|
139
142
|
renderBoardContent(position, positionBefore, move, squareSize, colorset, pieceset) {
|
|
140
143
|
if (move && this.props.animated) {
|
|
144
|
+
let key = positionBefore.variant() + '|' + positionBefore.fen() + '|' + move.toString();
|
|
141
145
|
return (
|
|
142
|
-
<Motion key={
|
|
143
|
-
{
|
|
144
|
-
: this.renderBoardContentAnimated(positionBefore, move,
|
|
146
|
+
<Motion key={key} duration={MOTION_DURATION}>
|
|
147
|
+
{motionCursor => (motionCursor === 1 ? this.renderBoardContentStill(position, move, squareSize, colorset, pieceset)
|
|
148
|
+
: this.renderBoardContentAnimated(positionBefore, move, motionCursor, squareSize, colorset, pieceset))}
|
|
145
149
|
</Motion>
|
|
146
150
|
);
|
|
147
151
|
}
|
|
@@ -153,13 +157,13 @@ export default class Chessboard extends React.Component {
|
|
|
153
157
|
/**
|
|
154
158
|
* Render the board content during the animation.
|
|
155
159
|
*/
|
|
156
|
-
renderBoardContentAnimated(positionBefore, move,
|
|
160
|
+
renderBoardContentAnimated(positionBefore, move, motionCursor, squareSize, colorset, pieceset) {
|
|
157
161
|
let pieces = [];
|
|
158
|
-
forEachSquare(sq => pieces.push(this.renderPieceAnimated(positionBefore, move,
|
|
162
|
+
forEachSquare(sq => pieces.push(this.renderPieceAnimated(positionBefore, move, motionCursor, squareSize, pieceset, sq)));
|
|
159
163
|
return (
|
|
160
164
|
<>
|
|
161
165
|
{pieces}
|
|
162
|
-
{this.renderMoveArrow(move,
|
|
166
|
+
{this.renderMoveArrow(move, motionCursor, squareSize, colorset)}
|
|
163
167
|
{this.renderTurnFlag(oppositeColor(positionBefore.turn()), squareSize, pieceset)}
|
|
164
168
|
</>
|
|
165
169
|
);
|
|
@@ -226,7 +230,7 @@ export default class Chessboard extends React.Component {
|
|
|
226
230
|
return <image key={'piece-' + sq} x={x} y={y} width={squareSize} height={squareSize} href={pieceset[cp]} />;
|
|
227
231
|
}
|
|
228
232
|
|
|
229
|
-
renderPieceAnimated(positionBefore, move,
|
|
233
|
+
renderPieceAnimated(positionBefore, move, motionCursor, squareSize, pieceset, sq) {
|
|
230
234
|
let cp = positionBefore.square(sq);
|
|
231
235
|
if (cp === '-' || move.to() === sq || (move.isEnPassant() && move.enPassantSquare() === sq)) {
|
|
232
236
|
return undefined;
|
|
@@ -234,16 +238,16 @@ export default class Chessboard extends React.Component {
|
|
|
234
238
|
let { x, y } = this.getSquareCoordinates(squareSize, sq);
|
|
235
239
|
if (sq === move.from()) {
|
|
236
240
|
let { x: xTo, y: yTo } = this.getSquareCoordinates(squareSize, move.to());
|
|
237
|
-
x = xTo *
|
|
238
|
-
y = yTo *
|
|
239
|
-
if (move.isPromotion() &&
|
|
241
|
+
x = xTo * motionCursor + x * (1 - motionCursor);
|
|
242
|
+
y = yTo * motionCursor + y * (1 - motionCursor);
|
|
243
|
+
if (move.isPromotion() && motionCursor > 0.8) {
|
|
240
244
|
cp = move.coloredPromotion();
|
|
241
245
|
}
|
|
242
246
|
}
|
|
243
247
|
else if (move.isCastling() && sq === move.rookFrom()) {
|
|
244
248
|
let { x: xTo, y: yTo } = this.getSquareCoordinates(squareSize, move.rookTo());
|
|
245
|
-
x = xTo *
|
|
246
|
-
y = yTo *
|
|
249
|
+
x = xTo * motionCursor + x * (1 - motionCursor);
|
|
250
|
+
y = yTo * motionCursor + y * (1 - motionCursor);
|
|
247
251
|
}
|
|
248
252
|
return <image key={'piece-' + sq} x={x} y={y} width={squareSize} height={squareSize} href={pieceset[cp]} />;
|
|
249
253
|
}
|
|
@@ -384,8 +388,8 @@ export default class Chessboard extends React.Component {
|
|
|
384
388
|
return result;
|
|
385
389
|
}
|
|
386
390
|
|
|
387
|
-
renderMoveArrow(move,
|
|
388
|
-
if (!move ||
|
|
391
|
+
renderMoveArrow(move, motionCursor, squareSize, colorset) {
|
|
392
|
+
if (!move || motionCursor < 0.1 || !this.props.moveArrowVisible || move.from() === move.to()) {
|
|
389
393
|
return undefined;
|
|
390
394
|
}
|
|
391
395
|
let { x: xFrom, y: yFrom } = this.getSquareCoordinates(squareSize, move.from());
|
|
@@ -396,8 +400,8 @@ export default class Chessboard extends React.Component {
|
|
|
396
400
|
yTo += squareSize / 2;
|
|
397
401
|
xTo += Math.sign(xFrom - xTo) * ARROW_TIP_OFFSET_FACTOR * squareSize;
|
|
398
402
|
yTo += Math.sign(yFrom - yTo) * ARROW_TIP_OFFSET_FACTOR * squareSize;
|
|
399
|
-
let x = xTo *
|
|
400
|
-
let y = yTo *
|
|
403
|
+
let x = xTo * motionCursor + xFrom * (1 - motionCursor);
|
|
404
|
+
let y = yTo * motionCursor + yFrom * (1 - motionCursor);
|
|
401
405
|
let color = this.props.moveArrowColor;
|
|
402
406
|
return (
|
|
403
407
|
<line
|
package/src/css/movetext.css
CHANGED
package/src/impl/ArrowTip.js
CHANGED
|
@@ -29,8 +29,8 @@ import React from 'react';
|
|
|
29
29
|
*/
|
|
30
30
|
export default function ArrowTip(props) {
|
|
31
31
|
return (
|
|
32
|
-
<marker id={props.id} markerWidth={4} markerHeight={4} refX={2.5} refY={2} orient="auto"
|
|
33
|
-
<path d="M 4,2 L 0,4 L 1,2 L 0,0 Z" />
|
|
32
|
+
<marker id={props.id} markerWidth={4} markerHeight={4} refX={2.5} refY={2} orient="auto">
|
|
33
|
+
<path fill={props.color} d="M 4,2 L 0,4 L 1,2 L 0,0 Z" />
|
|
34
34
|
</marker>
|
|
35
35
|
);
|
|
36
36
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
* *
|
|
3
|
+
* This file is part of Kokopu-React, a JavaScript chess library. *
|
|
4
|
+
* Copyright (C) 2021-2022 Yoann Le Montagner <yo35 -at- melix.net> *
|
|
5
|
+
* *
|
|
6
|
+
* This program is free software: you can redistribute it and/or *
|
|
7
|
+
* modify it under the terms of the GNU Lesser General Public License *
|
|
8
|
+
* as published by the Free Software Foundation, either version 3 of *
|
|
9
|
+
* the License, or (at your option) any later version. *
|
|
10
|
+
* *
|
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
14
|
+
* GNU Lesser General Public License for more details. *
|
|
15
|
+
* *
|
|
16
|
+
* You should have received a copy of the GNU Lesser General *
|
|
17
|
+
* Public License along with this program. If not, see *
|
|
18
|
+
* <http://www.gnu.org/licenses/>. *
|
|
19
|
+
* *
|
|
20
|
+
******************************************************************************/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
import PropTypes from 'prop-types';
|
|
24
|
+
import React from 'react';
|
|
25
|
+
|
|
26
|
+
const DEBUG_KEY = '__kokopu_debug_freeze_motion';
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Wrap some animated content.
|
|
31
|
+
*/
|
|
32
|
+
export default class Motion extends React.Component {
|
|
33
|
+
|
|
34
|
+
constructor(props) {
|
|
35
|
+
super(props);
|
|
36
|
+
this.state = {
|
|
37
|
+
cursor: 0,
|
|
38
|
+
};
|
|
39
|
+
this.animationFrameId = null;
|
|
40
|
+
this.cursorStop = 1;
|
|
41
|
+
|
|
42
|
+
// WARNING: this hack exists only for testing purposes. DO NOT USE IT IN PRODUCTION.
|
|
43
|
+
if (typeof window[DEBUG_KEY] === 'number' && window[DEBUG_KEY] >= 0 && window[DEBUG_KEY] <= 1) {
|
|
44
|
+
this.cursorStop = window[DEBUG_KEY];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
componentDidMount() {
|
|
49
|
+
this.animationFrameId = window.requestAnimationFrame(ts => this.handleAnimationStep(ts));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
componentWillUnmount() {
|
|
53
|
+
if (this.animationFrameId !== null) {
|
|
54
|
+
window.cancelAnimationFrame(this.animationFrameId);
|
|
55
|
+
this.animationFrameId = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
handleAnimationStep(timestamp) {
|
|
60
|
+
if (this.initialTimestamp === undefined) {
|
|
61
|
+
this.initialTimestamp = timestamp;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Compute the animation cursor and update the state.
|
|
65
|
+
let cursor = (timestamp - this.initialTimestamp) / this.props.duration;
|
|
66
|
+
if (cursor < 0) {
|
|
67
|
+
cursor = 0;
|
|
68
|
+
}
|
|
69
|
+
else if (cursor > this.cursorStop) {
|
|
70
|
+
cursor = this.cursorStop;
|
|
71
|
+
}
|
|
72
|
+
this.setState({ cursor: cursor });
|
|
73
|
+
|
|
74
|
+
// Schedule the next animation frame if necessary.
|
|
75
|
+
if (cursor === this.cursorStop) {
|
|
76
|
+
this.animationFrameId = null;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this.animationFrameId = window.requestAnimationFrame(ts => this.handleAnimationStep(ts));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
render() {
|
|
84
|
+
return this.props.children(this.state.cursor);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
Motion.propTypes = {
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Duration of the animation. Must be > 0.
|
|
92
|
+
*/
|
|
93
|
+
duration: PropTypes.number.isRequired,
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Factory for the content being animated. The animation cursor is guaranteed to be valued between 0 and 1 inclusive.
|
|
97
|
+
*/
|
|
98
|
+
children: PropTypes.func.isRequired,
|
|
99
|
+
};
|
|
@@ -41,6 +41,9 @@ describe('Chessboard graphic', function() {
|
|
|
41
41
|
'overlap', 'overlap & flip' ]);
|
|
42
42
|
itChecksScreenshots(browserContext, '05_chessboard_move', [ 'default', 'no move arrow', 'invalid', 'with forced move arrow & flip', 'capture', 'castling move',
|
|
43
43
|
'en-passant', 'promotion', 'wrong type' ]);
|
|
44
|
-
itChecksScreenshots(browserContext, '
|
|
44
|
+
itChecksScreenshots(browserContext, '06a_chessboard_animated_move', [ 'move 1', 'move 2', 'capture', 'castling move', 'en-pssant', 'promotion' ]);
|
|
45
|
+
itChecksScreenshots(browserContext, '06b_chessboard_animated_move', [ 'move 1', 'move 2', 'capture', 'castling move', 'en-pssant', 'promotion' ]);
|
|
46
|
+
itChecksScreenshots(browserContext, '06c_chessboard_animated_move', [ 'move 1', 'move 2', 'capture', 'castling move', 'en-pssant', 'promotion' ]);
|
|
47
|
+
itChecksScreenshots(browserContext, '07_chessboard_theme', [ 'default', 'large', 'small', 'custom 1', 'custom 2', 'custom 3',
|
|
45
48
|
'custom 4', 'custom 5', 'custom 6' ]);
|
|
46
49
|
});
|
|
@@ -36,7 +36,7 @@ describe('Chessboard interaction', function() {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
function itCheckClickSquare(itemIndex, label, targets) {
|
|
39
|
-
itCustom(browserContext, '
|
|
39
|
+
itCustom(browserContext, '08_chessboard_click_squares', itemIndex, label, async function(element) {
|
|
40
40
|
let actions = browserContext.driver.actions({ async: true });
|
|
41
41
|
let area = await element.getRect();
|
|
42
42
|
for (let i = 0; i < targets.length; ++i) {
|
|
@@ -63,7 +63,7 @@ describe('Chessboard interaction', function() {
|
|
|
63
63
|
]);
|
|
64
64
|
|
|
65
65
|
function itCheckMovePiece(itemIndex, label, xFrom, yFrom, xTo, yTo, imageBaseName, expectedText) {
|
|
66
|
-
itCustom(browserContext, '
|
|
66
|
+
itCustom(browserContext, '09_chessboard_move_pieces', itemIndex, label, async function(element) {
|
|
67
67
|
let actions = browserContext.driver.actions({ async: true });
|
|
68
68
|
let area = await element.getRect();
|
|
69
69
|
await actions.move({ x: area.x + xFrom, y: area.y + yFrom }).press().move({ x: area.x + xTo, y: area.y + yTo }).perform();
|
|
@@ -83,7 +83,7 @@ describe('Chessboard interaction', function() {
|
|
|
83
83
|
itCheckMovePiece(2, 'after move', 225, 225, 75, 260, 'after_move', 'piece moved: e4 -> b3');
|
|
84
84
|
|
|
85
85
|
function itCheckNonMovePiece(itemIndex, label, xFrom, yFrom, xTo, yTo, imageBaseName) {
|
|
86
|
-
itCustom(browserContext, '
|
|
86
|
+
itCustom(browserContext, '09_chessboard_move_pieces', itemIndex, label, async function(element) {
|
|
87
87
|
await setSandbox(browserContext, imageBaseName); // can be any value as long as it is unique among other test-cases
|
|
88
88
|
let actions = browserContext.driver.actions({ async: true });
|
|
89
89
|
let area = await element.getRect();
|
|
@@ -100,7 +100,7 @@ describe('Chessboard interaction', function() {
|
|
|
100
100
|
itCheckNonMovePiece(0, 'out of board', 175, 25, 500, 210, 'out_of_board');
|
|
101
101
|
|
|
102
102
|
function itCheckEditArrow(itemIndex, label, xFrom, yFrom, xTo, yTo, imageBaseName, expectedText) {
|
|
103
|
-
itCustom(browserContext, '
|
|
103
|
+
itCustom(browserContext, '10_chessboard_edit_arrows', itemIndex, label, async function(element) {
|
|
104
104
|
let actions = browserContext.driver.actions({ async: true });
|
|
105
105
|
let area = await element.getRect();
|
|
106
106
|
await actions.move({ x: area.x + xFrom, y: area.y + yFrom }).press().move({ x: area.x + xTo, y: area.y + yTo }).perform();
|
|
@@ -117,7 +117,7 @@ describe('Chessboard interaction', function() {
|
|
|
117
117
|
itCheckEditArrow(1, 'over arrow marker', 40, 110, 125, 290, 'over_arrow_marker', 'arrow edited: h3 -> f6');
|
|
118
118
|
|
|
119
119
|
function itCheckNonEditArrow(itemIndex, label, xFrom, yFrom, xTo, yTo, imageBaseName) {
|
|
120
|
-
itCustom(browserContext, '
|
|
120
|
+
itCustom(browserContext, '10_chessboard_edit_arrows', itemIndex, label, async function(element) {
|
|
121
121
|
await setSandbox(browserContext, imageBaseName); // can be any value as long as it is unique among other test-cases
|
|
122
122
|
let actions = browserContext.driver.actions({ async: true });
|
|
123
123
|
let area = await element.getRect();
|
|
@@ -36,7 +36,7 @@ describe('Chessboard play moves', function() {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
function itCheckPlayMove(itemIndex, label, xFrom, yFrom, xTo, yTo, imageBaseName, expectedText) {
|
|
39
|
-
itCustom(browserContext, '
|
|
39
|
+
itCustom(browserContext, '11_chessboard_play_moves', itemIndex, label, async function(element) {
|
|
40
40
|
let actions = browserContext.driver.actions({ async: true });
|
|
41
41
|
let area = await element.getRect();
|
|
42
42
|
await actions.move({ x: area.x + xFrom, y: area.y + yFrom }).press().move({ x: area.x + xTo, y: area.y + yTo }).perform();
|
|
@@ -55,7 +55,7 @@ describe('Chessboard play moves', function() {
|
|
|
55
55
|
itCheckPlayMove(3, 'chess960 ambiguous king move', 275, 375, 320, 375, 'chess960_ambiguous_king_move', 'move played: Kg1');
|
|
56
56
|
|
|
57
57
|
function itCheckNonPlayMove(itemIndex, label, xFrom, yFrom, xTo, yTo, imageBaseName) {
|
|
58
|
-
itCustom(browserContext, '
|
|
58
|
+
itCustom(browserContext, '11_chessboard_play_moves', itemIndex, label, async function(element) {
|
|
59
59
|
await setSandbox(browserContext, imageBaseName); // can be any value as long as it is unique among other test-cases
|
|
60
60
|
let actions = browserContext.driver.actions({ async: true });
|
|
61
61
|
let area = await element.getRect();
|
|
@@ -75,7 +75,7 @@ describe('Chessboard play moves', function() {
|
|
|
75
75
|
itCheckNonPlayMove(3, 'chess960 non-KxR castling', 275, 375, 130, 375, 'chess960_non_kxr_castling');
|
|
76
76
|
|
|
77
77
|
function itCheckPlayPromotion(itemIndex, label, xFrom, yFrom, xTo, yTo, xPromo, yPromo, imageBaseName, expectedText) {
|
|
78
|
-
itCustom(browserContext, '
|
|
78
|
+
itCustom(browserContext, '12_chessboard_play_promotions', itemIndex, label, async function(element) {
|
|
79
79
|
let actions = browserContext.driver.actions({ async: true });
|
|
80
80
|
let area = await element.getRect();
|
|
81
81
|
await actions.move({ x: area.x + xFrom, y: area.y + yFrom }).press().move({ x: area.x + xTo, y: area.y + yTo }).release().perform();
|
|
@@ -91,7 +91,7 @@ describe('Chessboard play moves', function() {
|
|
|
91
91
|
itCheckPlayPromotion(2, 'antichess promotion', 325, 325, 325, 375, 325, 175, 'antichess_promotion', 'promotion move played: b8=K');
|
|
92
92
|
|
|
93
93
|
function itCheckNonPlayPromotion(itemIndex, label, xFrom, yFrom, xTo, yTo, xPromo, yPromo, imageBaseName) {
|
|
94
|
-
itCustom(browserContext, '
|
|
94
|
+
itCustom(browserContext, '12_chessboard_play_promotions', itemIndex, label, async function(element) {
|
|
95
95
|
await setSandbox(browserContext, imageBaseName); // can be any value as long as it is unique among other test-cases
|
|
96
96
|
let actions = browserContext.driver.actions({ async: true });
|
|
97
97
|
let area = await element.getRect();
|
|
@@ -35,9 +35,9 @@ describe('Movetext graphic', function() {
|
|
|
35
35
|
await closeBrowser(browserContext);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
itChecksScreenshots(browserContext, '
|
|
39
|
-
itChecksScreenshots(browserContext, '
|
|
40
|
-
itChecksScreenshots(browserContext, '
|
|
41
|
-
itChecksScreenshots(browserContext, '
|
|
38
|
+
itChecksScreenshots(browserContext, '13_movetext_simple', [ 'game-0', 'game-1', 'game-2', 'game-3' ]);
|
|
39
|
+
itChecksScreenshots(browserContext, '14_movetext_error', [ 'wrong-game-index-1', 'wrong-game-index-2', 'pgn-parsing-error-1', 'pgn-parsing-error-2', 'wrong type' ]);
|
|
40
|
+
itChecksScreenshots(browserContext, '15_movetext_html', [ 'html-in-headers', 'html-in-comments', 'filtered-tags-and-attributes' ]);
|
|
41
|
+
itChecksScreenshots(browserContext, '16_movetext_options', [ 'localized-piece-symbols', 'custom-piece-symbols', 'figurine-piece-symbols-and-diagram-options',
|
|
42
42
|
'hidden-diagrams' ]);
|
|
43
43
|
});
|
|
@@ -37,7 +37,7 @@ describe('Movetext interaction', function() {
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
function itCheckClickMove(itemIndex, label, targets) {
|
|
40
|
-
itCustom(browserContext, '
|
|
40
|
+
itCustom(browserContext, '17_movetext_interaction', itemIndex, label, async function(element) {
|
|
41
41
|
let actions = browserContext.driver.actions({ async: true });
|
|
42
42
|
await setSandbox(browserContext, '');
|
|
43
43
|
for (let i = 0; i < targets.length; ++i) {
|
|
@@ -72,7 +72,7 @@ describe('Movetext interaction', function() {
|
|
|
72
72
|
]);
|
|
73
73
|
|
|
74
74
|
function itCheckKeyboardActions(itemIndex, label, expectedOnGoFirst, expectedOnGoPrevious, expectedOnGoNext, expectedOnGoLast) {
|
|
75
|
-
itCustom(browserContext, '
|
|
75
|
+
itCustom(browserContext, '17_movetext_interaction', itemIndex, label, async function(element) {
|
|
76
76
|
let focusFieldElement = await element.findElement(By.className('kokopu-focusField'));
|
|
77
77
|
|
|
78
78
|
await setSandbox(browserContext, '');
|
package/test/common/graphic.js
CHANGED
|
@@ -38,6 +38,9 @@ const UNREACHABLE_TEST_CLIENT_MESSAGE =
|
|
|
38
38
|
'Do not forget to run `npm run test_env:stop` when finished.\n';
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
const ANIMATION_DELAY = 200;
|
|
42
|
+
|
|
43
|
+
|
|
41
44
|
/**
|
|
42
45
|
* Open a browser in the client (+ ensure everything else is ready to execute graphic tests).
|
|
43
46
|
*/
|
|
@@ -111,6 +114,9 @@ async function fetchTestCase(browserContext, testCaseName) {
|
|
|
111
114
|
// Fetch the new page.
|
|
112
115
|
await browserContext.driver.get(`file:///app/build/test_graphic/${testCaseName}/index.html`);
|
|
113
116
|
browserContext.latestTestCase = testCaseName;
|
|
117
|
+
|
|
118
|
+
// Wait until the end of the animations.
|
|
119
|
+
await new Promise(resolve => setTimeout(resolve, ANIMATION_DELAY));
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/after_move.png
RENAMED
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/empty_square.png
RENAMED
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/null_vector.png
RENAMED
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/out_of_board.png
RENAMED
|
File without changes
|
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_empty.png
RENAMED
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_non_empty_1.png
RENAMED
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_non_empty_2.png
RENAMED
|
File without changes
|
|
File without changes
|
package/test/references/{08_chessboard_move_pieces → 09_chessboard_move_pieces}/over_text_marker.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/null_vector.png
RENAMED
|
File without changes
|
package/test/references/{09_chessboard_edit_arrows → 10_chessboard_edit_arrows}/out_of_board.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/castling_move.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/illegal_move.png
RENAMED
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/illegal_position.png
RENAMED
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/null_vector.png
RENAMED
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/out_of_board.png
RENAMED
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/regular_move_1.png
RENAMED
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/regular_move_2.png
RENAMED
|
File without changes
|
package/test/references/{10_chessboard_play_moves → 11_chessboard_play_moves}/wrong_color.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|