@mirasen/chessboard 0.1.0 → 1.0.0-rc.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/CHANGELOG.md +16 -0
- package/README.md +224 -47
- package/dist/animation/planner.d.ts +11 -6
- package/dist/animation/planner.js +167 -48
- package/dist/animation/render/fade.d.ts +5 -5
- package/dist/animation/render/fade.js +4 -4
- package/dist/animation/render/move.d.ts +6 -6
- package/dist/animation/render/move.js +6 -6
- package/dist/animation/render/plan.d.ts +6 -6
- package/dist/animation/render/plan.js +3 -3
- package/dist/animation/render/static.d.ts +5 -5
- package/dist/animation/render/static.js +4 -4
- package/dist/animation/render/types.d.ts +1 -1
- package/dist/animation/types.d.ts +15 -16
- package/dist/animation/types.js +1 -6
- package/dist/extensions/animation/factory.d.ts +1 -1
- package/dist/extensions/animation/factory.js +1 -1
- package/dist/extensions/animation/types.d.ts +1 -1
- package/dist/extensions/factory/main.d.ts +1 -1
- package/dist/extensions/factory/main.js +27 -6
- package/dist/extensions/factory/runtime.d.ts +6 -5
- package/dist/extensions/factory/runtime.js +48 -4
- package/dist/extensions/first-party/active-target/factory.d.ts +1 -1
- package/dist/extensions/first-party/active-target/factory.js +9 -9
- package/dist/extensions/first-party/active-target/types.d.ts +2 -2
- package/dist/extensions/first-party/auto-promote/factory.d.ts +2 -0
- package/dist/extensions/first-party/auto-promote/factory.js +51 -0
- package/dist/extensions/first-party/auto-promote/types.d.ts +14 -0
- package/dist/extensions/first-party/auto-promote/types.js +2 -0
- package/dist/extensions/first-party/board-events/factory.d.ts +1 -1
- package/dist/extensions/first-party/board-events/factory.js +3 -16
- package/dist/extensions/first-party/board-events/types.d.ts +6 -7
- package/dist/extensions/first-party/common/helpers.d.ts +2 -2
- package/dist/extensions/first-party/common/helpers.js +1 -1
- package/dist/extensions/first-party/common/types.d.ts +1 -1
- package/dist/extensions/first-party/last-move/factory.d.ts +1 -1
- package/dist/extensions/first-party/last-move/factory.js +10 -10
- package/dist/extensions/first-party/last-move/types.d.ts +2 -2
- package/dist/extensions/first-party/legal-moves/factory.d.ts +1 -1
- package/dist/extensions/first-party/legal-moves/factory.js +7 -7
- package/dist/extensions/first-party/legal-moves/types.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/animation/factory.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/animation/factory.js +3 -3
- package/dist/extensions/first-party/main-renderer/animation/render.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/animation/render.js +2 -3
- package/dist/extensions/first-party/main-renderer/animation/types.d.ts +7 -7
- package/dist/extensions/first-party/main-renderer/animation/update.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/animation/update.js +12 -26
- package/dist/extensions/first-party/main-renderer/board/factory.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/board/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/board/render.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/board/render.js +6 -6
- package/dist/extensions/first-party/main-renderer/board/types.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/board/update.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/board/update.js +8 -6
- package/dist/extensions/first-party/main-renderer/coordinates/factory.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/coordinates/factory.js +1 -1
- package/dist/extensions/first-party/main-renderer/coordinates/render.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/coordinates/render.js +7 -7
- package/dist/extensions/first-party/main-renderer/coordinates/types.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/drag/factory.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/drag/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/drag/render.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/drag/render.js +2 -2
- package/dist/extensions/first-party/main-renderer/drag/types.d.ts +4 -4
- package/dist/extensions/first-party/main-renderer/drag/update.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/drag/update.js +1 -1
- package/dist/extensions/first-party/main-renderer/factory.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/factory.js +9 -9
- package/dist/extensions/first-party/main-renderer/normalize.d.ts +2 -3
- package/dist/extensions/first-party/main-renderer/normalize.js +4 -4
- package/dist/extensions/first-party/main-renderer/pieces/factory.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/pieces/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/pieces/render.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/pieces/render.js +9 -9
- package/dist/extensions/first-party/main-renderer/pieces/suppress.d.ts +4 -4
- package/dist/extensions/first-party/main-renderer/pieces/suppress.js +7 -2
- package/dist/extensions/first-party/main-renderer/pieces/types.d.ts +5 -5
- package/dist/extensions/first-party/main-renderer/pieces/update.d.ts +4 -4
- package/dist/extensions/first-party/main-renderer/pieces/update.js +5 -5
- package/dist/extensions/first-party/main-renderer/types/extension.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/types/extension.js +1 -1
- package/dist/extensions/first-party/main-renderer/types/input.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/types/instance.d.ts +8 -8
- package/dist/extensions/first-party/main-renderer/types/internal.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/types/template.d.ts +1 -1
- package/dist/extensions/first-party/promotion/factory.d.ts +3 -0
- package/dist/extensions/first-party/promotion/factory.js +219 -0
- package/dist/extensions/first-party/promotion/normalize.d.ts +3 -0
- package/dist/extensions/first-party/promotion/normalize.js +37 -0
- package/dist/extensions/first-party/promotion/types/input.d.ts +10 -0
- package/dist/extensions/first-party/promotion/types/internal.d.ts +12 -0
- package/dist/extensions/first-party/promotion/types/internal.js +22 -0
- package/dist/extensions/first-party/promotion/types/main.d.ts +24 -0
- package/dist/extensions/first-party/promotion/types/main.js +2 -0
- package/dist/extensions/first-party/selected-square/factory.d.ts +1 -1
- package/dist/extensions/first-party/selected-square/factory.js +7 -7
- package/dist/extensions/first-party/selected-square/types.d.ts +2 -2
- package/dist/extensions/index.d.ts +8 -8
- package/dist/extensions/index.js +6 -6
- package/dist/extensions/invalidation/factory.d.ts +1 -1
- package/dist/extensions/types/basic/events.d.ts +10 -33
- package/dist/extensions/types/basic/events.js +9 -5
- package/dist/extensions/types/basic/interaction.d.ts +21 -0
- package/dist/extensions/types/basic/render.d.ts +2 -2
- package/dist/extensions/types/basic/transient-visuals.d.ts +3 -2
- package/dist/extensions/types/basic/update.d.ts +3 -3
- package/dist/extensions/types/context/animation.d.ts +3 -3
- package/dist/extensions/types/context/events.d.ts +5 -0
- package/dist/extensions/types/context/events.js +1 -0
- package/dist/extensions/types/context/render.d.ts +2 -2
- package/dist/extensions/types/context/transient-visuals.d.ts +2 -2
- package/dist/extensions/types/context/ui-move.d.ts +3 -15
- package/dist/extensions/types/context/update.d.ts +4 -4
- package/dist/extensions/types/context/update.js +1 -1
- package/dist/extensions/types/extension.d.ts +16 -14
- package/dist/extensions/types/main.d.ts +16 -11
- package/dist/extensions/types/surface/commands.d.ts +14 -5
- package/dist/extensions/types/surface/events.d.ts +2 -3
- package/dist/extensions/types/surface/main.d.ts +4 -4
- package/dist/extensions/types/wrapper.d.ts +23 -22
- package/dist/extensions/types/wrapper.js +34 -6
- package/dist/extensions/update.d.ts +3 -3
- package/dist/extensions/update.js +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/layout/factory.d.ts +1 -1
- package/dist/layout/factory.js +4 -4
- package/dist/layout/geometry/factory.d.ts +3 -12
- package/dist/layout/geometry/factory.js +17 -18
- package/dist/layout/geometry/helpers.d.ts +5 -0
- package/dist/layout/geometry/helpers.js +33 -0
- package/dist/layout/geometry/types.d.ts +14 -13
- package/dist/layout/helpers.d.ts +3 -4
- package/dist/layout/helpers.js +5 -5
- package/dist/layout/mutation.d.ts +1 -1
- package/dist/layout/reducers.d.ts +1 -1
- package/dist/layout/reducers.js +10 -9
- package/dist/layout/types.d.ts +7 -7
- package/dist/mutation/pipeline.d.ts +1 -1
- package/dist/mutation/pipeline.js +1 -1
- package/dist/mutation/session.d.ts +1 -1
- package/dist/render/factory.d.ts +1 -1
- package/dist/render/factory.js +7 -7
- package/dist/render/mount.d.ts +1 -1
- package/dist/render/mount.js +4 -4
- package/dist/render/rendering/animation.d.ts +1 -1
- package/dist/render/rendering/animation.js +1 -1
- package/dist/render/rendering/helpers.d.ts +1 -1
- package/dist/render/rendering/state.d.ts +2 -2
- package/dist/render/rendering/state.js +9 -9
- package/dist/render/rendering/visuals.d.ts +2 -2
- package/dist/render/rendering/visuals.js +1 -1
- package/dist/render/scheduler/scheduler.d.ts +1 -1
- package/dist/render/svg/factory.d.ts +2 -2
- package/dist/render/svg/factory.js +1 -1
- package/dist/render/svg/helpers.d.ts +1 -1
- package/dist/render/svg/helpers.js +1 -1
- package/dist/render/types.d.ts +5 -5
- package/dist/runtime/factory/events.d.ts +3 -0
- package/dist/runtime/factory/events.js +18 -0
- package/dist/runtime/factory/helpers.d.ts +2 -2
- package/dist/runtime/factory/helpers.js +14 -14
- package/dist/runtime/factory/input.d.ts +2 -2
- package/dist/runtime/factory/input.js +20 -13
- package/dist/runtime/factory/main.d.ts +1 -1
- package/dist/runtime/factory/main.js +56 -16
- package/dist/runtime/input/adapter/event.d.ts +3 -0
- package/dist/runtime/input/adapter/event.js +19 -0
- package/dist/runtime/input/adapter/factory.d.ts +1 -1
- package/dist/runtime/input/adapter/factory.js +19 -38
- package/dist/runtime/input/adapter/helpers.d.ts +3 -5
- package/dist/runtime/input/adapter/helpers.js +60 -12
- package/dist/runtime/input/adapter/pointer.d.ts +7 -11
- package/dist/runtime/input/adapter/pointer.js +37 -70
- package/dist/runtime/input/adapter/types.d.ts +7 -4
- package/dist/runtime/input/adapter/types.js +6 -1
- package/dist/runtime/input/controller/factory.d.ts +1 -1
- package/dist/runtime/input/controller/factory.js +13 -12
- package/dist/runtime/input/controller/helpers.d.ts +2 -2
- package/dist/runtime/input/controller/pointer.d.ts +6 -7
- package/dist/runtime/input/controller/pointer.js +39 -38
- package/dist/runtime/input/controller/transient-visuals.d.ts +3 -3
- package/dist/runtime/input/controller/transient-visuals.js +12 -5
- package/dist/runtime/input/controller/types.d.ts +8 -7
- package/dist/runtime/layout.d.ts +1 -1
- package/dist/runtime/layout.js +2 -2
- package/dist/runtime/lifecycle.d.ts +2 -2
- package/dist/runtime/lifecycle.js +8 -8
- package/dist/runtime/mutation/extension-update.d.ts +1 -1
- package/dist/runtime/mutation/factory.d.ts +1 -1
- package/dist/runtime/mutation/factory.js +6 -6
- package/dist/runtime/mutation/interaction.d.ts +1 -1
- package/dist/runtime/mutation/interaction.js +3 -7
- package/dist/runtime/mutation/invalidation.d.ts +1 -0
- package/dist/runtime/mutation/invalidation.js +1 -1
- package/dist/runtime/mutation/last-move.d.ts +1 -1
- package/dist/runtime/mutation/layout.d.ts +1 -1
- package/dist/runtime/mutation/pipeline.d.ts +6 -6
- package/dist/runtime/mutation/request-render.d.ts +1 -1
- package/dist/runtime/mutation/request-render.js +1 -1
- package/dist/runtime/mutation/run.d.ts +1 -1
- package/dist/runtime/mutation/types.d.ts +10 -8
- package/dist/runtime/types/main.d.ts +8 -6
- package/dist/state/board/check.d.ts +3 -3
- package/dist/state/board/check.js +1 -1
- package/dist/state/board/coords.d.ts +1 -1
- package/dist/state/board/denormalize.d.ts +3 -3
- package/dist/state/board/denormalize.js +4 -4
- package/dist/state/board/factory.d.ts +2 -2
- package/dist/state/board/factory.js +4 -4
- package/dist/state/board/mutation.d.ts +2 -2
- package/dist/state/board/normalize.d.ts +2 -2
- package/dist/state/board/normalize.js +2 -2
- package/dist/state/board/piece.d.ts +1 -1
- package/dist/state/board/position.d.ts +2 -2
- package/dist/state/board/position.js +2 -2
- package/dist/state/board/reducers.d.ts +2 -2
- package/dist/state/board/reducers.js +3 -3
- package/dist/state/board/types/input.d.ts +1 -1
- package/dist/state/board/types/internal.d.ts +1 -1
- package/dist/state/board/types/main.d.ts +3 -3
- package/dist/state/board/types/output.d.ts +2 -2
- package/dist/state/change/{factory.d.ts → factory/main.d.ts} +1 -1
- package/dist/state/change/{factory.js → factory/main.js} +8 -5
- package/dist/state/change/factory/ui-move.d.ts +4 -0
- package/dist/{runtime → state/change}/factory/ui-move.js +9 -9
- package/dist/state/change/helpers.d.ts +6 -4
- package/dist/state/change/helpers.js +12 -2
- package/dist/state/change/mutation.d.ts +2 -2
- package/dist/state/change/reducers.d.ts +4 -4
- package/dist/state/change/reducers.js +4 -4
- package/dist/state/change/types/main.d.ts +18 -0
- package/dist/state/change/types/main.js +1 -0
- package/dist/state/change/types/ui-move.d.ts +25 -0
- package/dist/state/change/types/ui-move.js +1 -0
- package/dist/state/factory.d.ts +1 -1
- package/dist/state/factory.js +4 -4
- package/dist/state/interaction/factory.d.ts +1 -1
- package/dist/state/interaction/factory.js +7 -5
- package/dist/state/interaction/helpers.d.ts +4 -2
- package/dist/state/interaction/helpers.js +5 -2
- package/dist/state/interaction/movability.d.ts +3 -3
- package/dist/state/interaction/movability.js +2 -2
- package/dist/state/interaction/mutation.d.ts +1 -1
- package/dist/state/interaction/normalize.d.ts +2 -2
- package/dist/state/interaction/normalize.js +2 -2
- package/dist/state/interaction/reducers.d.ts +3 -3
- package/dist/state/interaction/reducers.js +3 -3
- package/dist/state/interaction/types/input.d.ts +1 -1
- package/dist/state/interaction/types/internal.d.ts +10 -2
- package/dist/state/interaction/types/main.d.ts +4 -4
- package/dist/state/types.d.ts +6 -6
- package/dist/state/view/factory.d.ts +1 -1
- package/dist/state/view/factory.js +2 -2
- package/dist/state/view/mutation.d.ts +1 -1
- package/dist/state/view/reducers.d.ts +2 -2
- package/dist/state/view/types/internal.d.ts +1 -1
- package/dist/state/view/types/main.d.ts +4 -4
- package/dist/wrapper/factory.d.ts +2 -2
- package/dist/wrapper/factory.js +3 -27
- package/dist/wrapper/types.d.ts +4 -4
- package/package.json +9 -5
- package/dist/runtime/factory/ui-move.d.ts +0 -4
- package/dist/runtime/types/ui-move.d.ts +0 -9
- package/dist/state/change/types.d.ts +0 -17
- /package/dist/{runtime/types/ui-move.js → extensions/first-party/promotion/types/input.js} +0 -0
- /package/dist/{state/change/types.js → extensions/types/basic/interaction.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @mirasen/chessboard
|
|
2
2
|
|
|
3
|
+
## 1.0.0-rc.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 2609920: First 1.0 release candidate with the new extension-driven architecture, built-in chess interaction baseline, promotion flow, and auto-promote support.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 2609920: Added promotion and auto-promotion to queen extensions
|
|
12
|
+
|
|
13
|
+
## 0.1.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- f6ceb99: Fix relative import issues
|
|
18
|
+
|
|
3
19
|
## 0.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -6,45 +6,48 @@
|
|
|
6
6
|
|
|
7
7
|
# @mirasen/chessboard
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
A framework-agnostic TypeScript chessboard platform with real chess interaction built in and an extension-driven architecture.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Why this exists
|
|
12
|
+
|
|
13
|
+
Most chessboards fall into one of two buckets:
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
- rendering primitives that leave core interaction UX to app code
|
|
16
|
+
- tightly coupled monoliths that are hard to extend cleanly
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
`@mirasen/chessboard` aims for a better balance:
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
- meaningful built-in chess interaction out of the box
|
|
21
|
+
- first-party extensions for common board UX
|
|
22
|
+
- explicit rendering and ownership boundaries
|
|
23
|
+
- extension-driven growth without turning the board into glue hell
|
|
18
24
|
|
|
19
|
-
|
|
20
|
-
- extension-driven rendering and interaction
|
|
21
|
-
- public wrapper / package API
|
|
22
|
-
- early integration ergonomics
|
|
25
|
+
This is not just a board renderer. It is a chessboard platform designed for real chess interaction.
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
## What you get out of the box
|
|
25
28
|
|
|
26
|
-
-
|
|
27
|
-
- some higher-level public APIs
|
|
28
|
-
- broader test coverage
|
|
29
|
-
- final `1.0.0` API guarantees
|
|
29
|
+
The built-in first-party extension baseline currently includes both foundational runtime-facing extensions and user-facing board features.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
- `renderer` — the first-party rendering extension that validates the same extension architecture used for board features
|
|
32
|
+
- `events`
|
|
33
|
+
- `selectedSquare`
|
|
34
|
+
- `activeTarget`
|
|
35
|
+
- `legalMoves`
|
|
36
|
+
- `lastMove`
|
|
37
|
+
- `promotion`
|
|
38
|
+
- `autoPromote`
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
- explicit runtime / render / interaction boundaries
|
|
35
|
-
- extension-first architecture
|
|
36
|
-
- predictable rendering ownership
|
|
37
|
-
- room for advanced features without core hacks
|
|
40
|
+
That means the board already covers a meaningful baseline chess UX instead of stopping at “draw squares and pieces”.
|
|
38
41
|
|
|
39
|
-
##
|
|
42
|
+
## Highlights
|
|
40
43
|
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
44
|
+
- Real built-in chess interaction
|
|
45
|
+
- Extension-driven architecture
|
|
46
|
+
- First-party baseline extensions
|
|
47
|
+
- Explicit SVG slot ownership
|
|
48
|
+
- Clean separation between runtime, rendering, interaction, and animation
|
|
49
|
+
- Promotion flow built into the board pipeline
|
|
50
|
+
- Optional auto-promotion as a separate behavior extension
|
|
48
51
|
|
|
49
52
|
## Installation
|
|
50
53
|
|
|
@@ -52,45 +55,219 @@ Not finalized yet:
|
|
|
52
55
|
npm install @mirasen/chessboard
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
##
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
### Minimal example
|
|
56
61
|
|
|
57
62
|
```ts
|
|
58
63
|
import { createBoard } from '@mirasen/chessboard';
|
|
59
64
|
|
|
65
|
+
const element = document.getElementById('board');
|
|
66
|
+
|
|
67
|
+
if (!element) {
|
|
68
|
+
throw new Error('Missing board element');
|
|
69
|
+
}
|
|
70
|
+
|
|
60
71
|
const board = createBoard({
|
|
61
|
-
|
|
72
|
+
element
|
|
62
73
|
});
|
|
74
|
+
// Set free movability, default - disabled
|
|
75
|
+
board.setMovability({
|
|
76
|
+
mode: 'free'
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Explicit built-in interaction extensions
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { createBoard } from '@mirasen/chessboard';
|
|
84
|
+
|
|
85
|
+
const element = document.getElementById('board');
|
|
86
|
+
|
|
87
|
+
if (!element) {
|
|
88
|
+
throw new Error('Missing board element');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const board = createBoard({
|
|
92
|
+
element,
|
|
93
|
+
extensions: [
|
|
94
|
+
// Always add renderer first, otherwise nothing will be rendered
|
|
95
|
+
'renderer',
|
|
96
|
+
'selectedSquare',
|
|
97
|
+
'activeTarget',
|
|
98
|
+
'legalMoves',
|
|
99
|
+
'lastMove',
|
|
100
|
+
'events',
|
|
101
|
+
// Keep autoPromote before promotion, otherwise promotion may defer the move first
|
|
102
|
+
'autoPromote',
|
|
103
|
+
'promotion'
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
```
|
|
63
107
|
|
|
64
|
-
|
|
108
|
+
### setOnUIMove
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { createBoard } from '@mirasen/chessboard';
|
|
112
|
+
|
|
113
|
+
const element = document.getElementById('board');
|
|
114
|
+
|
|
115
|
+
if (!element) {
|
|
116
|
+
throw new Error('Missing board element');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const board = createBoard({
|
|
120
|
+
element,
|
|
121
|
+
state: {
|
|
122
|
+
board: 'start',
|
|
123
|
+
interaction: {
|
|
124
|
+
movability: {
|
|
125
|
+
mode: 'free'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
board.extensions.events.setOnUIMove((move) => {
|
|
65
132
|
console.log('UI move:', move);
|
|
66
133
|
});
|
|
67
134
|
```
|
|
68
135
|
|
|
69
|
-
|
|
136
|
+
### setMovability - strict with explicit destinations
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { createBoard } from '@mirasen/chessboard';
|
|
140
|
+
|
|
141
|
+
const element = document.getElementById('board');
|
|
142
|
+
|
|
143
|
+
if (!element) {
|
|
144
|
+
throw new Error('Missing board element');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const board = createBoard({
|
|
148
|
+
element
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
board.setMovability({
|
|
152
|
+
mode: 'strict',
|
|
153
|
+
destinations: {
|
|
154
|
+
e2: [{ to: 'e3' }, { to: 'e4' }],
|
|
155
|
+
d7: [
|
|
156
|
+
{ to: 'c8', promotedTo: ['queen', 'rook', 'bishop', 'knight'] },
|
|
157
|
+
{ to: 'd8', promotedTo: ['queen', 'rook', 'bishop', 'knight'] }
|
|
158
|
+
],
|
|
159
|
+
g1: [{ to: 'f3' }, { to: 'h3' }]
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### setMovability - strict with a resolver
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import { createBoard } from '@mirasen/chessboard';
|
|
168
|
+
|
|
169
|
+
const element = document.getElementById('board');
|
|
170
|
+
|
|
171
|
+
if (!element) {
|
|
172
|
+
throw new Error('Missing board element');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const board = createBoard({
|
|
176
|
+
element
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
board.setMovability({
|
|
180
|
+
mode: 'strict',
|
|
181
|
+
destinations: (source) => {
|
|
182
|
+
if (source === 'e2')
|
|
183
|
+
return [
|
|
184
|
+
{ to: 'e8', promotedTo: ['bishop', 'queen'] },
|
|
185
|
+
{ to: 'd8', promotedTo: ['rook', 'knight', 'queen'] }
|
|
186
|
+
];
|
|
187
|
+
if (source === 'f7')
|
|
188
|
+
return [
|
|
189
|
+
{ to: 'f8', promotedTo: ['bishop', 'rook', 'knight', 'queen'] },
|
|
190
|
+
{ to: 'g8', promotedTo: ['bishop', 'rook', 'knight', 'queen'] }
|
|
191
|
+
];
|
|
192
|
+
if (source === 'd7')
|
|
193
|
+
return [
|
|
194
|
+
{ to: 'd1', promotedTo: ['bishop', 'knight'] },
|
|
195
|
+
{ to: 'e1', promotedTo: ['rook', 'knight', 'queen'] }
|
|
196
|
+
];
|
|
197
|
+
if (source === 'c2')
|
|
198
|
+
return [
|
|
199
|
+
{ to: 'c1', promotedTo: ['bishop', 'rook', 'knight', 'queen'] },
|
|
200
|
+
{ to: 'b1', promotedTo: ['bishop', 'rook', 'knight', 'queen'] }
|
|
201
|
+
];
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Promotion and auto-promotion
|
|
70
208
|
|
|
71
|
-
|
|
209
|
+
Promotion is handled inside the board interaction pipeline through a natural deferred move flow.
|
|
72
210
|
|
|
73
|
-
|
|
211
|
+
That means the board does not need the awkward pattern of:
|
|
74
212
|
|
|
75
|
-
|
|
213
|
+
- reject move
|
|
214
|
+
- open external dialog
|
|
215
|
+
- replay the move later
|
|
76
216
|
|
|
77
|
-
|
|
78
|
-
- Source: https://github.com/LexLuengas/chessnut-pieces
|
|
79
|
-
- License: Apache License 2.0 — https://github.com/LexLuengas/chessnut-pieces/blob/master/LICENSE.txt
|
|
217
|
+
Instead:
|
|
80
218
|
|
|
81
|
-
|
|
219
|
+
- `promotion` provides the built-in promotion chooser UI
|
|
220
|
+
- `autoPromote` provides behavior-only auto-promotion logic
|
|
82
221
|
|
|
83
|
-
|
|
84
|
-
|
|
222
|
+
These are separate extensions on purpose:
|
|
223
|
+
|
|
224
|
+
- `promotion` is UI
|
|
225
|
+
- `autoPromote` is behavior
|
|
226
|
+
|
|
227
|
+
This separation is a good example of the architecture: common chess UX can be built in without collapsing everything into one hardcoded board layer.
|
|
228
|
+
|
|
229
|
+
## Architecture
|
|
230
|
+
|
|
231
|
+
`@mirasen/chessboard` is built around explicit boundaries:
|
|
232
|
+
|
|
233
|
+
- runtime owns board, interaction, and update semantics
|
|
234
|
+
- renderer owns SVG structure and visual layers
|
|
235
|
+
- animation owns transition planning and temporary visual occupancy
|
|
236
|
+
- extensions render through declared slots instead of ad hoc DOM access
|
|
237
|
+
|
|
238
|
+
The goal is to make common chess interaction powerful without making the system brittle.
|
|
239
|
+
|
|
240
|
+
## Not just a primitive, not a monolith
|
|
241
|
+
|
|
242
|
+
The project is intentionally positioned between two weak extremes:
|
|
243
|
+
|
|
244
|
+
### Primitive-only board
|
|
245
|
+
|
|
246
|
+
A board that only renders pieces and leaves everything else to app code often forces consumers to rebuild the same interaction UX repeatedly.
|
|
247
|
+
|
|
248
|
+
### Hardcoded monolith
|
|
249
|
+
|
|
250
|
+
A board that handles everything internally without clean boundaries becomes difficult to evolve, customize, or extend.
|
|
251
|
+
|
|
252
|
+
`@mirasen/chessboard` aims for a middle path:
|
|
253
|
+
|
|
254
|
+
- strong built-in baseline interaction
|
|
255
|
+
- clean internal architecture
|
|
256
|
+
- extension-driven feature growth
|
|
257
|
+
|
|
258
|
+
## Status
|
|
85
259
|
|
|
86
|
-
|
|
260
|
+
Release candidate for version `1.0.0`, focused on a strong built-in interaction baseline and extension-driven architecture.
|
|
87
261
|
|
|
88
|
-
|
|
262
|
+
## Roadmap after RC
|
|
89
263
|
|
|
90
|
-
|
|
264
|
+
After the first release candidate, the next steps are expected to include:
|
|
91
265
|
|
|
92
|
-
|
|
266
|
+
- remaining test hardening
|
|
267
|
+
- documentation expansion
|
|
268
|
+
- more examples
|
|
269
|
+
- further polish toward final `1.0.0`
|
|
93
270
|
|
|
94
|
-
##
|
|
271
|
+
## Project direction
|
|
95
272
|
|
|
96
|
-
|
|
273
|
+
This platform is being built as a foundation for richer chess learning and interaction workflows, but the board itself is designed to stand as a serious open-source UI platform in its own right.
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import type { AnimationPlan, AnimationPlanningInput } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Plan animation tracks and suppressed squares for a state transition.
|
|
4
|
+
*
|
|
5
|
+
* This is the single entry point for animation planning. It:
|
|
6
|
+
* 1. Normalizes both snapshots (incorporates deferredUIMoveRequest).
|
|
7
|
+
* 2. Detects lifted-piece-drag drop completion and builds an internal exclude.
|
|
8
|
+
* 3. Computes tracks via greedy min-distance matching.
|
|
9
|
+
* 4. Assembles the full suppressedSquares set (track-derived + excluded drop endpoints).
|
|
10
|
+
*/
|
|
11
|
+
export declare function calculateAnimationPlan(input: AnimationPlanningInput): AnimationPlan;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { isNonEmptyPieceCode } from '../state/board/check.js';
|
|
3
|
+
import { fileOf, rankOf } from '../state/board/coords.js';
|
|
4
|
+
import { SQUARE_COUNT } from '../state/board/types/internal.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
5
6
|
// Precomputed squared distance: (dFile² + dRank²) for all square pairs.
|
|
6
|
-
// Max value = 7² + 7² = 98, fits in Uint8.
|
|
7
|
+
// Max value = 7² + 7² = 98, fits in Uint8. Index: a * 64 + b.
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
7
9
|
const SQUARE_DIST = new Uint8Array(SQUARE_COUNT * SQUARE_COUNT);
|
|
8
10
|
for (let a = 0; a < SQUARE_COUNT; a++) {
|
|
9
11
|
for (let b = 0; b < SQUARE_COUNT; b++) {
|
|
@@ -12,7 +14,107 @@ for (let a = 0; a < SQUARE_COUNT; a++) {
|
|
|
12
14
|
SQUARE_DIST[a * SQUARE_COUNT + b] = df * df + dr * dr;
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
|
-
|
|
17
|
+
const EMPTY_EXCLUDE = {
|
|
18
|
+
move: new Map(),
|
|
19
|
+
square: new Set()
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Detect whether a lifted-piece-drag was just completed (dropped).
|
|
23
|
+
*
|
|
24
|
+
* Condition:
|
|
25
|
+
* - previous snapshot had an active lifted-piece-drag session
|
|
26
|
+
* - current snapshot has no drag session
|
|
27
|
+
* - current snapshot has a lastMove
|
|
28
|
+
*
|
|
29
|
+
* Returns the lastMove when the condition holds, otherwise null.
|
|
30
|
+
*/
|
|
31
|
+
function detectLiftedPieceDrop(previous, current) {
|
|
32
|
+
const prevDrag = previous.interaction.dragSession;
|
|
33
|
+
if (!prevDrag || prevDrag.type !== 'lifted-piece-drag')
|
|
34
|
+
return null;
|
|
35
|
+
if (current.interaction.dragSession !== null)
|
|
36
|
+
return null;
|
|
37
|
+
return current.change.lastMove ?? null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build an ExcludeSpec that suppresses the move track and both endpoint
|
|
41
|
+
* fades for a given lastMove (used when a lifted-piece drop is detected).
|
|
42
|
+
*/
|
|
43
|
+
function buildExcludeForDrop(lastMove) {
|
|
44
|
+
const moveMap = new Map();
|
|
45
|
+
moveMap.set(lastMove.from, new Set([lastMove.to]));
|
|
46
|
+
const squareSet = new Set([lastMove.from, lastMove.to]);
|
|
47
|
+
return { move: moveMap, square: squareSet };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Normalize a snapshot by incorporating a pending deferredUIMoveRequest
|
|
51
|
+
* into the board and lastMove. Currently limited to pawn moves.
|
|
52
|
+
*
|
|
53
|
+
* If there is no deferred request the snapshot is returned as-is.
|
|
54
|
+
*/
|
|
55
|
+
function buildEffectiveAnimationPlanningSnapshot(state) {
|
|
56
|
+
const request = state.change.deferredUIMoveRequest;
|
|
57
|
+
if (request === null)
|
|
58
|
+
return state; // nothing to do
|
|
59
|
+
const newPieces = new Uint8Array(state.board.pieces);
|
|
60
|
+
const from = request.sourceSquare;
|
|
61
|
+
const to = request.destination.to;
|
|
62
|
+
const pieceCode = state.board.pieces[from];
|
|
63
|
+
assert(pieceCode === 1 /* PieceCode.WhitePawn */ || pieceCode === 9 /* PieceCode.BlackPawn */, 'Only pawn moves should be deferred UI move requests at this time');
|
|
64
|
+
newPieces[to] = pieceCode;
|
|
65
|
+
newPieces[from] = 0 /* PieceCode.Empty */;
|
|
66
|
+
const newBoard = {
|
|
67
|
+
...state.board,
|
|
68
|
+
pieces: newPieces
|
|
69
|
+
};
|
|
70
|
+
const newLastMove = {
|
|
71
|
+
from,
|
|
72
|
+
to,
|
|
73
|
+
piece: pieceCode
|
|
74
|
+
};
|
|
75
|
+
const newChange = {
|
|
76
|
+
deferredUIMoveRequest: null,
|
|
77
|
+
lastMove: newLastMove
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
...state,
|
|
81
|
+
board: newBoard,
|
|
82
|
+
change: newChange
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* When a promotion was already auto-resolved/auto-promoted (no deferredUIMoveRequest but
|
|
87
|
+
* lastMove.promotedTo is set), the current board already contains the promoted
|
|
88
|
+
* piece (e.g. queen) on the target square. For animation planning we
|
|
89
|
+
* temporarily replace it with the original piece (pawn) so that the greedy
|
|
90
|
+
* matching can build a proper move track from→to instead of separate fades.
|
|
91
|
+
*
|
|
92
|
+
* After the animation finishes the promoted piece will "snap" into view on
|
|
93
|
+
* the next render frame.
|
|
94
|
+
*/
|
|
95
|
+
function buildPromotionEffectiveCurrent(state) {
|
|
96
|
+
const lastMove = state.change.lastMove;
|
|
97
|
+
if (state.change.deferredUIMoveRequest !== null ||
|
|
98
|
+
lastMove === null ||
|
|
99
|
+
lastMove.promotedTo === undefined) {
|
|
100
|
+
return state; // not an auto-resolved/auto-promoted move — nothing to do
|
|
101
|
+
}
|
|
102
|
+
const newPieces = new Uint8Array(state.board.pieces);
|
|
103
|
+
newPieces[lastMove.to] = lastMove.piece;
|
|
104
|
+
const newBoard = {
|
|
105
|
+
...state.board,
|
|
106
|
+
pieces: newPieces
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
...state,
|
|
110
|
+
board: newBoard
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Collect suppressed squares purely from the given tracks.
|
|
115
|
+
* For move tracks both endpoints are included; for fade/static the single square.
|
|
116
|
+
*/
|
|
117
|
+
function collectSuppressedSquaresFromTracks(tracks) {
|
|
16
118
|
const result = new Set();
|
|
17
119
|
for (const track of tracks) {
|
|
18
120
|
if (track.effect === 'move') {
|
|
@@ -25,14 +127,20 @@ export function collectSuppressedSquares(tracks) {
|
|
|
25
127
|
}
|
|
26
128
|
return result;
|
|
27
129
|
}
|
|
28
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Low-level track calculation.
|
|
132
|
+
*
|
|
133
|
+
* Compares two board snapshots (already derived / effective), applies the
|
|
134
|
+
* provided exclude spec, and returns the resulting animation tracks.
|
|
135
|
+
*/
|
|
136
|
+
function calculateTracks(prevBoard, currBoard, exclude) {
|
|
29
137
|
const tracks = [];
|
|
30
138
|
let nextId = 0;
|
|
31
139
|
const removed = [];
|
|
32
140
|
const added = [];
|
|
33
141
|
for (let sq = 0; sq < SQUARE_COUNT; sq++) {
|
|
34
|
-
const c1 =
|
|
35
|
-
const c2 =
|
|
142
|
+
const c1 = prevBoard.pieces[sq];
|
|
143
|
+
const c2 = currBoard.pieces[sq];
|
|
36
144
|
if (c1 === c2)
|
|
37
145
|
continue;
|
|
38
146
|
if (isNonEmptyPieceCode(c1))
|
|
@@ -43,29 +151,29 @@ export function calculateAnimationTracks(pos1, pos2, options) {
|
|
|
43
151
|
// Step 2: greedy min-distance matching of same-code pairs → move tracks
|
|
44
152
|
const removedMatched = new Uint8Array(removed.length);
|
|
45
153
|
const addedMatched = new Uint8Array(added.length);
|
|
46
|
-
// toSq → code of the piece that moved there (used for static detection)
|
|
47
|
-
const movedToSqCode = new Map();
|
|
48
154
|
const candidates = [];
|
|
49
155
|
for (let ri = 0; ri < removed.length; ri++) {
|
|
50
156
|
for (let ai = 0; ai < added.length; ai++) {
|
|
51
157
|
if (removed[ri].pieceCode !== added[ai].pieceCode)
|
|
52
158
|
continue;
|
|
53
|
-
candidates.push({
|
|
159
|
+
candidates.push({
|
|
160
|
+
dist: SQUARE_DIST[removed[ri].sq * SQUARE_COUNT + added[ai].sq],
|
|
161
|
+
ri,
|
|
162
|
+
ai
|
|
163
|
+
});
|
|
54
164
|
}
|
|
55
165
|
}
|
|
56
166
|
candidates.sort((a, b) => a.dist - b.dist);
|
|
57
|
-
const excl = options?.exclude;
|
|
58
|
-
const preparedExcl = prepareExclude(excl);
|
|
59
167
|
for (const { ri, ai } of candidates) {
|
|
60
168
|
if (removedMatched[ri] || addedMatched[ai])
|
|
61
169
|
continue;
|
|
62
170
|
removedMatched[ri] = 1;
|
|
63
171
|
addedMatched[ai] = 1;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
//
|
|
172
|
+
// Check if this move pair is excluded (e.g. lifted-piece drop)
|
|
173
|
+
const fromSet = exclude.move.get(removed[ri].sq);
|
|
174
|
+
if (fromSet && fromSet.has(added[ai].sq)) {
|
|
175
|
+
// Suppress the move track but keep both entries matched so they
|
|
176
|
+
// don't turn into fades.
|
|
69
177
|
continue;
|
|
70
178
|
}
|
|
71
179
|
tracks.push({
|
|
@@ -80,9 +188,8 @@ export function calculateAnimationTracks(pos1, pos2, options) {
|
|
|
80
188
|
for (let ai = 0; ai < added.length; ai++) {
|
|
81
189
|
if (addedMatched[ai])
|
|
82
190
|
continue;
|
|
83
|
-
if (
|
|
191
|
+
if (exclude.square.has(added[ai].sq))
|
|
84
192
|
continue;
|
|
85
|
-
}
|
|
86
193
|
tracks.push({
|
|
87
194
|
id: nextId++,
|
|
88
195
|
pieceCode: added[ai].pieceCode,
|
|
@@ -90,39 +197,51 @@ export function calculateAnimationTracks(pos1, pos2, options) {
|
|
|
90
197
|
effect: 'fade-in'
|
|
91
198
|
});
|
|
92
199
|
}
|
|
93
|
-
// Step 4: unmatched removed → fade-out
|
|
200
|
+
// Step 4: unmatched removed → fade-out
|
|
94
201
|
for (let ri = 0; ri < removed.length; ri++) {
|
|
95
202
|
if (removedMatched[ri])
|
|
96
203
|
continue;
|
|
97
|
-
if (
|
|
204
|
+
if (exclude.square.has(removed[ri].sq))
|
|
98
205
|
continue;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
tracks.push({ id: nextId++, pieceCode, sq, effect: 'fade-out' });
|
|
206
|
+
tracks.push({
|
|
207
|
+
id: nextId++,
|
|
208
|
+
pieceCode: removed[ri].pieceCode,
|
|
209
|
+
sq: removed[ri].sq,
|
|
210
|
+
effect: 'fade-out'
|
|
211
|
+
});
|
|
106
212
|
}
|
|
107
213
|
return tracks;
|
|
108
214
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// Public API — single orchestrator
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
/**
|
|
219
|
+
* Plan animation tracks and suppressed squares for a state transition.
|
|
220
|
+
*
|
|
221
|
+
* This is the single entry point for animation planning. It:
|
|
222
|
+
* 1. Normalizes both snapshots (incorporates deferredUIMoveRequest).
|
|
223
|
+
* 2. Detects lifted-piece-drag drop completion and builds an internal exclude.
|
|
224
|
+
* 3. Computes tracks via greedy min-distance matching.
|
|
225
|
+
* 4. Assembles the full suppressedSquares set (track-derived + excluded drop endpoints).
|
|
226
|
+
*/
|
|
227
|
+
export function calculateAnimationPlan(input) {
|
|
228
|
+
// 1) Normalize snapshots to account for deferredUIMoveRequest
|
|
229
|
+
const effectivePrevious = buildEffectiveAnimationPlanningSnapshot(input.previous);
|
|
230
|
+
const effectiveCurrent = buildEffectiveAnimationPlanningSnapshot(input.current);
|
|
231
|
+
// 2) Detect lifted-piece drop and prepare exclude spec
|
|
232
|
+
const droppedMove = detectLiftedPieceDrop(effectivePrevious, effectiveCurrent);
|
|
233
|
+
const exclude = droppedMove !== null ? buildExcludeForDrop(droppedMove) : EMPTY_EXCLUDE;
|
|
234
|
+
// 3) Normalize current for auto-resolved/auto-promoted move (pawn→queen on target square)
|
|
235
|
+
const planningCurrent = buildPromotionEffectiveCurrent(effectiveCurrent);
|
|
236
|
+
// 4) Calculate tracks
|
|
237
|
+
const tracks = calculateTracks(effectivePrevious.board, planningCurrent.board, exclude);
|
|
238
|
+
// 5) Build suppressedSquares: track-derived + excluded drop endpoints
|
|
239
|
+
const suppressed = collectSuppressedSquaresFromTracks(tracks);
|
|
240
|
+
if (droppedMove !== null) {
|
|
241
|
+
// The dropped move was intentionally suppressed (no move track emitted),
|
|
242
|
+
// but the base render must still hide both endpoints.
|
|
243
|
+
suppressed.add(droppedMove.from);
|
|
244
|
+
suppressed.add(droppedMove.to);
|
|
126
245
|
}
|
|
127
|
-
return
|
|
246
|
+
return { tracks, suppressedSquares: suppressed };
|
|
128
247
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { PieceUrls } from '../../extensions/first-party/main-renderer/types/internal';
|
|
2
|
-
import type {
|
|
3
|
-
import type { AnimationTrackFade } from '../types';
|
|
4
|
-
import type { PreparedFadeNode } from './types';
|
|
5
|
-
export declare function prepareFadeTrack(track: AnimationTrackFade, geometry:
|
|
1
|
+
import type { PieceUrls } from '../../extensions/first-party/main-renderer/types/internal.js';
|
|
2
|
+
import type { SceneRenderGeometry } from '../../layout/geometry/types.js';
|
|
3
|
+
import type { AnimationTrackFade } from '../types.js';
|
|
4
|
+
import type { PreparedFadeNode } from './types.js';
|
|
5
|
+
export declare function prepareFadeTrack(track: AnimationTrackFade, geometry: SceneRenderGeometry, pieceUrls: PieceUrls, layer: SVGElement): PreparedFadeNode;
|
|
6
6
|
export declare function renderFadeTrack(node: PreparedFadeNode, progress: number): void;
|
|
7
7
|
export declare function cleanFadeTrack(node: PreparedFadeNode): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createSvgElement, updateElementAttributes } from '../../render/svg/helpers';
|
|
1
|
+
import { createSvgElement, updateElementAttributes } from '../../render/svg/helpers.js';
|
|
2
2
|
export function prepareFadeTrack(track, geometry, pieceUrls, layer) {
|
|
3
|
-
const r = geometry.
|
|
3
|
+
const r = geometry.getSquareRect(track.sq);
|
|
4
4
|
const url = pieceUrls[track.pieceCode];
|
|
5
5
|
const initialOpacity = track.effect === 'fade-in' ? '0' : '1';
|
|
6
6
|
const root = createSvgElement(layer, 'image', {
|
|
@@ -9,8 +9,8 @@ export function prepareFadeTrack(track, geometry, pieceUrls, layer) {
|
|
|
9
9
|
href: url,
|
|
10
10
|
x: r.x.toString(),
|
|
11
11
|
y: r.y.toString(),
|
|
12
|
-
width: r.
|
|
13
|
-
height: r.
|
|
12
|
+
width: r.width.toString(),
|
|
13
|
+
height: r.height.toString(),
|
|
14
14
|
opacity: initialOpacity
|
|
15
15
|
});
|
|
16
16
|
return { ...track, root };
|