@johnmorrisdotca/kumimoji 1.2.2 → 1.3.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 +33 -1
- package/CONTRIBUTING.md +11 -2
- package/README.md +80 -39
- package/dist/check.d.ts +26 -1
- package/dist/check.js +30 -3
- package/dist/computer.types.d.ts +24 -2
- package/dist/computerPlay.d.ts +45 -2
- package/dist/computerPlay.js +56 -6
- package/dist/computerTurn.d.ts +42 -3
- package/dist/computerTurn.js +47 -5
- package/dist/daily.d.ts +22 -2
- package/dist/daily.js +23 -3
- package/dist/element-define.d.ts +1 -1
- package/dist/element-define.js +3 -13
- package/dist/element.d.ts +85 -4
- package/dist/element.js +359 -77
- package/dist/embed-day.d.ts +4 -0
- package/dist/embed-day.js +23 -0
- package/dist/export.d.ts +123 -6
- package/dist/export.js +109 -9
- package/dist/generate.d.ts +14 -0
- package/dist/generate.js +32 -5
- package/dist/grid.d.ts +181 -10
- package/dist/grid.js +148 -11
- package/dist/help.d.ts +36 -3
- package/dist/help.js +36 -3
- package/dist/index.d.ts +22 -22
- package/dist/index.js +22 -22
- package/dist/judge.d.ts +14 -0
- package/dist/judge.js +14 -0
- package/dist/kana.d.ts +23 -1
- package/dist/kana.js +62 -7
- package/dist/kumimoji.types.d.ts +70 -5
- package/dist/party.d.ts +268 -14
- package/dist/party.js +296 -19
- package/dist/party.types.d.ts +50 -2
- package/dist/partyKept.d.ts +74 -4
- package/dist/partyKept.js +127 -12
- package/dist/partySeats.d.ts +92 -6
- package/dist/partySeats.js +83 -8
- package/dist/partyTurns.d.ts +171 -5
- package/dist/partyTurns.js +187 -8
- package/dist/placement.d.ts +50 -2
- package/dist/placement.js +35 -2
- package/dist/play.d.ts +247 -15
- package/dist/play.js +251 -18
- package/dist/random.d.ts +34 -3
- package/dist/random.js +23 -2
- package/dist/react.d.ts +42 -4
- package/dist/react.js +54 -7
- package/dist/showcase.d.ts +83 -7
- package/dist/showcase.js +61 -7
- package/dist/strings.d.ts +54 -5
- package/dist/strings.js +34 -3
- package/dist/tableView.d.ts +151 -8
- package/dist/tableView.js +129 -6
- package/dist/tileFace.d.ts +59 -5
- package/dist/tileFace.js +48 -4
- package/dist/tileFamily.d.ts +9 -0
- package/dist/tileFamily.js +9 -0
- package/dist/tileWords.d.ts +93 -6
- package/dist/tileWords.js +94 -12
- package/dist/tileWordsModule.d.ts +12 -2
- package/dist/tileWordsModule.js +14 -2
- package/dist/tiles.constants.d.ts +99 -5
- package/dist/tiles.constants.js +171 -13
- package/dist/turn.d.ts +82 -4
- package/dist/turn.js +88 -5
- package/dist/ui/board.d.ts +60 -5
- package/dist/ui/board.js +44 -4
- package/dist/ui/draw.d.ts +62 -0
- package/dist/ui/draw.js +229 -0
- package/dist/ui/mount.d.ts +41 -2
- package/dist/ui/mount.js +190 -265
- package/dist/ui/style.d.ts +6 -1
- package/dist/ui/style.js +6 -0
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +2 -2
- package/dist/version.d.ts +9 -2
- package/dist/version.js +9 -2
- package/dist/wilds.d.ts +22 -1
- package/dist/wilds.js +25 -3
- package/package.json +68 -61
package/dist/tableView.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ import { type Tiles } from "./grid.ts";
|
|
|
10
10
|
* there is always room to build outward, and it zooms to fit the crossword:
|
|
11
11
|
* big tiles for a first word, smaller as the grid spreads, never smaller than
|
|
12
12
|
* a thumb can press (`TABLE.tileLeast`). Past that the table pans instead.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { TABLE } from "@johnmorrisdotca/kumimoji";
|
|
17
|
+
* console.log(TABLE);
|
|
18
|
+
* ```
|
|
13
19
|
*/
|
|
14
20
|
export declare const TABLE: {
|
|
15
21
|
/** Empty squares shown beyond the tiles on every side. */
|
|
@@ -40,20 +46,52 @@ export declare const TABLE: {
|
|
|
40
46
|
/** How long a dragged tile must stay near an edge before the table pans: crossing an edge on the way in is not asking to pan. */
|
|
41
47
|
readonly edgeDwellMs: 350;
|
|
42
48
|
};
|
|
43
|
-
/** The squares shown: from `top`/`left`, `rows` by `cols`.
|
|
49
|
+
/** The squares shown: from `top`/`left`, `rows` by `cols`.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import type { Area } from "@johnmorrisdotca/kumimoji";
|
|
54
|
+
*
|
|
55
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
56
|
+
* const value: Area = area;
|
|
57
|
+
* console.log(value);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
44
60
|
export type Area = {
|
|
45
61
|
top: number;
|
|
46
62
|
left: number;
|
|
47
63
|
rows: number;
|
|
48
64
|
cols: number;
|
|
49
65
|
};
|
|
50
|
-
/** A view: a tile's side in pixels, and where the corner of square (0, 0) is drawn.
|
|
66
|
+
/** A view: a tile's side in pixels, and where the corner of square (0, 0) is drawn.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* import type { View } from "@johnmorrisdotca/kumimoji";
|
|
71
|
+
*
|
|
72
|
+
* const view = {tile:40,x:100,y:100};
|
|
73
|
+
* const value: View = view;
|
|
74
|
+
* console.log(value);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
51
77
|
export type View = {
|
|
52
78
|
tile: number;
|
|
53
79
|
x: number;
|
|
54
80
|
y: number;
|
|
55
81
|
};
|
|
56
|
-
/** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
|
|
82
|
+
/** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
|
|
83
|
+
*
|
|
84
|
+
* @param tiles - The map from row,column square names to internal tile codes.
|
|
85
|
+
* @param also - Additional square names to include in the table bounds.
|
|
86
|
+
* @returns The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* import { tableArea } from "@johnmorrisdotca/kumimoji";
|
|
90
|
+
*
|
|
91
|
+
* const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
|
|
92
|
+
* console.log(tableArea(tiles));
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
57
95
|
export declare function tableArea(tiles: Tiles, also?: readonly string[]): Area;
|
|
58
96
|
/**
|
|
59
97
|
* The largest a fitted tile is drawn in a table this big. `tileMost` in any
|
|
@@ -61,32 +99,137 @@ export declare function tableArea(tiles: Tiles, also?: readonly string[]): Area;
|
|
|
61
99
|
* the Regular desk table; past that, in proportion, so a table the player asked
|
|
62
100
|
* to be Large or Full (`BoardScale`) draws bigger squares rather than only more
|
|
63
101
|
* of them — never past what a hand may zoom to.
|
|
102
|
+
*
|
|
103
|
+
* @param width - The available viewport width in pixels.
|
|
104
|
+
* @param height - The available viewport height in pixels.
|
|
105
|
+
* @returns The largest a fitted tile is drawn in a table this big. `tileMost` in any table up to `growsFrom` across its shorter side, which is every phone's and the Regular desk table; past that, in proportion, so a table the player asked to be Large or Full (`BoardScale`) draws bigger squares rather than only more of them — never past what a hand may zoom to.
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* import { fittedMost } from "@johnmorrisdotca/kumimoji";
|
|
109
|
+
*
|
|
110
|
+
* console.log(fittedMost(640,480));
|
|
111
|
+
* ```
|
|
64
112
|
*/
|
|
65
113
|
export declare function fittedMost(width: number, height: number): number;
|
|
66
114
|
/**
|
|
67
115
|
* The view that shows the whole area, centred, its tiles as big as fit between
|
|
68
116
|
* the least and the most. A picture nobody presses (a finished grid, the
|
|
69
117
|
* set-up preview) passes a smaller least, so a whole grid fits its box.
|
|
118
|
+
*
|
|
119
|
+
* @param area - The occupied table bounds.
|
|
120
|
+
* @param width - The available viewport width in pixels.
|
|
121
|
+
* @param height - The available viewport height in pixels.
|
|
122
|
+
* @param least - The minimum permitted tile size.
|
|
123
|
+
* @returns The view that shows the whole area, centred, its tiles as big as fit between the least and the most. A picture nobody presses (a finished grid, the set-up preview) passes a smaller least, so a whole grid fits its box.
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* import { fitView } from "@johnmorrisdotca/kumimoji";
|
|
127
|
+
*
|
|
128
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
129
|
+
* console.log(fitView(area,640,480));
|
|
130
|
+
* ```
|
|
70
131
|
*/
|
|
71
132
|
export declare function fitView(area: Area, width: number, height: number, least?: number): View;
|
|
72
|
-
/** Whether the area, at this view's size, is bigger than the screen: then the table pans.
|
|
133
|
+
/** Whether the area, at this view's size, is bigger than the screen: then the table pans.
|
|
134
|
+
*
|
|
135
|
+
* @param area - The occupied table bounds.
|
|
136
|
+
* @param view - The current tile size and pixel translation.
|
|
137
|
+
* @param width - The available viewport width in pixels.
|
|
138
|
+
* @param height - The available viewport height in pixels.
|
|
139
|
+
* @returns Whether the area, at this view's size, is bigger than the screen: then the table pans.
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* import { overflows } from "@johnmorrisdotca/kumimoji";
|
|
143
|
+
*
|
|
144
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
145
|
+
* const view = {tile:40,x:100,y:100};
|
|
146
|
+
* console.log(overflows(area,view,640,480));
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
73
149
|
export declare function overflows(area: Area, view: View, width: number, height: number): boolean;
|
|
74
|
-
/** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
|
|
150
|
+
/** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
|
|
151
|
+
*
|
|
152
|
+
* @param view - The current tile size and pixel translation.
|
|
153
|
+
* @param factor - The positive scale factor for zooming.
|
|
154
|
+
* @param px - The horizontal pointer position in pixels.
|
|
155
|
+
* @param py - The vertical pointer position in pixels.
|
|
156
|
+
* @returns Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* import { zoomView } from "@johnmorrisdotca/kumimoji";
|
|
160
|
+
*
|
|
161
|
+
* const view = {tile:40,x:100,y:100};
|
|
162
|
+
* console.log(zoomView(view,1.2,320,240));
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
75
165
|
export declare function zoomView(view: View, factor: number, px: number, py: number): View;
|
|
76
|
-
/** The view moved by `dx` and `dy` screen pixels.
|
|
166
|
+
/** The view moved by `dx` and `dy` screen pixels.
|
|
167
|
+
*
|
|
168
|
+
* @param view - The current tile size and pixel translation.
|
|
169
|
+
* @param dx - The horizontal pixel movement.
|
|
170
|
+
* @param dy - The vertical pixel movement.
|
|
171
|
+
* @returns The view moved by `dx` and `dy` screen pixels.
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* import { panView } from "@johnmorrisdotca/kumimoji";
|
|
175
|
+
*
|
|
176
|
+
* const view = {tile:40,x:100,y:100};
|
|
177
|
+
* console.log(panView(view,20,10));
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
77
180
|
export declare function panView(view: View, dx: number, dy: number): View;
|
|
78
181
|
/**
|
|
79
182
|
* Kept within reach: some of the area always on the screen, so a pan can
|
|
80
183
|
* never lose the crossword. A quarter of the screen or two tiles, whichever
|
|
81
184
|
* is less, stays in view on every side.
|
|
185
|
+
*
|
|
186
|
+
* @param view - The current tile size and pixel translation.
|
|
187
|
+
* @param area - The occupied table bounds.
|
|
188
|
+
* @param width - The available viewport width in pixels.
|
|
189
|
+
* @param height - The available viewport height in pixels.
|
|
190
|
+
* @returns Kept within reach: some of the area always on the screen, so a pan can never lose the crossword. A quarter of the screen or two tiles, whichever is less, stays in view on every side.
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* import { keepInReach } from "@johnmorrisdotca/kumimoji";
|
|
194
|
+
*
|
|
195
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
196
|
+
* const view = {tile:40,x:100,y:100};
|
|
197
|
+
* console.log(keepInReach(view,area,640,480));
|
|
198
|
+
* ```
|
|
82
199
|
*/
|
|
83
200
|
export declare function keepInReach(view: View, area: Area, width: number, height: number): View;
|
|
84
|
-
/** The square under a point on the screen.
|
|
201
|
+
/** The square under a point on the screen.
|
|
202
|
+
*
|
|
203
|
+
* @param view - The current tile size and pixel translation.
|
|
204
|
+
* @param px - The horizontal pointer position in pixels.
|
|
205
|
+
* @param py - The vertical pointer position in pixels.
|
|
206
|
+
* @returns The square under a point on the screen.
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* import { squareUnder } from "@johnmorrisdotca/kumimoji";
|
|
210
|
+
*
|
|
211
|
+
* const view = {tile:40,x:100,y:100};
|
|
212
|
+
* console.log(squareUnder(view,100,100));
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
85
215
|
export declare function squareUnder(view: View, px: number, py: number): {
|
|
86
216
|
row: number;
|
|
87
217
|
col: number;
|
|
88
218
|
};
|
|
89
|
-
/** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
|
|
219
|
+
/** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
|
|
220
|
+
*
|
|
221
|
+
* @param px - The horizontal pointer position in pixels.
|
|
222
|
+
* @param py - The vertical pointer position in pixels.
|
|
223
|
+
* @param width - The available viewport width in pixels.
|
|
224
|
+
* @param height - The available viewport height in pixels.
|
|
225
|
+
* @returns Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* import { edgePan } from "@johnmorrisdotca/kumimoji";
|
|
229
|
+
*
|
|
230
|
+
* console.log(edgePan(5,240,640,480));
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
90
233
|
export declare function edgePan(px: number, py: number, width: number, height: number): {
|
|
91
234
|
dx: number;
|
|
92
235
|
dy: number;
|
package/dist/tableView.js
CHANGED
|
@@ -10,6 +10,12 @@ import { boundsOf, placeOf } from "./grid.js";
|
|
|
10
10
|
* there is always room to build outward, and it zooms to fit the crossword:
|
|
11
11
|
* big tiles for a first word, smaller as the grid spreads, never smaller than
|
|
12
12
|
* a thumb can press (`TABLE.tileLeast`). Past that the table pans instead.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { TABLE } from "@johnmorrisdotca/kumimoji";
|
|
17
|
+
* console.log(TABLE);
|
|
18
|
+
* ```
|
|
13
19
|
*/
|
|
14
20
|
export const TABLE = {
|
|
15
21
|
/** Empty squares shown beyond the tiles on every side. */
|
|
@@ -40,7 +46,19 @@ export const TABLE = {
|
|
|
40
46
|
/** How long a dragged tile must stay near an edge before the table pans: crossing an edge on the way in is not asking to pan. */
|
|
41
47
|
edgeDwellMs: 350,
|
|
42
48
|
};
|
|
43
|
-
/** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
|
|
49
|
+
/** The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
|
|
50
|
+
*
|
|
51
|
+
* @param tiles - The map from row,column square names to internal tile codes.
|
|
52
|
+
* @param also - Additional square names to include in the table bounds.
|
|
53
|
+
* @returns The squares to show: the tiles' extent and the margin, or the margin round square (0, 0) on an empty table. Extra squares (the one a typed letter goes to) are kept in.
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* import { tableArea } from "@johnmorrisdotca/kumimoji";
|
|
57
|
+
*
|
|
58
|
+
* const tiles = new Map([["0,0","c"],["0,1","a"],["0,2","t"]]);
|
|
59
|
+
* console.log(tableArea(tiles));
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
44
62
|
export function tableArea(tiles, also = []) {
|
|
45
63
|
const bounds = boundsOf(tiles) ?? { top: 0, left: 0, bottom: 0, right: 0 };
|
|
46
64
|
let { top, left, bottom, right } = bounds;
|
|
@@ -60,6 +78,16 @@ export function tableArea(tiles, also = []) {
|
|
|
60
78
|
* the Regular desk table; past that, in proportion, so a table the player asked
|
|
61
79
|
* to be Large or Full (`BoardScale`) draws bigger squares rather than only more
|
|
62
80
|
* of them — never past what a hand may zoom to.
|
|
81
|
+
*
|
|
82
|
+
* @param width - The available viewport width in pixels.
|
|
83
|
+
* @param height - The available viewport height in pixels.
|
|
84
|
+
* @returns The largest a fitted tile is drawn in a table this big. `tileMost` in any table up to `growsFrom` across its shorter side, which is every phone's and the Regular desk table; past that, in proportion, so a table the player asked to be Large or Full (`BoardScale`) draws bigger squares rather than only more of them — never past what a hand may zoom to.
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { fittedMost } from "@johnmorrisdotca/kumimoji";
|
|
88
|
+
*
|
|
89
|
+
* console.log(fittedMost(640,480));
|
|
90
|
+
* ```
|
|
63
91
|
*/
|
|
64
92
|
export function fittedMost(width, height) {
|
|
65
93
|
const side = Math.min(width, height);
|
|
@@ -71,6 +99,19 @@ export function fittedMost(width, height) {
|
|
|
71
99
|
* The view that shows the whole area, centred, its tiles as big as fit between
|
|
72
100
|
* the least and the most. A picture nobody presses (a finished grid, the
|
|
73
101
|
* set-up preview) passes a smaller least, so a whole grid fits its box.
|
|
102
|
+
*
|
|
103
|
+
* @param area - The occupied table bounds.
|
|
104
|
+
* @param width - The available viewport width in pixels.
|
|
105
|
+
* @param height - The available viewport height in pixels.
|
|
106
|
+
* @param least - The minimum permitted tile size.
|
|
107
|
+
* @returns The view that shows the whole area, centred, its tiles as big as fit between the least and the most. A picture nobody presses (a finished grid, the set-up preview) passes a smaller least, so a whole grid fits its box.
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* import { fitView } from "@johnmorrisdotca/kumimoji";
|
|
111
|
+
*
|
|
112
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
113
|
+
* console.log(fitView(area,640,480));
|
|
114
|
+
* ```
|
|
74
115
|
*/
|
|
75
116
|
export function fitView(area, width, height, least = TABLE.tileLeast) {
|
|
76
117
|
const fits = Math.min(width / area.cols, height / area.rows);
|
|
@@ -81,17 +122,59 @@ export function fitView(area, width, height, least = TABLE.tileLeast) {
|
|
|
81
122
|
y: Math.round((height - area.rows * tile) / 2 - area.top * tile),
|
|
82
123
|
};
|
|
83
124
|
}
|
|
84
|
-
/** Whether the area, at this view's size, is bigger than the screen: then the table pans.
|
|
125
|
+
/** Whether the area, at this view's size, is bigger than the screen: then the table pans.
|
|
126
|
+
*
|
|
127
|
+
* @param area - The occupied table bounds.
|
|
128
|
+
* @param view - The current tile size and pixel translation.
|
|
129
|
+
* @param width - The available viewport width in pixels.
|
|
130
|
+
* @param height - The available viewport height in pixels.
|
|
131
|
+
* @returns Whether the area, at this view's size, is bigger than the screen: then the table pans.
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* import { overflows } from "@johnmorrisdotca/kumimoji";
|
|
135
|
+
*
|
|
136
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
137
|
+
* const view = {tile:40,x:100,y:100};
|
|
138
|
+
* console.log(overflows(area,view,640,480));
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
85
141
|
export function overflows(area, view, width, height) {
|
|
86
142
|
return area.cols * view.tile > width + 0.5 || area.rows * view.tile > height + 0.5;
|
|
87
143
|
}
|
|
88
|
-
/** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
|
|
144
|
+
/** Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
|
|
145
|
+
*
|
|
146
|
+
* @param view - The current tile size and pixel translation.
|
|
147
|
+
* @param factor - The positive scale factor for zooming.
|
|
148
|
+
* @param px - The horizontal pointer position in pixels.
|
|
149
|
+
* @param py - The vertical pointer position in pixels.
|
|
150
|
+
* @returns Zoomed by `factor` about the point (px, py) on the screen, which stays over the same spot of the table.
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import { zoomView } from "@johnmorrisdotca/kumimoji";
|
|
154
|
+
*
|
|
155
|
+
* const view = {tile:40,x:100,y:100};
|
|
156
|
+
* console.log(zoomView(view,1.2,320,240));
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
89
159
|
export function zoomView(view, factor, px, py) {
|
|
90
160
|
const tile = Math.max(TABLE.zoomLeast, Math.min(TABLE.zoomMost, view.tile * factor));
|
|
91
161
|
const scale = tile / view.tile;
|
|
92
162
|
return { tile, x: px - (px - view.x) * scale, y: py - (py - view.y) * scale };
|
|
93
163
|
}
|
|
94
|
-
/** The view moved by `dx` and `dy` screen pixels.
|
|
164
|
+
/** The view moved by `dx` and `dy` screen pixels.
|
|
165
|
+
*
|
|
166
|
+
* @param view - The current tile size and pixel translation.
|
|
167
|
+
* @param dx - The horizontal pixel movement.
|
|
168
|
+
* @param dy - The vertical pixel movement.
|
|
169
|
+
* @returns The view moved by `dx` and `dy` screen pixels.
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* import { panView } from "@johnmorrisdotca/kumimoji";
|
|
173
|
+
*
|
|
174
|
+
* const view = {tile:40,x:100,y:100};
|
|
175
|
+
* console.log(panView(view,20,10));
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
95
178
|
export function panView(view, dx, dy) {
|
|
96
179
|
return { ...view, x: view.x + dx, y: view.y + dy };
|
|
97
180
|
}
|
|
@@ -99,6 +182,20 @@ export function panView(view, dx, dy) {
|
|
|
99
182
|
* Kept within reach: some of the area always on the screen, so a pan can
|
|
100
183
|
* never lose the crossword. A quarter of the screen or two tiles, whichever
|
|
101
184
|
* is less, stays in view on every side.
|
|
185
|
+
*
|
|
186
|
+
* @param view - The current tile size and pixel translation.
|
|
187
|
+
* @param area - The occupied table bounds.
|
|
188
|
+
* @param width - The available viewport width in pixels.
|
|
189
|
+
* @param height - The available viewport height in pixels.
|
|
190
|
+
* @returns Kept within reach: some of the area always on the screen, so a pan can never lose the crossword. A quarter of the screen or two tiles, whichever is less, stays in view on every side.
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* import { keepInReach } from "@johnmorrisdotca/kumimoji";
|
|
194
|
+
*
|
|
195
|
+
* const area = {top:0,left:0,rows:1,cols:3};
|
|
196
|
+
* const view = {tile:40,x:100,y:100};
|
|
197
|
+
* console.log(keepInReach(view,area,640,480));
|
|
198
|
+
* ```
|
|
102
199
|
*/
|
|
103
200
|
export function keepInReach(view, area, width, height) {
|
|
104
201
|
const hold = (span) => Math.min(span / 4, view.tile * 2);
|
|
@@ -117,11 +214,37 @@ export function keepInReach(view, area, width, height) {
|
|
|
117
214
|
y -= top - (height - hold(height));
|
|
118
215
|
return { ...view, x, y };
|
|
119
216
|
}
|
|
120
|
-
/** The square under a point on the screen.
|
|
217
|
+
/** The square under a point on the screen.
|
|
218
|
+
*
|
|
219
|
+
* @param view - The current tile size and pixel translation.
|
|
220
|
+
* @param px - The horizontal pointer position in pixels.
|
|
221
|
+
* @param py - The vertical pointer position in pixels.
|
|
222
|
+
* @returns The square under a point on the screen.
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* import { squareUnder } from "@johnmorrisdotca/kumimoji";
|
|
226
|
+
*
|
|
227
|
+
* const view = {tile:40,x:100,y:100};
|
|
228
|
+
* console.log(squareUnder(view,100,100));
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
121
231
|
export function squareUnder(view, px, py) {
|
|
122
232
|
return { row: Math.floor((py - view.y) / view.tile), col: Math.floor((px - view.x) / view.tile) };
|
|
123
233
|
}
|
|
124
|
-
/** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
|
|
234
|
+
/** Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
|
|
235
|
+
*
|
|
236
|
+
* @param px - The horizontal pointer position in pixels.
|
|
237
|
+
* @param py - The vertical pointer position in pixels.
|
|
238
|
+
* @param width - The available viewport width in pixels.
|
|
239
|
+
* @param height - The available viewport height in pixels.
|
|
240
|
+
* @returns Which way, and how far, the table pans this frame for a tile dragged to (px, py): toward the edge it is near.
|
|
241
|
+
* @example
|
|
242
|
+
* ```ts
|
|
243
|
+
* import { edgePan } from "@johnmorrisdotca/kumimoji";
|
|
244
|
+
*
|
|
245
|
+
* console.log(edgePan(5,240,640,480));
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
125
248
|
export function edgePan(px, py, width, height) {
|
|
126
249
|
const step = (near) => (near < TABLE.edge ? TABLE.edgeStep * (1 - Math.max(0, near) / TABLE.edge) : 0);
|
|
127
250
|
return { dx: step(px) - step(width - px), dy: step(py) - step(height - py) };
|
package/dist/tileFace.d.ts
CHANGED
|
@@ -6,13 +6,47 @@
|
|
|
6
6
|
* `KANA_TILE_START`, or above `KANA_WILD_START` for a wild given that kana.
|
|
7
7
|
* So the set-up's preview and a finished game's page draw Japanese tiles
|
|
8
8
|
* without fetching the dictionary, and `tileWords` reads the same codes.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { KANA_TILE_START } from "@johnmorrisdotca/kumimoji";
|
|
13
|
+
* console.log(KANA_TILE_START);
|
|
14
|
+
* ```
|
|
9
15
|
*/
|
|
10
16
|
export declare const KANA_TILE_START = 57344;
|
|
11
|
-
/** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this.
|
|
17
|
+
/** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { KANA_WILD_START } from "@johnmorrisdotca/kumimoji";
|
|
22
|
+
* console.log(KANA_WILD_START);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
12
25
|
export declare const KANA_WILD_START = 61440;
|
|
13
|
-
/** The code of a base kana's tile, or of a wild given that kana.
|
|
26
|
+
/** The code of a base kana's tile, or of a wild given that kana.
|
|
27
|
+
*
|
|
28
|
+
* @param kana - The hiragana reading to map to a base tile.
|
|
29
|
+
* @param wild - Whether to encode the assigned face as a wild tile.
|
|
30
|
+
* @returns The internal tile code, or null when the kana has no supported base tile.
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { kanaTileCode } from "@johnmorrisdotca/kumimoji";
|
|
34
|
+
*
|
|
35
|
+
* console.log(kanaTileCode("は"));
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
14
38
|
export declare function kanaTileCode(kana: string, wild?: boolean): string | null;
|
|
15
|
-
/** What a tile shows: what `tileFace` answers.
|
|
39
|
+
/** What a tile shows: what `tileFace` answers.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import type { TileFaceOf } from "@johnmorrisdotca/kumimoji";
|
|
44
|
+
* import { tileFace } from "@johnmorrisdotca/kumimoji";
|
|
45
|
+
*
|
|
46
|
+
* const value: TileFaceOf = tileFace("A");
|
|
47
|
+
* console.log(value);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
16
50
|
export type TileFaceOf = {
|
|
17
51
|
/** The letter or kana printed on it: 五 on a wild nobody has given one. */
|
|
18
52
|
glyph: string;
|
|
@@ -23,7 +57,27 @@ export type TileFaceOf = {
|
|
|
23
57
|
/** A wild with no letter yet. */
|
|
24
58
|
blank: boolean;
|
|
25
59
|
};
|
|
26
|
-
/** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
|
|
60
|
+
/** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
|
|
61
|
+
*
|
|
62
|
+
* @param tile - The internal tile code to describe.
|
|
63
|
+
* @returns What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* import { tileFace } from "@johnmorrisdotca/kumimoji";
|
|
67
|
+
*
|
|
68
|
+
* console.log(tileFace("A"));
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
27
71
|
export declare function tileFace(tile: string): TileFaceOf;
|
|
28
|
-
/** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
|
|
72
|
+
/** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
|
|
73
|
+
*
|
|
74
|
+
* @param tile - The internal tile code to describe.
|
|
75
|
+
* @returns What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { tileDescription } from "@johnmorrisdotca/kumimoji";
|
|
79
|
+
*
|
|
80
|
+
* console.log(tileDescription("A"));
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
29
83
|
export declare function tileDescription(tile: string): string;
|
package/dist/tileFace.js
CHANGED
|
@@ -7,17 +7,51 @@ import { BASE_KANA, CORNER_FORMS } from "./kana.js";
|
|
|
7
7
|
* `KANA_TILE_START`, or above `KANA_WILD_START` for a wild given that kana.
|
|
8
8
|
* So the set-up's preview and a finished game's page draw Japanese tiles
|
|
9
9
|
* without fetching the dictionary, and `tileWords` reads the same codes.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { KANA_TILE_START } from "@johnmorrisdotca/kumimoji";
|
|
14
|
+
* console.log(KANA_TILE_START);
|
|
15
|
+
* ```
|
|
10
16
|
*/
|
|
11
17
|
export const KANA_TILE_START = 0xe000;
|
|
12
|
-
/** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this.
|
|
18
|
+
/** Where the codes of wild tiles given a kana begin: the kana's place in `BASE_KANA` above this.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { KANA_WILD_START } from "@johnmorrisdotca/kumimoji";
|
|
23
|
+
* console.log(KANA_WILD_START);
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
13
26
|
export const KANA_WILD_START = 0xf000;
|
|
14
27
|
const KANA = [...BASE_KANA];
|
|
15
|
-
/** The code of a base kana's tile, or of a wild given that kana.
|
|
28
|
+
/** The code of a base kana's tile, or of a wild given that kana.
|
|
29
|
+
*
|
|
30
|
+
* @param kana - The hiragana reading to map to a base tile.
|
|
31
|
+
* @param wild - Whether to encode the assigned face as a wild tile.
|
|
32
|
+
* @returns The internal tile code, or null when the kana has no supported base tile.
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* import { kanaTileCode } from "@johnmorrisdotca/kumimoji";
|
|
36
|
+
*
|
|
37
|
+
* console.log(kanaTileCode("は"));
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
16
40
|
export function kanaTileCode(kana, wild = false) {
|
|
17
41
|
const at = KANA.indexOf(kana);
|
|
18
42
|
return at === -1 ? null : String.fromCodePoint((wild ? KANA_WILD_START : KANA_TILE_START) + at);
|
|
19
43
|
}
|
|
20
|
-
/** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
|
|
44
|
+
/** What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
|
|
45
|
+
*
|
|
46
|
+
* @param tile - The internal tile code to describe.
|
|
47
|
+
* @returns What a tile code shows, read without the word list: its letter or kana, its corner forms, and whether it is a wild.
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { tileFace } from "@johnmorrisdotca/kumimoji";
|
|
51
|
+
*
|
|
52
|
+
* console.log(tileFace("A"));
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
21
55
|
export function tileFace(tile) {
|
|
22
56
|
if (tile === "*")
|
|
23
57
|
return { glyph: "五", forms: "", wild: true, blank: true };
|
|
@@ -32,7 +66,17 @@ export function tileFace(tile) {
|
|
|
32
66
|
return { glyph: wildKana, forms: "", wild: true, blank: false };
|
|
33
67
|
return { glyph: tile, forms: "", wild: false, blank: false };
|
|
34
68
|
}
|
|
35
|
-
/** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
|
|
69
|
+
/** What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
|
|
70
|
+
*
|
|
71
|
+
* @param tile - The internal tile code to describe.
|
|
72
|
+
* @returns What a screen reader says for a tile: its letter, or that it is a wild and what it stands for.
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { tileDescription } from "@johnmorrisdotca/kumimoji";
|
|
76
|
+
*
|
|
77
|
+
* console.log(tileDescription("A"));
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
36
80
|
export function tileDescription(tile) {
|
|
37
81
|
const face = tileFace(tile);
|
|
38
82
|
if (face.wild)
|
package/dist/tileFamily.d.ts
CHANGED
|
@@ -7,5 +7,14 @@ import type { KumimojiLanguage } from "./kumimoji.types.ts";
|
|
|
7
7
|
* several devices (docs/plans/party-online/README.md, John 2026-09-29: the
|
|
8
8
|
* browser checks the words, the server only that the tiles are real).
|
|
9
9
|
* `tileFamily.test.ts` holds the two to one another.
|
|
10
|
+
*
|
|
11
|
+
* @param language - The English or Japanese tile language.
|
|
12
|
+
* @returns A function returning the physical family of a tile, or null for an invalid code.
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { familyKeyOf } from "@johnmorrisdotca/kumimoji";
|
|
16
|
+
*
|
|
17
|
+
* console.log(familyKeyOf("english")("A"));
|
|
18
|
+
* ```
|
|
10
19
|
*/
|
|
11
20
|
export declare function familyKeyOf(language: KumimojiLanguage): (tile: string) => string | null;
|
package/dist/tileFamily.js
CHANGED
|
@@ -8,6 +8,15 @@ import { KANA_TILE_START, KANA_WILD_START, tileFace } from "./tileFace.js";
|
|
|
8
8
|
* several devices (docs/plans/party-online/README.md, John 2026-09-29: the
|
|
9
9
|
* browser checks the words, the server only that the tiles are real).
|
|
10
10
|
* `tileFamily.test.ts` holds the two to one another.
|
|
11
|
+
*
|
|
12
|
+
* @param language - The English or Japanese tile language.
|
|
13
|
+
* @returns A function returning the physical family of a tile, or null for an invalid code.
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { familyKeyOf } from "@johnmorrisdotca/kumimoji";
|
|
17
|
+
*
|
|
18
|
+
* console.log(familyKeyOf("english")("A"));
|
|
19
|
+
* ```
|
|
11
20
|
*/
|
|
12
21
|
export function familyKeyOf(language) {
|
|
13
22
|
if (language === "english") {
|