@mirasen/chessboard 1.1.5 → 1.2.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/CHANGELOG.md +45 -0
- package/README.md +61 -13
- package/dist/animation/render/fade.d.ts +2 -3
- package/dist/animation/render/fade.js +6 -6
- package/dist/animation/render/move.d.ts +2 -3
- package/dist/animation/render/move.js +6 -6
- package/dist/animation/render/plan.d.ts +3 -4
- package/dist/animation/render/plan.js +5 -5
- package/dist/animation/render/static.d.ts +2 -3
- package/dist/animation/render/static.js +4 -4
- package/dist/animation/render/types.d.ts +10 -4
- package/dist/extensions/build/index.d.ts +1 -2
- package/dist/extensions/build/index.js +1 -1
- package/dist/extensions/factory/main.js +11 -7
- package/dist/extensions/factory/runtime.js +24 -1
- package/dist/extensions/first-party/active-target/factory.js +18 -11
- package/dist/extensions/first-party/annotations/api.d.ts +16 -0
- package/dist/extensions/first-party/annotations/api.js +79 -0
- package/dist/extensions/first-party/annotations/committed.d.ts +3 -0
- package/dist/extensions/first-party/annotations/committed.js +11 -0
- package/dist/extensions/first-party/annotations/constants.d.ts +3 -0
- package/dist/extensions/first-party/annotations/constants.js +54 -0
- package/dist/extensions/first-party/annotations/denormalize.d.ts +4 -0
- package/dist/extensions/first-party/annotations/denormalize.js +22 -0
- package/dist/extensions/first-party/annotations/factory.d.ts +3 -0
- package/dist/extensions/first-party/annotations/factory.js +143 -0
- package/dist/extensions/first-party/annotations/interaction.d.ts +8 -0
- package/dist/extensions/first-party/annotations/interaction.js +129 -0
- package/dist/extensions/first-party/annotations/invalidation.d.ts +3 -0
- package/dist/extensions/first-party/annotations/invalidation.js +7 -0
- package/dist/extensions/first-party/annotations/normalize.d.ts +12 -0
- package/dist/extensions/first-party/annotations/normalize.js +54 -0
- package/dist/extensions/first-party/annotations/render/committed.d.ts +3 -0
- package/dist/extensions/first-party/annotations/render/committed.js +123 -0
- package/dist/extensions/first-party/annotations/render/helpers/arrows.d.ts +33 -0
- package/dist/extensions/first-party/annotations/render/helpers/arrows.js +93 -0
- package/dist/extensions/first-party/annotations/render/helpers/circles.d.ts +18 -0
- package/dist/extensions/first-party/annotations/render/helpers/circles.js +30 -0
- package/dist/extensions/first-party/annotations/render/preview.d.ts +3 -0
- package/dist/extensions/first-party/annotations/render/preview.js +96 -0
- package/dist/extensions/first-party/annotations/types/internal.d.ts +77 -0
- package/dist/extensions/first-party/annotations/types/internal.js +1 -0
- package/dist/extensions/first-party/annotations/types/main.d.ts +40 -0
- package/dist/extensions/first-party/annotations/types/main.js +6 -0
- package/dist/extensions/first-party/annotations/types/public.d.ts +48 -0
- package/dist/extensions/first-party/annotations/types/public.js +1 -0
- package/dist/extensions/first-party/annotations/update.d.ts +3 -0
- package/dist/extensions/first-party/annotations/update.js +45 -0
- package/dist/extensions/first-party/auto-promote/factory.js +6 -6
- package/dist/extensions/first-party/board-events/factory.js +6 -6
- package/dist/extensions/first-party/common/helpers.d.ts +2 -1
- package/dist/extensions/first-party/common/helpers.js +6 -5
- package/dist/extensions/first-party/common/types.d.ts +2 -0
- package/dist/extensions/first-party/last-move/factory.js +9 -9
- package/dist/extensions/first-party/legal-moves/factory.js +8 -8
- package/dist/extensions/first-party/main-renderer/animation/factory.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/animation/factory.js +4 -4
- package/dist/extensions/first-party/main-renderer/animation/render.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/animation/render.js +2 -2
- package/dist/extensions/first-party/main-renderer/animation/types.d.ts +3 -3
- package/dist/extensions/first-party/main-renderer/board/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/board/render.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/board/render.js +4 -4
- package/dist/extensions/first-party/main-renderer/board/types.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/coordinates/factory.js +2 -2
- package/dist/extensions/first-party/main-renderer/coordinates/render.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/coordinates/render.js +5 -5
- package/dist/extensions/first-party/main-renderer/coordinates/types.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/drag/factory.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/drag/factory.js +11 -8
- package/dist/extensions/first-party/main-renderer/drag/render.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/drag/render.js +7 -6
- package/dist/extensions/first-party/main-renderer/drag/types.d.ts +6 -5
- package/dist/extensions/first-party/main-renderer/drag/update.js +2 -2
- package/dist/extensions/first-party/main-renderer/factory.js +9 -5
- package/dist/extensions/first-party/main-renderer/piece-symbols.d.ts +19 -0
- package/dist/extensions/first-party/main-renderer/piece-symbols.js +45 -0
- package/dist/extensions/first-party/main-renderer/pieces/factory.d.ts +2 -2
- package/dist/extensions/first-party/main-renderer/pieces/factory.js +4 -4
- package/dist/extensions/first-party/main-renderer/pieces/render.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/pieces/render.js +8 -8
- package/dist/extensions/first-party/main-renderer/pieces/types.d.ts +4 -4
- package/dist/extensions/first-party/main-renderer/types/extension.d.ts +1 -1
- package/dist/extensions/first-party/main-renderer/types/extension.js +8 -1
- package/dist/extensions/first-party/main-renderer/types/instance.d.ts +2 -0
- package/dist/extensions/first-party/promotion/factory.js +10 -10
- package/dist/extensions/first-party/selected-square/factory.js +8 -8
- package/dist/extensions/first-party/watermark/factory.js +8 -8
- package/dist/extensions/types/basic/events.d.ts +32 -3
- package/dist/extensions/types/basic/events.js +2 -1
- package/dist/extensions/types/basic/mount.d.ts +5 -2
- package/dist/extensions/types/basic/mount.js +0 -2
- package/dist/extensions/types/basic/transient-visuals.d.ts +1 -1
- package/dist/extensions/types/context/animation.d.ts +3 -3
- package/dist/extensions/types/context/events.d.ts +2 -1
- package/dist/extensions/types/context/update.d.ts +6 -7
- package/dist/extensions/types/extension.d.ts +3 -0
- package/dist/extensions/types/main.d.ts +1 -0
- package/dist/extensions/types/surface/commands.d.ts +1 -1
- package/dist/extensions/types/surface/main.d.ts +6 -4
- package/dist/extensions/types/wrapper.d.ts +3 -1
- package/dist/extensions/types/wrapper.js +6 -2
- package/dist/extensions/update.js +6 -10
- package/dist/index.d.ts +1 -1
- package/dist/render/mount.js +3 -3
- package/dist/render/rendering/state.js +2 -2
- package/dist/render/svg/factory.js +40 -25
- package/dist/render/svg/helpers.d.ts +8 -4
- package/dist/render/svg/helpers.js +27 -12
- package/dist/render/svg/ids.d.ts +6 -0
- package/dist/render/svg/ids.js +11 -0
- package/dist/render/types.d.ts +4 -3
- package/dist/render/types.js +2 -1
- package/dist/runtime/factory/input.d.ts +3 -1
- package/dist/runtime/factory/input.js +11 -2
- package/dist/runtime/factory/main.js +10 -4
- package/dist/runtime/input/adapter/event.js +2 -2
- package/dist/runtime/input/adapter/pointer.d.ts +2 -2
- package/dist/runtime/input/controller/factory.d.ts +1 -1
- package/dist/runtime/input/controller/factory.js +35 -15
- package/dist/runtime/input/controller/helpers.d.ts +1 -1
- package/dist/runtime/input/controller/interaction.d.ts +3 -0
- package/dist/runtime/input/controller/interaction.js +14 -0
- package/dist/runtime/input/controller/pointer.d.ts +6 -6
- package/dist/runtime/input/controller/pointer.js +53 -27
- package/dist/runtime/input/controller/transient-visuals.d.ts +2 -3
- package/dist/runtime/input/controller/types.d.ts +6 -5
- package/dist/runtime/types/main.d.ts +1 -1
- package/dist/wrapper/factory.js +2 -7
- package/dist/wrapper/types.d.ts +3 -11
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @mirasen/chessboard
|
|
2
2
|
|
|
3
|
+
## 1.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7f5649f: Update README and documentation entry points for the built-in annotations release.
|
|
8
|
+
|
|
9
|
+
The README now describes annotations as part of the default first-party extension baseline, adds a short annotations section, updates the explicit extension-list example, and links to the new documentation hub.
|
|
10
|
+
|
|
11
|
+
## 1.2.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 101903a: Add board annotations with square markers, free arrows, live previews, and programmatic annotation APIs.
|
|
16
|
+
- 101903a: Refines extension/rendering internals before third-party extension APIs stabilize.
|
|
17
|
+
|
|
18
|
+
Breaking for custom extension authors:
|
|
19
|
+
- SVG helper exports were simplified around generic SVG helpers: `createSvgElement`, `createSvgRootElement`, `createSvgDefsElement`, and `clearSvgElementChildren`.
|
|
20
|
+
- `defs` is now an extension-owned top-level `<defs>` slot under the root `<svg>`, instead of a shared `defs-root`.
|
|
21
|
+
- `extensionUnmountBase` now clears the extension-owned slot roots directly and no longer accepts an `extensionId`.
|
|
22
|
+
|
|
23
|
+
Board/runtime initialization is now element-first. Most consumers using direct container-based board creation should not need migration changes.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- 4ec620b: dependabot: directory '/', update @sveltejs/kit
|
|
28
|
+
- 4ec620b: dependabot: directory '/', update eslint
|
|
29
|
+
- 4ec620b: dependabot: directory '/', update globals
|
|
30
|
+
- 4ec620b: dependabot: directory '/', update svelte-check
|
|
31
|
+
- 49760cc: dependabot: directory '/', update @sveltejs/kit
|
|
32
|
+
- 49760cc: dependabot: directory '/', update @types/node
|
|
33
|
+
- 49760cc: dependabot: directory '/', update publint
|
|
34
|
+
- 49760cc: dependabot: directory '/', update svelte-check
|
|
35
|
+
- 49760cc: dependabot: directory '/', update typescript-eslint
|
|
36
|
+
- 559677e: dependabot: directory '/', update @eslint/compat
|
|
37
|
+
- 559677e: dependabot: directory '/', update publint
|
|
38
|
+
- 72a1480: dependabot: directory '/', update @playwright/test
|
|
39
|
+
- 72a1480: dependabot: directory '/', update @types/node
|
|
40
|
+
- 72a1480: dependabot: directory '/', update @vitest/browser-playwright
|
|
41
|
+
- 72a1480: dependabot: directory '/', update @vitest/coverage-istanbul
|
|
42
|
+
- 72a1480: dependabot: directory '/', update playwright
|
|
43
|
+
- 72a1480: dependabot: directory '/', update prettier-plugin-svelte
|
|
44
|
+
- 72a1480: dependabot: directory '/', update publint
|
|
45
|
+
- 72a1480: dependabot: directory '/', update typescript-eslint
|
|
46
|
+
- 72a1480: dependabot: directory '/', update vitest
|
|
47
|
+
|
|
3
48
|
## 1.1.5
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
A framework-agnostic TypeScript chessboard platform with real chess interaction built in and an extension-driven architecture.
|
|
10
10
|
|
|
11
|
-
## Try it live
|
|
11
|
+
## Try it live (including annotations)
|
|
12
12
|
|
|
13
13
|
- [Play a chess.js game](https://mirasen.io/chessboard/examples/chessjs.html)
|
|
14
14
|
- [Try the promotion flow](https://mirasen.io/chessboard/examples/promotion.html)
|
|
@@ -16,7 +16,7 @@ A framework-agnostic TypeScript chessboard platform with real chess interaction
|
|
|
16
16
|
|
|
17
17
|
## Using React?
|
|
18
18
|
|
|
19
|
-
Use [`@mirasen/react-chessboard`](https://
|
|
19
|
+
Use [`@mirasen/react-chessboard`](https://www.npmjs.com/package/@mirasen/react-chessboard) for a React component with the same built-in interaction, annotations, promotion, animation, and chess.js integration.
|
|
20
20
|
|
|
21
21
|
## Why this exists
|
|
22
22
|
|
|
@@ -36,7 +36,7 @@ This is not just a board renderer. It is a chessboard platform designed for real
|
|
|
36
36
|
|
|
37
37
|
## What you get out of the box
|
|
38
38
|
|
|
39
|
-
The default first-party extension baseline includes rendering, events, selection, active target feedback, legal move hints, last move feedback, promotion UI, and optional auto-promotion.
|
|
39
|
+
The default first-party extension baseline includes rendering, events, selection, active target feedback, legal move hints, last move feedback, annotations, promotion UI, and optional auto-promotion.
|
|
40
40
|
|
|
41
41
|
- `renderer` — the first-party rendering extension that validates the same extension architecture used for board features
|
|
42
42
|
- `events`
|
|
@@ -44,16 +44,17 @@ The default first-party extension baseline includes rendering, events, selection
|
|
|
44
44
|
- `activeTarget`
|
|
45
45
|
- `legalMoves`
|
|
46
46
|
- `lastMove`
|
|
47
|
+
- `annotations`
|
|
47
48
|
- `promotion`
|
|
48
49
|
- `autoPromote`
|
|
49
50
|
|
|
50
51
|
The package also includes `chess.js` adapter helpers for connecting legal destinations, UI moves, external moves, promotion, castling, and en passant without writing special-move glue code by hand.
|
|
51
52
|
|
|
52
|
-
That means the board already covers a meaningful baseline chess UX instead of stopping at “draw squares and pieces
|
|
53
|
+
That means the board already covers a meaningful baseline chess UX instead of stopping at “draw squares and pieces”: users can move pieces, see legal targets, promote naturally, animate state changes, and draw circles and arrows without rebuilding common board behavior in app code.
|
|
53
54
|
|
|
54
55
|
### Built-in chessboard behavior
|
|
55
56
|
|
|
56
|
-
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.
|
|
57
|
+
Mirasen Chessboard provides a complete modern interaction and visual baseline out of the box: selection, deselection, reselection, drag-to-move, release targeting, legal destinations, circles and arrows, promotion, auto-promotion, and state-diff animation.
|
|
57
58
|
|
|
58
59
|
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, castle, or return smoothly without app-level rendering glue code.
|
|
59
60
|
|
|
@@ -62,6 +63,7 @@ Rules and legality still belong to your game layer. Use the built-in `chess.js`
|
|
|
62
63
|
## Highlights
|
|
63
64
|
|
|
64
65
|
- Real built-in chess interaction
|
|
66
|
+
- Built-in circles and arrows with live add/remove previews
|
|
65
67
|
- **Easy game/rules integration** — connect your own game model, or use the built-in `chess.js` adapter
|
|
66
68
|
- Works on desktop and mobile out of the box, with pointer-based mouse and touch interaction
|
|
67
69
|
- State-diff animation beyond simple move events
|
|
@@ -104,7 +106,7 @@ board.setMovability({
|
|
|
104
106
|
|
|
105
107
|
### Connect to chess.js
|
|
106
108
|
|
|
107
|
-
`@mirasen/chessboard` owns board interaction, rendering, promotion UI, and animation.
|
|
109
|
+
`@mirasen/chessboard` owns board interaction, rendering, annotations, promotion UI, and animation.
|
|
108
110
|
Your game/rules layer owns legality and game state.
|
|
109
111
|
|
|
110
112
|
For `chess.js`, use the built-in adapter:
|
|
@@ -193,7 +195,7 @@ The adapter exposes three small conversion helpers:
|
|
|
193
195
|
This keeps the boundary explicit:
|
|
194
196
|
|
|
195
197
|
- `chess.js` decides which moves are legal.
|
|
196
|
-
- The board handles interaction, legal targets, promotion UI, castling/en-passant board updates, and animation.
|
|
198
|
+
- The board handles interaction, legal targets, annotations, promotion UI, castling/en-passant board updates, and animation.
|
|
197
199
|
- User moves flow from the board into `chess.js`.
|
|
198
200
|
- External moves flow from `chess.js` back into the board.
|
|
199
201
|
|
|
@@ -237,6 +239,16 @@ const board = createBoard({
|
|
|
237
239
|
board.extensions.autoPromote.toQueen = true;
|
|
238
240
|
```
|
|
239
241
|
|
|
242
|
+
### Annotations
|
|
243
|
+
|
|
244
|
+
The default extension baseline includes built-in board annotations.
|
|
245
|
+
|
|
246
|
+
Users can draw circles and arrows directly on the board. Desktop users can right-click to annotate by default, while touch or mobile-style UIs can switch annotation drawing to the primary pointer button with `drawButton`.
|
|
247
|
+
|
|
248
|
+
Annotation gestures show live previews before commit. Repeating the same-color circle or arrow removes it, with a low-opacity remove preview so users can see that release will delete the existing annotation.
|
|
249
|
+
|
|
250
|
+
Color selection can come from keyboard modifiers, or be forced through `drawModifier` for on-screen controls.
|
|
251
|
+
|
|
240
252
|
### Movability modes
|
|
241
253
|
|
|
242
254
|
Movability controls how the board accepts user-initiated moves.
|
|
@@ -251,14 +263,44 @@ Most users can rely on the default first-party extension baseline. Use an explic
|
|
|
251
263
|
|
|
252
264
|
```ts
|
|
253
265
|
import { createBoard, type Chessboard, type ChessboardExtensionInput } from '@mirasen/chessboard';
|
|
266
|
+
import { builtInExtensionFactoryMap } from '@mirasen/chessboard/extensions';
|
|
267
|
+
|
|
268
|
+
const pieceUrls = {
|
|
269
|
+
wK: '/pieces/wK.svg',
|
|
270
|
+
wQ: '/pieces/wQ.svg',
|
|
271
|
+
wR: '/pieces/wR.svg',
|
|
272
|
+
wB: '/pieces/wB.svg',
|
|
273
|
+
wN: '/pieces/wN.svg',
|
|
274
|
+
wP: '/pieces/wP.svg',
|
|
275
|
+
bK: '/pieces/bK.svg',
|
|
276
|
+
bQ: '/pieces/bQ.svg',
|
|
277
|
+
bR: '/pieces/bR.svg',
|
|
278
|
+
bB: '/pieces/bB.svg',
|
|
279
|
+
bN: '/pieces/bN.svg',
|
|
280
|
+
bP: '/pieces/bP.svg'
|
|
281
|
+
};
|
|
254
282
|
|
|
255
283
|
const extensionList = [
|
|
256
|
-
// Always add renderer first, otherwise nothing will be rendered
|
|
257
|
-
|
|
284
|
+
// Always add renderer first, otherwise nothing will be rendered.
|
|
285
|
+
{
|
|
286
|
+
builtin: 'renderer',
|
|
287
|
+
options: {
|
|
288
|
+
pieceUrls,
|
|
289
|
+
colors: {
|
|
290
|
+
board: {
|
|
291
|
+
light: '#d7dde5',
|
|
292
|
+
dark: '#707a8a'
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
},
|
|
258
297
|
'lastMove',
|
|
259
|
-
|
|
298
|
+
'annotations',
|
|
299
|
+
// Keep autoPromote before promotion, otherwise promotion may defer the move first.
|
|
260
300
|
'autoPromote',
|
|
261
|
-
|
|
301
|
+
builtInExtensionFactoryMap.promotion({
|
|
302
|
+
pieceUrls
|
|
303
|
+
})
|
|
262
304
|
// customExtensionDefinition
|
|
263
305
|
] as const satisfies readonly ChessboardExtensionInput[];
|
|
264
306
|
let board: Chessboard<typeof extensionList> | null = null;
|
|
@@ -275,12 +317,18 @@ board = createBoard({
|
|
|
275
317
|
});
|
|
276
318
|
```
|
|
277
319
|
|
|
320
|
+
Configured built-in extensions can be provided either as declarative `{ builtin, options }` objects or through the built-in extension factory map. If you use custom piece assets, pass the same `pieceUrls` map to renderer and promotion when you want the board and promotion UI to use the same piece set.
|
|
321
|
+
|
|
278
322
|
### Default visual identity
|
|
279
323
|
|
|
280
324
|
The default first-party extension baseline includes a subtle Mirasen board watermark.
|
|
281
325
|
|
|
282
326
|
If you want full control over the visual baseline, use an explicit extension list and omit the `watermark` extension.
|
|
283
327
|
|
|
328
|
+
## Documentation
|
|
329
|
+
|
|
330
|
+
See [Documentation](./documentation.md) for the documentation hub.
|
|
331
|
+
|
|
284
332
|
## Architecture
|
|
285
333
|
|
|
286
334
|
`@mirasen/chessboard` is built around explicit boundaries:
|
|
@@ -304,7 +352,7 @@ A board that only renders pieces and leaves everything else to app code often fo
|
|
|
304
352
|
|
|
305
353
|
A board that handles everything internally without clean boundaries becomes difficult to evolve, customize, or extend.
|
|
306
354
|
|
|
307
|
-
### Opt out,
|
|
355
|
+
### Opt out, don’t build up, focus on your app
|
|
308
356
|
|
|
309
357
|
`@mirasen/chessboard` aims for a middle path:
|
|
310
358
|
|
|
@@ -312,7 +360,7 @@ A board that handles everything internally without clean boundaries becomes diff
|
|
|
312
360
|
- clean internal architecture
|
|
313
361
|
- extension-driven feature growth
|
|
314
362
|
|
|
315
|
-
Common chessboard behavior is included by default: rendering, interaction, selection, legal target feedback, promotion, and animation. You start from a working interaction baseline
|
|
363
|
+
Common chessboard behavior is included by default: rendering, interaction, selection, legal target feedback, annotations, promotion, and animation. You start from a working interaction baseline, remove or replace extensions only when you need something different, and keep your own code focused on your application domain.
|
|
316
364
|
|
|
317
365
|
## Project direction
|
|
318
366
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { PieceUrls } from '../../extensions/first-party/main-renderer/types/internal.js';
|
|
2
1
|
import type { SceneRenderGeometry } from '../../layout/geometry/types.js';
|
|
3
2
|
import type { AnimationTrackFade } from '../types.js';
|
|
4
|
-
import type { PreparedFadeNode } from './types.js';
|
|
5
|
-
export declare function prepareFadeTrack(track: AnimationTrackFade, geometry: SceneRenderGeometry,
|
|
3
|
+
import type { PieceHrefResolver, PreparedFadeNode } from './types.js';
|
|
4
|
+
export declare function prepareFadeTrack(track: AnimationTrackFade, geometry: SceneRenderGeometry, resolveHref: PieceHrefResolver, slot: SVGGElement): PreparedFadeNode;
|
|
6
5
|
export declare function renderFadeTrack(node: PreparedFadeNode, progress: number): void;
|
|
7
6
|
export declare function cleanFadeTrack(node: PreparedFadeNode): void;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { createSvgElement,
|
|
2
|
-
export function prepareFadeTrack(track, geometry,
|
|
1
|
+
import { createSvgElement, updateSvgElementAttributes } from '../../render/svg/helpers.js';
|
|
2
|
+
export function prepareFadeTrack(track, geometry, resolveHref, slot) {
|
|
3
3
|
const r = geometry.getSquareRect(track.sq);
|
|
4
|
-
const
|
|
4
|
+
const href = resolveHref(track.pieceCode);
|
|
5
5
|
const initialOpacity = track.effect === 'fade-in' ? '0' : '1';
|
|
6
|
-
const root = createSvgElement(
|
|
6
|
+
const root = createSvgElement(slot, 'use', {
|
|
7
7
|
'data-chessboard-id': `animation-fade-${track.id}`,
|
|
8
8
|
'data-animation-effect': track.effect,
|
|
9
|
-
href
|
|
9
|
+
href,
|
|
10
10
|
x: r.x.toString(),
|
|
11
11
|
y: r.y.toString(),
|
|
12
12
|
width: r.width.toString(),
|
|
@@ -17,7 +17,7 @@ export function prepareFadeTrack(track, geometry, pieceUrls, layer) {
|
|
|
17
17
|
}
|
|
18
18
|
export function renderFadeTrack(node, progress) {
|
|
19
19
|
const opacity = node.effect === 'fade-in' ? progress : 1 - progress;
|
|
20
|
-
|
|
20
|
+
updateSvgElementAttributes(node.root, { opacity: opacity.toString() });
|
|
21
21
|
}
|
|
22
22
|
export function cleanFadeTrack(node) {
|
|
23
23
|
node.root.remove();
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { PieceUrls } from '../../extensions/first-party/main-renderer/types/internal.js';
|
|
2
1
|
import type { SceneRenderGeometry } from '../../layout/geometry/types.js';
|
|
3
2
|
import type { AnimationTrackMove } from '../types.js';
|
|
4
|
-
import type { PreparedMoveNode } from './types.js';
|
|
5
|
-
export declare function prepareMoveTrack(track: AnimationTrackMove, geometry: SceneRenderGeometry,
|
|
3
|
+
import type { PieceHrefResolver, PreparedMoveNode } from './types.js';
|
|
4
|
+
export declare function prepareMoveTrack(track: AnimationTrackMove, geometry: SceneRenderGeometry, resolveHref: PieceHrefResolver, slot: SVGGElement): PreparedMoveNode;
|
|
6
5
|
export declare function renderMoveTrack(node: PreparedMoveNode, geometry: SceneRenderGeometry, progress: number): void;
|
|
7
6
|
export declare function cleanMoveTrack(node: PreparedMoveNode): void;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { createSvgElement,
|
|
2
|
-
export function prepareMoveTrack(track, geometry,
|
|
1
|
+
import { createSvgElement, updateSvgElementAttributes } from '../../render/svg/helpers.js';
|
|
2
|
+
export function prepareMoveTrack(track, geometry, resolveHref, slot) {
|
|
3
3
|
const r = geometry.getSquareRect(track.fromSq);
|
|
4
|
-
const
|
|
5
|
-
const root = createSvgElement(
|
|
4
|
+
const href = resolveHref(track.pieceCode);
|
|
5
|
+
const root = createSvgElement(slot, 'use', {
|
|
6
6
|
'data-chessboard-id': `animation-move-${track.id}`,
|
|
7
7
|
'data-animation-effect': 'move',
|
|
8
|
-
href
|
|
8
|
+
href,
|
|
9
9
|
x: r.x.toString(),
|
|
10
10
|
y: r.y.toString(),
|
|
11
11
|
width: r.width.toString(),
|
|
@@ -18,7 +18,7 @@ export function renderMoveTrack(node, geometry, progress) {
|
|
|
18
18
|
const to = geometry.getSquareRect(node.toSq);
|
|
19
19
|
const x = from.x + (to.x - from.x) * progress;
|
|
20
20
|
const y = from.y + (to.y - from.y) * progress;
|
|
21
|
-
|
|
21
|
+
updateSvgElementAttributes(node.root, {
|
|
22
22
|
x: x.toString(),
|
|
23
23
|
y: y.toString()
|
|
24
24
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type { PieceUrls } from '../../extensions/first-party/main-renderer/types/internal.js';
|
|
2
1
|
import type { SceneRenderGeometry } from '../../layout/geometry/types.js';
|
|
3
2
|
import type { AnimationPlan } from '../types.js';
|
|
4
|
-
import type { PreparedNodeMap } from './types.js';
|
|
3
|
+
import type { PieceHrefResolver, PreparedNodeMap } from './types.js';
|
|
5
4
|
/**
|
|
6
|
-
* Prepare all tracks in the plan — creates SVG nodes in `
|
|
5
|
+
* Prepare all tracks in the plan — creates SVG nodes in `slot` for each track.
|
|
7
6
|
* Returns a map keyed by track id for use in render/clean passes.
|
|
8
7
|
*/
|
|
9
|
-
export declare function prepareAnimationPlan(plan: AnimationPlan, geometry: SceneRenderGeometry,
|
|
8
|
+
export declare function prepareAnimationPlan(plan: AnimationPlan, geometry: SceneRenderGeometry, resolveHref: PieceHrefResolver, slot: SVGGElement): PreparedNodeMap;
|
|
10
9
|
export declare function renderAnimationPlan(nodes: PreparedNodeMap, geometry: SceneRenderGeometry, progress: number): void;
|
|
11
10
|
/**
|
|
12
11
|
* Clean up all track nodes — removes SVG elements from the DOM.
|
|
@@ -2,23 +2,23 @@ import { cleanFadeTrack, prepareFadeTrack, renderFadeTrack } from './fade.js';
|
|
|
2
2
|
import { cleanMoveTrack, prepareMoveTrack, renderMoveTrack } from './move.js';
|
|
3
3
|
import { cleanStaticTrack, prepareStaticTrack, renderStaticTrack } from './static.js';
|
|
4
4
|
/**
|
|
5
|
-
* Prepare all tracks in the plan — creates SVG nodes in `
|
|
5
|
+
* Prepare all tracks in the plan — creates SVG nodes in `slot` for each track.
|
|
6
6
|
* Returns a map keyed by track id for use in render/clean passes.
|
|
7
7
|
*/
|
|
8
|
-
export function prepareAnimationPlan(plan, geometry,
|
|
8
|
+
export function prepareAnimationPlan(plan, geometry, resolveHref, slot) {
|
|
9
9
|
const nodes = new Map();
|
|
10
10
|
for (const track of plan.tracks) {
|
|
11
11
|
let node;
|
|
12
12
|
switch (track.effect) {
|
|
13
13
|
case 'move':
|
|
14
|
-
node = prepareMoveTrack(track, geometry,
|
|
14
|
+
node = prepareMoveTrack(track, geometry, resolveHref, slot);
|
|
15
15
|
break;
|
|
16
16
|
case 'fade-in':
|
|
17
17
|
case 'fade-out':
|
|
18
|
-
node = prepareFadeTrack(track, geometry,
|
|
18
|
+
node = prepareFadeTrack(track, geometry, resolveHref, slot);
|
|
19
19
|
break;
|
|
20
20
|
case 'static':
|
|
21
|
-
node = prepareStaticTrack(track, geometry,
|
|
21
|
+
node = prepareStaticTrack(track, geometry, resolveHref, slot);
|
|
22
22
|
break;
|
|
23
23
|
default:
|
|
24
24
|
throw new RangeError(`Unsupported track effect: ${track}`);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { PieceUrls } from '../../extensions/first-party/main-renderer/types/internal.js';
|
|
2
1
|
import type { SceneRenderGeometry } from '../../layout/geometry/types.js';
|
|
3
2
|
import type { AnimationTrackStatic } from '../types.js';
|
|
4
|
-
import type { PreparedStaticNode } from './types.js';
|
|
5
|
-
export declare function prepareStaticTrack(track: AnimationTrackStatic, geometry: SceneRenderGeometry,
|
|
3
|
+
import type { PieceHrefResolver, PreparedStaticNode } from './types.js';
|
|
4
|
+
export declare function prepareStaticTrack(track: AnimationTrackStatic, geometry: SceneRenderGeometry, resolveHref: PieceHrefResolver, slot: SVGGElement): PreparedStaticNode;
|
|
6
5
|
export declare function renderStaticTrack(_node: PreparedStaticNode): void;
|
|
7
6
|
export declare function cleanStaticTrack(node: PreparedStaticNode): void;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createSvgElement } from '../../render/svg/helpers.js';
|
|
2
|
-
export function prepareStaticTrack(track, geometry,
|
|
2
|
+
export function prepareStaticTrack(track, geometry, resolveHref, slot) {
|
|
3
3
|
const r = geometry.getSquareRect(track.sq);
|
|
4
|
-
const
|
|
5
|
-
const root = createSvgElement(
|
|
4
|
+
const href = resolveHref(track.pieceCode);
|
|
5
|
+
const root = createSvgElement(slot, 'use', {
|
|
6
6
|
'data-chessboard-id': `animation-static-${track.id}`,
|
|
7
7
|
'data-animation-effect': 'static',
|
|
8
|
-
href
|
|
8
|
+
href,
|
|
9
9
|
x: r.x.toString(),
|
|
10
10
|
y: r.y.toString(),
|
|
11
11
|
width: r.width.toString(),
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import type { NonEmptyPieceCode } from '../../state/board/types/internal.js';
|
|
1
2
|
import type { AnimationTrack, AnimationTrackFade, AnimationTrackMove, AnimationTrackStatic } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* A function that resolves a piece code to a href string for <use> elements.
|
|
5
|
+
* Decoupled from main-renderer internals — any conforming callback works.
|
|
6
|
+
*/
|
|
7
|
+
export type PieceHrefResolver = (pieceCode: NonEmptyPieceCode) => string;
|
|
8
|
+
/** Prepared node for a move track — holds the SVG use element and its track. */
|
|
3
9
|
export interface PreparedMoveNode extends AnimationTrackMove {
|
|
4
|
-
root:
|
|
10
|
+
root: SVGUseElement;
|
|
5
11
|
}
|
|
6
12
|
/** Prepared node for a fade-in / fade-out track. */
|
|
7
13
|
export interface PreparedFadeNode extends AnimationTrackFade {
|
|
8
|
-
root:
|
|
14
|
+
root: SVGUseElement;
|
|
9
15
|
}
|
|
10
16
|
/** Prepared node for a static (captured piece) track. */
|
|
11
17
|
export interface PreparedStaticNode extends AnimationTrackStatic {
|
|
12
|
-
root:
|
|
18
|
+
root: SVGUseElement;
|
|
13
19
|
}
|
|
14
20
|
export type PreparedTrackNode = PreparedMoveNode | PreparedFadeNode | PreparedStaticNode;
|
|
15
21
|
/** Keyed map from track id → prepared node, for fast lookup during render/clean. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { cleanAnimationPlan, prepareAnimationPlan, renderAnimationPlan } from '../../animation/render/plan.js';
|
|
2
|
-
export {
|
|
2
|
+
export { clearSvgElementChildren, createSvgElement, createSvgRootElement, updateSvgElementAttributes } from '../../render/svg/helpers.js';
|
|
3
3
|
export type { RuntimeReadonlyMutationSession } from '../../runtime/mutation/types.js';
|
|
4
4
|
export { isNonEmptyPieceCode } from '../../state/board/check.js';
|
|
5
5
|
export { fileOf, rankOf, squareOf } from '../../state/board/coords.js';
|
|
@@ -7,7 +7,6 @@ export { denormalizeMove } from '../../state/board/denormalize.js';
|
|
|
7
7
|
export { normalizePiece } from '../../state/board/normalize.js';
|
|
8
8
|
export { fromPieceCode, toPieceCode } from '../../state/board/piece.js';
|
|
9
9
|
export type { ColorCode, EmptyPieceCode, NonEmptyPieceCode, PieceCode, RoleCode, RolePromotionCode, Square, SquareFile, SquareRank } from '../../state/board/types/internal.js';
|
|
10
|
-
export type { MoveOutput } from '../../state/board/types/output.js';
|
|
11
10
|
export type { MovabilityModeCode } from '../../state/interaction/types/internal.js';
|
|
12
11
|
export { extensionCreateInternalBase, extensionDestroyBase, extensionIsDestroyedBase, extensionIsMountedBase, extensionMountBase, extensionUnmountBase } from '../first-party/common/helpers.js';
|
|
13
12
|
export type { ExtensionInternalBase, OpaqueColor } from '../first-party/common/types.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { cleanAnimationPlan, prepareAnimationPlan, renderAnimationPlan } from '../../animation/render/plan.js';
|
|
2
|
-
export {
|
|
2
|
+
export { clearSvgElementChildren, createSvgElement, createSvgRootElement, updateSvgElementAttributes } from '../../render/svg/helpers.js';
|
|
3
3
|
export { isNonEmptyPieceCode } from '../../state/board/check.js';
|
|
4
4
|
export { fileOf, rankOf, squareOf } from '../../state/board/coords.js';
|
|
5
5
|
export { denormalizeMove } from '../../state/board/denormalize.js';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import assert from '@ktarmyshov/assert';
|
|
2
|
+
import { createSvgIdResolver } from '../../render/svg/ids.js';
|
|
2
3
|
import { createExtensionAnimationController } from '../animation/factory.js';
|
|
3
4
|
import { createExtensionInvalidationState } from '../invalidation/factory.js';
|
|
4
5
|
import { extensionSystemUpdateState, extensionSystemUpdateUIMoveRequest } from '../update.js';
|
|
5
6
|
import { createExtensionRuntimeSurface } from './runtime.js';
|
|
6
7
|
function createExtensionSystemInternal(getInternalState, options) {
|
|
8
|
+
const svgIds = createSvgIdResolver();
|
|
7
9
|
const extensions = new Map();
|
|
8
10
|
const extensionsArray = options.extensions ?? [];
|
|
9
11
|
for (const extensionDef of extensionsArray) {
|
|
@@ -14,7 +16,8 @@ function createExtensionSystemInternal(getInternalState, options) {
|
|
|
14
16
|
throw new Error(`Duplicate extension id found: ${extensionDef.id}`);
|
|
15
17
|
}
|
|
16
18
|
const instance = extensionDef.createInstance({
|
|
17
|
-
runtimeSurface: createExtensionRuntimeSurface(getInternalState, options.extensionRuntimeSurfaceCommands, options.extensionRuntimeSurfaceEvents, extensionDef)
|
|
19
|
+
runtimeSurface: createExtensionRuntimeSurface(getInternalState, options.extensionRuntimeSurfaceCommands, options.extensionRuntimeSurfaceEvents, extensionDef),
|
|
20
|
+
svgIds
|
|
18
21
|
});
|
|
19
22
|
const record = {
|
|
20
23
|
id: extensionDef.id,
|
|
@@ -93,23 +96,24 @@ export function createExtensionSystem(options) {
|
|
|
93
96
|
assert(extensionRec.instance.completeDrag, `Extension instance does not have a completeDrag handler for completing drag session with owner ${session.owner}`);
|
|
94
97
|
extensionRec.instance.completeDrag(session);
|
|
95
98
|
},
|
|
99
|
+
cancelDrag(session) {
|
|
100
|
+
const extensionRec = internalState.extensions.get(session.owner);
|
|
101
|
+
assert(extensionRec, `Extension record not found for cancelling drag session with owner ${session.owner}`);
|
|
102
|
+
extensionRec.instance.cancelDrag?.(session);
|
|
103
|
+
},
|
|
96
104
|
onUnmount() {
|
|
97
105
|
internalState.transientVisualsSubscribers.clear();
|
|
98
106
|
internalState.eventSubscribers.clear();
|
|
99
107
|
internalState.currentFrame = null;
|
|
100
108
|
for (const extensionRec of internalState.extensions.values()) {
|
|
101
|
-
extensionRec.invalidation.clear();
|
|
102
109
|
extensionRec.animation.clear();
|
|
103
110
|
}
|
|
104
111
|
},
|
|
105
112
|
onDestroy() {
|
|
106
|
-
// We assume that the
|
|
113
|
+
// We assume that the onUnmount was already called by runtime, but let's still validate
|
|
107
114
|
for (const extensionRec of internalState.extensions.values()) {
|
|
108
115
|
extensionRec.instance.destroy?.();
|
|
109
|
-
const onUnmountCalled =
|
|
110
|
-
extensionRec.invalidation.dirtyLayers === 0,
|
|
111
|
-
extensionRec.animation.getAll().length === 0
|
|
112
|
-
].every(Boolean);
|
|
116
|
+
const onUnmountCalled = extensionRec.animation.getAll().length === 0;
|
|
113
117
|
if (!onUnmountCalled) {
|
|
114
118
|
throw new Error(`Extension ${extensionRec.id} was not properly unmounted before destroy. Please make sure to call onUnmount before onDestroy to allow the extension to clean up its state and resources.`);
|
|
115
119
|
}
|
|
@@ -80,11 +80,34 @@ function createExtensionRuntimeSurfaceCommands(getInternalState, runtimeSurfaceC
|
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
|
+
function createExtensionRuntimeSurfaceInvalidation(getInternalState, extensionDef) {
|
|
84
|
+
function getInvalidation() {
|
|
85
|
+
const internalState = getInternalState();
|
|
86
|
+
const record = internalState.extensions.get(extensionDef.id);
|
|
87
|
+
assert(record, 'Extension record not found for invalidation');
|
|
88
|
+
return record.invalidation;
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
get dirtyLayers() {
|
|
92
|
+
return getInvalidation().dirtyLayers;
|
|
93
|
+
},
|
|
94
|
+
markDirty(layers) {
|
|
95
|
+
getInvalidation().markDirty(layers);
|
|
96
|
+
},
|
|
97
|
+
clearDirty(layers) {
|
|
98
|
+
getInvalidation().clearDirty(layers);
|
|
99
|
+
},
|
|
100
|
+
clear() {
|
|
101
|
+
getInvalidation().clear();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
83
105
|
export function createExtensionRuntimeSurface(getInternalState, commands, events, extensionDef) {
|
|
84
106
|
return {
|
|
85
107
|
commands: createExtensionRuntimeSurfaceCommands(getInternalState, commands, extensionDef),
|
|
86
108
|
animation: createExtensionRuntimeSurfaceAnimation(getInternalState, extensionDef),
|
|
87
109
|
transientVisuals: createExtensionRuntimeSurfaceTransientVisuals(getInternalState, extensionDef),
|
|
88
|
-
events: createExtensionRuntimeSurfaceEvents(getInternalState, events, extensionDef)
|
|
110
|
+
events: createExtensionRuntimeSurfaceEvents(getInternalState, events, extensionDef),
|
|
111
|
+
invalidation: createExtensionRuntimeSurfaceInvalidation(getInternalState, extensionDef)
|
|
89
112
|
};
|
|
90
113
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from '@ktarmyshov/assert';
|
|
2
2
|
import { toMerged } from 'es-toolkit';
|
|
3
|
-
import { createSvgElement,
|
|
3
|
+
import { createSvgElement, updateSvgElementAttributes } from '../../../render/svg/helpers.js';
|
|
4
4
|
import { isUpdateContextRenderable } from '../../types/context/update.js';
|
|
5
5
|
import { extensionCreateInternalBase, extensionDestroyBase, extensionMountBase, extensionUnmountBase } from '../common/helpers.js';
|
|
6
6
|
import { DEFAULT_CONFIG, EXTENSION_ID, EXTENSION_SLOTS } from './types.js';
|
|
@@ -9,14 +9,14 @@ export function createActiveTarget(config = {}) {
|
|
|
9
9
|
return {
|
|
10
10
|
id: EXTENSION_ID,
|
|
11
11
|
slots: EXTENSION_SLOTS,
|
|
12
|
-
createInstance() {
|
|
13
|
-
return createActiveTargetInstance(mergedConfig);
|
|
12
|
+
createInstance(options) {
|
|
13
|
+
return createActiveTargetInstance(options, mergedConfig);
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
-
function createActiveTargetInternal(config) {
|
|
17
|
+
function createActiveTargetInternal(options, config) {
|
|
18
18
|
return {
|
|
19
|
-
...extensionCreateInternalBase(),
|
|
19
|
+
...extensionCreateInternalBase(options),
|
|
20
20
|
svgRect: null,
|
|
21
21
|
svgCircle: null,
|
|
22
22
|
config
|
|
@@ -26,8 +26,8 @@ function extensionClean(state) {
|
|
|
26
26
|
state.svgRect = null;
|
|
27
27
|
state.svgCircle = null;
|
|
28
28
|
}
|
|
29
|
-
function createActiveTargetInstance(config) {
|
|
30
|
-
const internalState = createActiveTargetInternal(config);
|
|
29
|
+
function createActiveTargetInstance(options, config) {
|
|
30
|
+
const internalState = createActiveTargetInternal(options, config);
|
|
31
31
|
return {
|
|
32
32
|
id: EXTENSION_ID,
|
|
33
33
|
mount(env) {
|
|
@@ -38,7 +38,11 @@ function createActiveTargetInstance(config) {
|
|
|
38
38
|
causes: ['layout.refreshGeometry'],
|
|
39
39
|
// we really need almost all: setDrag, updateTarget, clear, clearActive, so just take all interaction mutations
|
|
40
40
|
prefixes: ['state.interaction.']
|
|
41
|
-
}) &&
|
|
41
|
+
}) &&
|
|
42
|
+
isUpdateContextRenderable(context) &&
|
|
43
|
+
(context.currentFrame.state.interaction.dragSession?.type === 'lifted-piece-drag' ||
|
|
44
|
+
context.currentFrame.state.interaction.dragSession?.type === 'release-targeting' ||
|
|
45
|
+
context.currentFrame.state.interaction.dragSession === null);
|
|
42
46
|
if (!needsRender) {
|
|
43
47
|
return; // no-op
|
|
44
48
|
}
|
|
@@ -48,7 +52,10 @@ function createActiveTargetInstance(config) {
|
|
|
48
52
|
assert(context.invalidation.dirtyLayers !== 0, 'Render should only be called when there are dirty layers');
|
|
49
53
|
// For AI: `release-targeting` is also represented by `dragSession`.
|
|
50
54
|
// `dragSession` here is the active interaction session, not only lifted-piece drag.
|
|
51
|
-
const square = context.currentFrame.state.interaction.dragSession?.
|
|
55
|
+
const square = context.currentFrame.state.interaction.dragSession?.type === 'lifted-piece-drag' ||
|
|
56
|
+
context.currentFrame.state.interaction.dragSession?.type === 'release-targeting'
|
|
57
|
+
? context.currentFrame.state.interaction.dragSession.targetSquare
|
|
58
|
+
: null;
|
|
52
59
|
if (square === undefined || square === null) {
|
|
53
60
|
if (internalState.svgRect !== null) {
|
|
54
61
|
internalState.svgRect.remove();
|
|
@@ -92,9 +99,9 @@ function createActiveTargetInstance(config) {
|
|
|
92
99
|
});
|
|
93
100
|
}
|
|
94
101
|
else {
|
|
95
|
-
|
|
102
|
+
updateSvgElementAttributes(internalState.svgRect, rectAttributes);
|
|
96
103
|
assert(internalState.svgCircle, 'svgCircle should be available if svgRect is available');
|
|
97
|
-
|
|
104
|
+
updateSvgElementAttributes(internalState.svgCircle, haloAttributes);
|
|
98
105
|
}
|
|
99
106
|
},
|
|
100
107
|
unmount() {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SquareString } from '../../../state/board/types/input.js';
|
|
2
|
+
import type { AnnotationsStateInternal } from './types/main.js';
|
|
3
|
+
import type { AnnotationsDrawModifier, ArrowAnnotationPublic, ArrowAnnotationValuePublic, CircleAnnotationPublic, CircleAnnotationValuePublic } from './types/public.js';
|
|
4
|
+
export declare function annotationsGetCircles(state: AnnotationsStateInternal): CircleAnnotationPublic[];
|
|
5
|
+
export declare function annotationsGetArrows(state: AnnotationsStateInternal): ArrowAnnotationPublic[];
|
|
6
|
+
export declare function annotationsSetCircles(state: AnnotationsStateInternal, circles: CircleAnnotationPublic[]): void;
|
|
7
|
+
export declare function annotationsSetArrows(state: AnnotationsStateInternal, arrows: ArrowAnnotationPublic[]): void;
|
|
8
|
+
export declare function annotationsSetCircle(state: AnnotationsStateInternal, square: SquareString, annotation: CircleAnnotationValuePublic | null): void;
|
|
9
|
+
export declare function annotationsSetArrow(state: AnnotationsStateInternal, from: SquareString, to: SquareString, annotation: ArrowAnnotationValuePublic | null): void;
|
|
10
|
+
export declare function annotationsClear(state: AnnotationsStateInternal): void;
|
|
11
|
+
export declare function annotationsSetClearOnCoreInteraction(state: AnnotationsStateInternal, value: boolean): void;
|
|
12
|
+
export declare function annotationsGetClearOnCoreInteraction(state: AnnotationsStateInternal): boolean;
|
|
13
|
+
export declare function annotationsSetDrawButton(state: AnnotationsStateInternal, value: number): void;
|
|
14
|
+
export declare function annotationsGetDrawButton(state: AnnotationsStateInternal): number;
|
|
15
|
+
export declare function annotationsSetDrawModifier(state: AnnotationsStateInternal, value: AnnotationsDrawModifier | null): void;
|
|
16
|
+
export declare function annotationsGetDrawModifier(state: AnnotationsStateInternal): AnnotationsDrawModifier | null;
|