@mirasen/chessboard 1.0.5 → 1.0.6
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/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
[](https://www.npmjs.com/package/@mirasen/chessboard)
|
|
2
2
|
[](https://github.com/mirasen-io/chessboard/actions/workflows/ci.yml)
|
|
3
|
+
[](https://sonarcloud.io/summary/new_code?id=mirasen-io_chessboard)
|
|
4
|
+
[](https://sonarcloud.io/summary/new_code?id=mirasen-io_chessboard)
|
|
3
5
|
[](./LICENSE)
|
|
4
6
|
|
|
5
7
|
# @mirasen/chessboard
|
|
@@ -37,9 +39,15 @@ The default first-party extension baseline includes rendering, events, selection
|
|
|
37
39
|
|
|
38
40
|
That means the board already covers a meaningful baseline chess UX instead of stopping at “draw squares and pieces”.
|
|
39
41
|
|
|
42
|
+
### Built-in chessboard behavior
|
|
43
|
+
|
|
44
|
+
Mirasen Chessboard provides a complete modern interaction and visual baseline out of the box: selection, deselection, reselection, drag-to-move, release targeting, legal destinations, promotion, auto-promotion, and state-diff animation. Moves are resolved on release rather than committed immediately on press, giving users a more forgiving interaction flow. Because animation is driven by board-state transitions, pieces can move, appear, disappear, promote, or return smoothly without app-level glue code.
|
|
45
|
+
|
|
40
46
|
## Highlights
|
|
41
47
|
|
|
42
48
|
- Real built-in chess interaction
|
|
49
|
+
- Easy game/rules layer integration
|
|
50
|
+
- State-diff animation beyond simple move events
|
|
43
51
|
- Extension-driven architecture
|
|
44
52
|
- First-party baseline extensions
|
|
45
53
|
- Explicit SVG slot ownership
|
|
@@ -3,16 +3,14 @@ export function createScheduler(opts) {
|
|
|
3
3
|
let scheduled = false;
|
|
4
4
|
let runId = 0;
|
|
5
5
|
let rafHandle = null;
|
|
6
|
-
const flushCore = () => {
|
|
7
|
-
if (!scheduled && rafHandle == null) {
|
|
6
|
+
const flushCore = (force = false) => {
|
|
7
|
+
if (!force && !scheduled && rafHandle == null) {
|
|
8
8
|
// Maybe was cancelled after the rAF callback was scheduled but before it fired.
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
// Reset scheduled flags first to allow schedule() during render to queue the next frame.
|
|
12
12
|
scheduled = false;
|
|
13
|
-
|
|
14
|
-
rafHandle = null;
|
|
15
|
-
}
|
|
13
|
+
rafHandle = null;
|
|
16
14
|
render();
|
|
17
15
|
};
|
|
18
16
|
return {
|
|
@@ -29,17 +27,16 @@ export function createScheduler(opts) {
|
|
|
29
27
|
});
|
|
30
28
|
},
|
|
31
29
|
flushNow() {
|
|
30
|
+
if (!scheduled && rafHandle == null)
|
|
31
|
+
return;
|
|
32
32
|
// Invalidate any pending rAF render immediately.
|
|
33
|
-
|
|
34
|
-
runId++;
|
|
35
|
-
scheduled = false;
|
|
36
|
-
}
|
|
33
|
+
runId++;
|
|
37
34
|
if (rafHandle != null) {
|
|
38
35
|
const caf = globalThis.cancelAnimationFrame;
|
|
39
36
|
caf(rafHandle);
|
|
40
37
|
rafHandle = null;
|
|
41
38
|
}
|
|
42
|
-
flushCore();
|
|
39
|
+
flushCore(true);
|
|
43
40
|
},
|
|
44
41
|
cancel() {
|
|
45
42
|
scheduled = false;
|
|
@@ -19,7 +19,7 @@ export function createInputAdapter(options) {
|
|
|
19
19
|
internalState.container.addEventListener(type, onEventHander);
|
|
20
20
|
},
|
|
21
21
|
unsubscribeEvent(type) {
|
|
22
|
-
assert(NEED_EVENT_TYPES.has(type), `Unsubscribe for event type ${type} is not supported. This is required event type for the board to function properly.`);
|
|
22
|
+
assert(!NEED_EVENT_TYPES.has(type), `Unsubscribe for event type ${type} is not supported. This is required event type for the board to function properly.`);
|
|
23
23
|
internalState.container.removeEventListener(type, onEventHander);
|
|
24
24
|
},
|
|
25
25
|
destroy() {
|
package/package.json
CHANGED