@johnmorrisdotca/kyogijo-stadiums 0.12.1 → 0.12.2
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 +12 -0
- package/dist/turn.camera.d.ts +6 -1
- package/dist/turn.camera.js +16 -3
- package/dist/turn.kit.d.ts +5 -0
- package/dist/turn.markup.d.ts +5 -0
- package/dist/turn.markup.js +23 -6
- package/dist/turn.model.d.ts +1 -1
- package/dist/turn.model.js +1 -1
- package/dist/turn.style.js +3 -0
- package/dist/uprights.budo.d.ts +2 -0
- package/dist/uprights.budo.js +14 -7
- package/dist/uprights.d.ts +2 -0
- package/dist/uprights.js +3 -1
- package/dist/uprights.net.js +12 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ All notable changes to this project are written here. The format follows
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.12.2] - 2026-10-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **The demo leads to the tournament layouts.** A "Tournament layouts" link in the demo's header; under the surface of a sport that has layouts (table tennis, pickleball, curling, judo, karate, badminton, tennis) a "See it as a tournament floor" link to `halls.html` with that sport's first layout chosen (and the page's language and theme); and a link back to the demo from `halls.html`. `halls.html` also takes `theme=light|dark` in its address.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A dohyō in the 3D view is a solid block, not a hollow tray, and the floor round it is not cut off.** The whole floor was lifted to the mound's height and always drawn under the mound's four walls, so the walls on the far side showed over the clay and the clay looked sunk in a tray, with the grey hall floor raised level with it. Now the floor lies on the hall's floor, the mound is four sides (a tone darker than the top) and a flat top (the drawing's own clay and straw bales, cropped to the mound's square and lifted to its height), and the sides on the far side are drawn before the top and the ones on the near side after it at every turn. The view is fitted to the whole floor, so no part of it is cut off at any angle, and the stands of a crowd stand on the hall's floor.
|
|
19
|
+
- **A table tennis table's far legs no longer show through its top, and its legs stand on something.** The raised floor (the table's top) was always drawn under every plane, so the legs and skirt on the far side were drawn over it. A raised floor now takes its turn among the planes by its middle, like any other, and a soft shadow under the table on the hall's floor seats the legs.
|
|
20
|
+
- **The 3D view no longer swells and shrinks as it turns.** A surface going round, by hand or by the auto-turn, grew and shrank rhythmically, and in steps, instead of turning smoothly. There were two causes, both in the camera. The matrix written to each plane (`matrix3d`) rounded every number to four decimals, but its perspective terms are a few ten-thousandths and are multiplied by the pixels of a whole floor, so the rounding bent the perspective by tens of percent and by jumps as the angle changed (a floor's area on the screen jumped by up to a quarter between two views a few degrees apart); the numbers are now written to ten decimals. And the lens was short (1.7 times the box's longer side), so the nearer end of the floor swelled as it swung toward the eye (about a tenth of the area over a turn); the default is now 8 (`lens` still takes any value, and a smaller one brings the swelling back). The scale and the centre were already one for the whole turn (0.10.0); now the floor's area on the screen varies by about one percent over a turn, smoothly, for every sport and a tournament layout used as a floor, light and dark, desk and phone. New tests (`src/turn.size.test.ts`, and one in `e2e/turn.demo.mjs` in a real browser) sample the floor's area over a full turn, as the browser draws the written matrix, and fail on the old camera.
|
|
21
|
+
|
|
10
22
|
## [0.12.1] - 2026-10-19
|
|
11
23
|
|
|
12
24
|
The npm page shows the tournament layouts. No change to the package's code.
|
package/dist/turn.camera.d.ts
CHANGED
|
@@ -114,5 +114,10 @@ export declare function cameraMatrix(view: TurnView, at: Placement, distance: nu
|
|
|
114
114
|
export declare const matrix3d: (m: Mat4) => string;
|
|
115
115
|
/** How far a point is from the eye's plane after the scene is turned and tipped, in pixels towards the eye: bigger is nearer. Planes are drawn far first. */
|
|
116
116
|
export declare function depthOf(point: readonly [number, number, number], view: TurnView, at: Placement): number;
|
|
117
|
-
/**
|
|
117
|
+
/** The lens of the eye, as a multiple of the container's longer side. */
|
|
118
|
+
export declare const LENS = 8;
|
|
119
|
+
/**
|
|
120
|
+
* How far the eye is from the screen, in pixels, for a container: a long lens, so that the floor keeps its shape and the heights lean a little. The lens is long enough that the
|
|
121
|
+
* nearer end of a floor is hardly larger than the farther one: with a short lens (it was 1.7) the floor swelled by up to a quarter as its near end swung toward the eye in a turn.
|
|
122
|
+
*/
|
|
118
123
|
export declare const eyeDistance: (w: number, h: number, lens?: number) => number;
|
package/dist/turn.camera.js
CHANGED
|
@@ -199,7 +199,15 @@ export function cameraMatrix(view, at, distance) {
|
|
|
199
199
|
m = multiply(m, rotateZ);
|
|
200
200
|
return multiply(m, scale);
|
|
201
201
|
}
|
|
202
|
-
|
|
202
|
+
/**
|
|
203
|
+
* A number of a matrix as CSS writes it: to ten decimals, with no exponent. The perspective terms of a camera matrix are tiny (a few ten-thousandths) and are multiplied by
|
|
204
|
+
* the pixels of a whole floor, so rounding them to four decimals, as every other term could be, bent the perspective by tens of percent and by jumps as the turn went on: the
|
|
205
|
+
* surface swelled and shrank in steps.
|
|
206
|
+
*/
|
|
207
|
+
const num = (value) => {
|
|
208
|
+
const text = value.toFixed(10).replace(/\.?0+$/, "");
|
|
209
|
+
return text === "-0" || text === "" ? "0" : text;
|
|
210
|
+
};
|
|
203
211
|
/** A matrix as the CSS `transform` that applies it. */
|
|
204
212
|
export const matrix3d = (m) => `matrix3d(${m.map(num).join(",")})`;
|
|
205
213
|
/** How far a point is from the eye's plane after the scene is turned and tipped, in pixels towards the eye: bigger is nearer. Planes are drawn far first. */
|
|
@@ -210,5 +218,10 @@ export function depthOf(point, view, at) {
|
|
|
210
218
|
const y2 = x * Math.sin(yaw) + y * Math.cos(yaw);
|
|
211
219
|
return y2 * Math.sin(view.pitch * RAD) + z * Math.cos(view.pitch * RAD);
|
|
212
220
|
}
|
|
213
|
-
/**
|
|
214
|
-
export const
|
|
221
|
+
/** The lens of the eye, as a multiple of the container's longer side. */
|
|
222
|
+
export const LENS = 8;
|
|
223
|
+
/**
|
|
224
|
+
* How far the eye is from the screen, in pixels, for a container: a long lens, so that the floor keeps its shape and the heights lean a little. The lens is long enough that the
|
|
225
|
+
* nearer end of a floor is hardly larger than the farther one: with a short lens (it was 1.7) the floor swelled by up to a quarter as its near end swung toward the eye in a turn.
|
|
226
|
+
*/
|
|
227
|
+
export const eyeDistance = (w, h, lens = LENS) => lens * Math.max(w, h);
|
package/dist/turn.kit.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ export interface Plane {
|
|
|
21
21
|
* wall. The nearer the eye is to that side, and the lower it is, the more the wall is cut away (see `fadeOf`), so that the court is never hidden behind its own glass.
|
|
22
22
|
*/
|
|
23
23
|
shy?: readonly [number, number];
|
|
24
|
+
/**
|
|
25
|
+
* A plane that is the floor's own drawing seen through its rectangle, not a drawing of its own: the top of a raised platform (a dohyō's clay with its bales). The floor lies on the ground, so
|
|
26
|
+
* that the ground round the platform stays low, and this plane lifts the part of it that is the platform's top to the platform's height. Its `u` and `v` must be flat and along x and y.
|
|
27
|
+
*/
|
|
28
|
+
crop?: boolean;
|
|
24
29
|
/** How much of a `shy` plane is left when it is cut away altogether: 0.08 when missing. A plane that others lie over on the screen (the steps of a gallery) takes less, so that they do not add up to a veil. */
|
|
25
30
|
fadeTo?: number;
|
|
26
31
|
}
|
package/dist/turn.markup.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ export interface Layout {
|
|
|
21
21
|
export declare function layoutOf(model: TurnModel, view: TurnView, width: number, height: number, lens?: number): Layout;
|
|
22
22
|
/** One plane as an element: its box in pixels and the SVG drawn on it in feet. */
|
|
23
23
|
export declare function planeMarkup(p: Plane, scale: number, transform: string, stack: number, fade?: number): string;
|
|
24
|
+
/**
|
|
25
|
+
* A plane that is the floor's own drawing seen through its rectangle (`Plane.crop`): the floor's SVG again, its viewBox cut down to the plane's rectangle, in the plane's own box. It is a picture, not a second
|
|
26
|
+
* description: it carries no role, title or description of its own.
|
|
27
|
+
*/
|
|
28
|
+
export declare function cropMarkup(model: TurnModel, p: Plane, transform: string, stack: number, fade?: number): string;
|
|
24
29
|
/** The floor as an element: the flat drawing, in the pixels of the scene. */
|
|
25
30
|
export declare function floorMarkup(model: TurnModel, transform: string, stack: number): string;
|
|
26
31
|
/** The patterns the venue's planes are drawn with, once, in a box of no size: every plane's SVG reads them by id, and the crowd's colours are on this element. */
|
package/dist/turn.markup.js
CHANGED
|
@@ -29,15 +29,16 @@ export function layoutOf(model, view, width, height, lens) {
|
|
|
29
29
|
// A billboard faces the eye at this view.
|
|
30
30
|
const planes = model.planes.map((p) => facing(p, view.yaw));
|
|
31
31
|
const transforms = [floor, ...planes].map((p) => matrix3d(multiply(camera, planeMatrix(p, s, centre))));
|
|
32
|
-
// Far to near: a plane's depth is that of its middle. The ground of a hall is under everything
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// Far to near: a plane's depth is that of its middle. The ground of a hall is under everything. The floor is next, unless it stands raised on something (a table tennis table's top, on its legs): then it is
|
|
33
|
+
// sorted with the rest, by its middle, so that the legs and the skirt on the far side are drawn under it and the ones on the near side over it, and nothing under the top shows through it.
|
|
34
|
+
const depth = (p) => depthOf([(p.o[0] + (p.u[0] + p.v[0]) / 2 - centre[0]) * s, (p.o[1] + (p.u[1] + p.v[1]) / 2 - centre[1]) * s, (p.o[2] + (p.u[2] + p.v[2]) / 2) * s], view, at);
|
|
35
|
+
const raised = model.uprights.lift > 0;
|
|
36
|
+
const order = [...planes.map((p, i) => ({ i: i + 1, ground: p.kind === "ground", depth: depth(p) })), ...(raised ? [{ i: 0, ground: false, depth: depth(floor) }] : [])].filter((one) => !one.ground);
|
|
36
37
|
order.sort((a, b) => a.depth - b.depth);
|
|
37
38
|
const stack = new Array(model.planes.length + 1).fill(0);
|
|
38
39
|
stack[0] = 1;
|
|
39
40
|
order.forEach((one, rank) => {
|
|
40
|
-
stack[one.i
|
|
41
|
+
stack[one.i] = rank + 2;
|
|
41
42
|
});
|
|
42
43
|
const fade = [1, ...model.planes.map((p) => fadeOf(p, view.yaw, view.pitch))];
|
|
43
44
|
return { at, transforms, stack, fade };
|
|
@@ -47,6 +48,22 @@ export function planeMarkup(p, scale, transform, stack, fade = 1) {
|
|
|
47
48
|
const [w, h] = size(p);
|
|
48
49
|
return `<div class="ky-up ky-up-${p.kind}" data-part="${esc(p.id)}" style="width:${px(w * scale)}px;height:${px(h * scale)}px;transform:${transform};z-index:${stack}${fade < 1 ? `;opacity:${n(fade)}` : ""}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${n(w)} ${n(h)}" width="${px(w * scale)}" height="${px(h * scale)}" aria-hidden="true" focusable="false">${p.svg}</svg></div>`;
|
|
49
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* A plane that is the floor's own drawing seen through its rectangle (`Plane.crop`): the floor's SVG again, its viewBox cut down to the plane's rectangle, in the plane's own box. It is a picture, not a second
|
|
53
|
+
* description: it carries no role, title or description of its own.
|
|
54
|
+
*/
|
|
55
|
+
export function cropMarkup(model, p, transform, stack, fade = 1) {
|
|
56
|
+
const [w, h] = size(p);
|
|
57
|
+
const box = `${px(p.o[0])} ${px(p.o[1])} ${px(w)} ${px(h)}`;
|
|
58
|
+
const picture = model.floor
|
|
59
|
+
.replace(/^<svg([^>]*?)\sviewBox="[^"]*"/, `<svg$1 viewBox="${box}"`)
|
|
60
|
+
.replace(/^<svg([^>]*?)\swidth="[^"]*"/, "<svg$1")
|
|
61
|
+
.replace(/^<svg([^>]*?)\sheight="[^"]*"/, "<svg$1")
|
|
62
|
+
.replace(/^<svg([^>]*?)\srole="img"/, '<svg$1 aria-hidden="true"')
|
|
63
|
+
.replace(/^<svg([^>]*?)\saria-labelledby="[^"]*"/, "<svg$1")
|
|
64
|
+
.replace(/<title\b[^>]*>[\s\S]*?<\/title>|<desc\b[^>]*>[\s\S]*?<\/desc>/g, "");
|
|
65
|
+
return `<div class="ky-up ky-up-${p.kind}" data-part="${esc(p.id)}" data-crop="floor" style="width:${px(w * model.scale)}px;height:${px(h * model.scale)}px;transform:${transform};z-index:${stack}${fade < 1 ? `;opacity:${n(fade)}` : ""}">${picture}</div>`;
|
|
66
|
+
}
|
|
50
67
|
/** The floor as an element: the flat drawing, in the pixels of the scene. */
|
|
51
68
|
export function floorMarkup(model, transform, stack) {
|
|
52
69
|
const vb = model.viewBox;
|
|
@@ -66,7 +83,7 @@ export function worldAttributes(model) {
|
|
|
66
83
|
}
|
|
67
84
|
/** The floor and the planes of a model, laid out. */
|
|
68
85
|
export function worldMarkup(model, layout) {
|
|
69
|
-
return defsMarkup(model) + floorMarkup(model, layout.transforms[0], layout.stack[0]) + model.planes.map((p, i) => planeMarkup(p, model.scale, layout.transforms[i + 1], layout.stack[i + 1], layout.fade[i + 1])).join("");
|
|
86
|
+
return defsMarkup(model) + floorMarkup(model, layout.transforms[0], layout.stack[0]) + model.planes.map((p, i) => (p.crop === true ? cropMarkup(model, p, layout.transforms[i + 1], layout.stack[i + 1], layout.fade[i + 1]) : planeMarkup(p, model.scale, layout.transforms[i + 1], layout.stack[i + 1], layout.fade[i + 1]))).join("");
|
|
70
87
|
}
|
|
71
88
|
/** The buttons under the view. */
|
|
72
89
|
export function controlsMarkup(model, view, playing = false) {
|
package/dist/turn.model.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export interface TurnSettings {
|
|
|
29
29
|
motion?: "auto" | "smooth" | "none";
|
|
30
30
|
/** The drawing the floor is, in place of `drawKyogijo`: a chart's `draw`, for instance. It is given the options with the view's own changes (the whole surface, lying wide). */
|
|
31
31
|
floor?: (options: SurfaceOptions | ScoreOptions) => string;
|
|
32
|
-
/** How long a lens the eye has, as a multiple of the view's longer side:
|
|
32
|
+
/** How long a lens the eye has, as a multiple of the view's longer side: 8 by default (`LENS`), and the larger it is the flatter the picture; a short lens makes the near end of a turning floor swell. */
|
|
33
33
|
lens?: number;
|
|
34
34
|
/** The size the first view is worked out for, in pixels, when the markup is made away from a page. 960 by 600 by default. */
|
|
35
35
|
size?: {
|
package/dist/turn.model.js
CHANGED
|
@@ -66,7 +66,7 @@ export function buildTurn(options, settings = {}) {
|
|
|
66
66
|
const centre = [vx + vw / 2, vy + vh / 2];
|
|
67
67
|
// The scene's extent: the playing surface (the whole floor where it has no uprights), and whatever stands beyond it (a net behind a goal line). The ground
|
|
68
68
|
// round the surface is not counted, so that the view is fitted to what is played on and the ground runs out of the picture.
|
|
69
|
-
const area = uprights.area
|
|
69
|
+
const area = uprights.whole === true || uprights.area === undefined ? { x0: vx, y0: vy, x1: vx + vw, y1: vy + vh } : uprights.area;
|
|
70
70
|
let [x0, y0, x1, y1] = [area.x0, area.y0, area.x1, area.y1];
|
|
71
71
|
let top = uprights.lift;
|
|
72
72
|
for (const p of planes) {
|
package/dist/turn.style.js
CHANGED
|
@@ -15,6 +15,7 @@ export const KYOGIJO_TURN_STYLE = `
|
|
|
15
15
|
.ky-turn-floor,.ky-up{position:absolute;left:0;top:0;transform-origin:0 0;pointer-events:none}
|
|
16
16
|
.ky-turn-floor>svg{display:block;width:100%;height:auto}
|
|
17
17
|
.ky-up>svg{display:block;overflow:visible}
|
|
18
|
+
.ky-up[data-crop]>svg{width:100%;height:100%;overflow:hidden}
|
|
18
19
|
@media (max-width:560px){.ky-turn-view{--ky-turn-ratio:5/4}.ky-turn-controls button{padding:0 10px;font-size:.85rem}}
|
|
19
20
|
.ky-turn .u-sbframe{fill:var(--ky-up-sbframe);stroke:var(--ky-up-sbedge);stroke-width:.25}
|
|
20
21
|
.ky-turn .u-sbline{stroke:var(--ky-up-sbline)}
|
|
@@ -29,8 +30,10 @@ export const KYOGIJO_TURN_STYLE = `
|
|
|
29
30
|
.ky-turn .u-table{fill:var(--ky-up-table)}
|
|
30
31
|
.ky-turn .u-foot{fill:var(--ky-up-foot)}
|
|
31
32
|
.ky-turn .u-ground{fill:var(--ky-up-ground)}
|
|
33
|
+
.ky-turn .u-shadow{fill:#000;fill-opacity:.16}
|
|
32
34
|
.ky-turn .u-wall{fill:var(--ky-up-wall)}
|
|
33
35
|
.ky-turn .u-clay{fill:var(--ky-up-clay)}
|
|
36
|
+
.ky-turn .u-clay-side{fill:color-mix(in srgb,var(--ky-dirt,var(--ky-up-clay)) 74%,#000)}
|
|
34
37
|
.ky-turn .u-cap{fill:var(--ky-up-cap)}
|
|
35
38
|
.ky-turn .u-board{fill:var(--ky-up-board)}
|
|
36
39
|
.ky-turn .u-glass{fill:var(--ky-up-glass)}
|
package/dist/uprights.budo.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export interface BudoUprights {
|
|
|
10
10
|
x1: number;
|
|
11
11
|
y1: number;
|
|
12
12
|
};
|
|
13
|
+
/** The view is fitted to the whole floor (a platform stands in it), not to `area`. */
|
|
14
|
+
whole: boolean;
|
|
13
15
|
}
|
|
14
16
|
/** The walls of a dojo, 3 m high (ours). */
|
|
15
17
|
export declare const DOJO_WALL = 3;
|
package/dist/uprights.budo.js
CHANGED
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
// (a judo platform's height is not in the rules: "it depends on the sightlines"). The plans are in metres in the frame of their own origin, and the drawing's frame is feet from the corner of the plan's
|
|
4
4
|
// box, so every point goes through `at`. The mound's height is the option's; the azuchi's (1.5 m or 1.8 m) and a dojo wall's (3 m) are ours: no rule gives them.
|
|
5
5
|
import { budoPlan } from "./budo/plan.js";
|
|
6
|
-
import { n, plane, shy, wall } from "./turn.kit.js";
|
|
6
|
+
import { flat, n, plane, shy, wall } from "./turn.kit.js";
|
|
7
7
|
const K = 1 / 0.3048;
|
|
8
8
|
/** The walls of a dojo, 3 m high (ours). */
|
|
9
9
|
export const DOJO_WALL = 3;
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* The planes of the dohyō's clay mound, a solid block: its four sides, from the floor of the hall up to the clay, and its flat top, which is the drawing's own clay with the ring of straw bales on it, lifted to the
|
|
12
|
+
* mound's height (the floor itself lies on the hall's floor, so that the ground round the mound stays low). The sides are one tone darker than the top, so that top and sides are lit the same way; whichever way
|
|
13
|
+
* the view is turned, the sides on the far side are drawn first and the top over them (see `layoutOf`), so the mound never looks hollow.
|
|
14
|
+
*/
|
|
11
15
|
function moundPlanes(plan, at, height) {
|
|
12
16
|
const L = plan.sumo;
|
|
13
17
|
if (L === undefined)
|
|
@@ -17,8 +21,10 @@ function moundPlanes(plan, at, height) {
|
|
|
17
21
|
const planes = [];
|
|
18
22
|
corners.forEach((a, i) => {
|
|
19
23
|
const c = corners[(i + 1) % 4];
|
|
20
|
-
planes.push(wall(`mound-${i + 1}`, "wall", a[0], a[1], c[0], c[1], 0, height, `<rect width="${n(Math.hypot(c[0] - a[0], c[1] - a[1]))}" height="${n(height)}" class="u-clay"/>`));
|
|
24
|
+
planes.push(wall(`mound-${i + 1}`, "wall", a[0], a[1], c[0], c[1], 0, height, `<rect width="${n(Math.hypot(c[0] - a[0], c[1] - a[1]))}" height="${n(height)}" class="u-clay u-clay-side"/>`));
|
|
21
25
|
});
|
|
26
|
+
const [a, c] = [corners[0], corners[2]];
|
|
27
|
+
planes.push({ ...flat("mound-top", "platform", a[0], a[1], c[0], c[1], height, ""), crop: true });
|
|
22
28
|
return planes;
|
|
23
29
|
}
|
|
24
30
|
/** The azuchi's face, a slope from the foot of the mound up to its top, and the target of each shooter standing against it. */
|
|
@@ -54,10 +60,11 @@ export function budoUprights(o, thin) {
|
|
|
54
60
|
const at = (x, y) => [(x - ox) * K, (y - oy) * K];
|
|
55
61
|
const area = { x0: 0, y0: 0, x1: (plan.box.x1 - ox) * K, y1: (plan.box.y1 - oy) * K };
|
|
56
62
|
const items = [];
|
|
57
|
-
|
|
63
|
+
// The floor lies on the hall's floor (`lift` is 0): the mound is a block standing on it, with its own top.
|
|
64
|
+
const lift = 0;
|
|
58
65
|
if (plan.sumo !== undefined) {
|
|
59
|
-
|
|
60
|
-
items.push({ id: "mound", kind: "mound", at: at(plan.sumo.centre[0], plan.sumo.centre[1]), height
|
|
66
|
+
const height = plan.sumo.height * K;
|
|
67
|
+
items.push({ id: "mound", kind: "mound", at: at(plan.sumo.centre[0], plan.sumo.centre[1]), height, planes: moundPlanes(plan, at, height) });
|
|
61
68
|
}
|
|
62
69
|
if (plan.kyudo !== undefined) {
|
|
63
70
|
const built = azuchiPlanes(plan, at);
|
|
@@ -83,5 +90,5 @@ export function budoUprights(o, thin) {
|
|
|
83
90
|
items.push({ id: "walls", kind: "walls", at: centre, height: h, planes });
|
|
84
91
|
}
|
|
85
92
|
void thin;
|
|
86
|
-
return { items, lift, area };
|
|
93
|
+
return { items, lift, area, whole: plan.sumo !== undefined };
|
|
87
94
|
}
|
package/dist/uprights.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface Uprights {
|
|
|
29
29
|
x1: number;
|
|
30
30
|
y1: number;
|
|
31
31
|
};
|
|
32
|
+
/** True when the view is fitted to the whole floor drawing, not to `area` (which is then only where the score board goes): a raised platform stands in a floor that must not be cut at any angle. */
|
|
33
|
+
whole?: boolean;
|
|
32
34
|
/** The patterns the venue's planes are drawn with (the contents of an SVG `defs`), when it has any. */
|
|
33
35
|
defs?: string;
|
|
34
36
|
/** How far the venue reaches beyond the surface, in feet, when it has one: the ground a floor needs for it to stand on. */
|
package/dist/uprights.js
CHANGED
|
@@ -41,6 +41,7 @@ export function uprightsFor(o, settings = {}) {
|
|
|
41
41
|
let lift = 0;
|
|
42
42
|
let thin = 0.2;
|
|
43
43
|
let area;
|
|
44
|
+
let whole = false;
|
|
44
45
|
if (sport === "nfl" || sport === "cfl" || sport === "ifaf") {
|
|
45
46
|
const spec = league?.family === "football" ? fieldOf(league, o.year) : footballIn(sport, o.year);
|
|
46
47
|
const shape = league?.family === "football" || sport === "ifaf" ? "slingshot" : rulesFor(sport, o.year).rules.postShape;
|
|
@@ -112,6 +113,7 @@ export function uprightsFor(o, settings = {}) {
|
|
|
112
113
|
thin = thinnest(area.x1, area.y1);
|
|
113
114
|
items = budoUprights({ ...o, sport }, thin).items;
|
|
114
115
|
lift = built.lift;
|
|
116
|
+
whole = built.whole;
|
|
115
117
|
}
|
|
116
118
|
else if (isFieldSport(sport)) {
|
|
117
119
|
const plan = fieldPlan({ ...o, sport });
|
|
@@ -145,7 +147,7 @@ export function uprightsFor(o, settings = {}) {
|
|
|
145
147
|
}
|
|
146
148
|
if (settings.only !== undefined)
|
|
147
149
|
items = items.filter((item) => settings.only.includes(item.kind));
|
|
148
|
-
return { items, lift, thin, area, ...(defs === "" ? {} : { defs }), ...(reach === 0 ? {} : { reach }) };
|
|
150
|
+
return { items, lift, thin, area, ...(whole ? { whole } : {}), ...(defs === "" ? {} : { defs }), ...(reach === 0 ? {} : { reach }) };
|
|
149
151
|
}
|
|
150
152
|
/** A length in feet as a rulebook would print it in `unit`: metres to the centimetre, feet to a tenth. */
|
|
151
153
|
function said(feet, unit, language) {
|
package/dist/uprights.net.js
CHANGED
|
@@ -100,7 +100,18 @@ export function netUprights(plan, geo, settings, thin) {
|
|
|
100
100
|
items.push({ id: "table", kind: "table-legs", at: [L / 2, W / 2], height: lift, planes: tableBody(0, 0, L, W, lift, thin, false) });
|
|
101
101
|
// The floor of the hall, under the table.
|
|
102
102
|
const room = Math.max(L, W) * 5;
|
|
103
|
-
|
|
103
|
+
// Under the table lies its shadow on that floor, so that the legs stand on something.
|
|
104
|
+
const grow = Math.max(convertLength(0.25, "m", "ft"), thin * 4);
|
|
105
|
+
items.push({
|
|
106
|
+
id: "ground",
|
|
107
|
+
kind: "table-legs",
|
|
108
|
+
at: [L / 2, W / 2],
|
|
109
|
+
height: 0,
|
|
110
|
+
planes: [
|
|
111
|
+
flat("ground", "ground", -room, -room, L + room, W + room, 0, `<rect width="${n(L + 2 * room)}" height="${n(W + 2 * room)}" class="u-ground"/>`),
|
|
112
|
+
flat("table-shadow", "ground", -grow / 2, -grow / 2, L + grow / 2, W + grow / 2, 0.005, `<rect width="${n(L + grow)}" height="${n(W + grow)}" rx="${n(grow)}" class="u-shadow"/>`),
|
|
113
|
+
],
|
|
114
|
+
});
|
|
104
115
|
return { items, lift };
|
|
105
116
|
}
|
|
106
117
|
default:
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** The package's version: the same as package.json's, and a test holds them to each other. */
|
|
2
|
-
export declare const VERSION = "0.12.
|
|
2
|
+
export declare const VERSION = "0.12.2";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** The package's version: the same as package.json's, and a test holds them to each other. */
|
|
2
|
-
export const VERSION = "0.12.
|
|
2
|
+
export const VERSION = "0.12.2";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@johnmorrisdotca/kyogijo-stadiums",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Kyogijo Stadiums 競技場, 39 sports' surfaces as SVG, drawn to scale from the rulebooks: NFL, CFL and IFAF football fields, an NHL rink, an NBA court, MLB ballparks, soccer pitches, curling sheets, athletics stadiums, speed skating, short track and figure skating rinks, swimming pools, water polo fields, diving wells, artistic swimming areas, and the courts and fields of tennis, volleyball (indoor, beach and sitting), badminton, pickleball, table tennis, padel, squash, racquetball, sepak takraw, teqball, roundnet, netball, lacrosse, rugby, Australian football, Gaelic games, cricket, field hockey and handball, and the budo of judo, karate, kendo, sumo and kyudo with a dojo of tatami laid as real units, with each team's name and logo on its side and the score in the middle, stands and a crowd, a pageant of flags, and a 3D view. Light and dark, accessible, a compact badge for lists, a helper for React and a custom element. Zero dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sports",
|