@johnmorrisdotca/kyogijo-stadiums 0.44.1 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +76 -0
- package/dist/areas-entry.d.ts +2 -0
- package/dist/areas-entry.js +2 -0
- package/dist/areas.d.ts +46 -0
- package/dist/areas.js +87 -0
- package/dist/cityctx.d.ts +3 -6
- package/dist/cityctx.data.d.ts +5 -8
- package/dist/cityctx.data.js +5 -7137
- package/dist/cityctx.js +3 -6
- package/dist/cityctx.seattle-center.data.d.ts +3 -0
- package/dist/cityctx.seattle-center.data.js +1883 -0
- package/dist/cityctx.seattle-city.data.d.ts +3 -0
- package/dist/cityctx.seattle-city.data.js +3778 -0
- package/dist/cityctx.seattle-sodo.data.d.ts +3 -0
- package/dist/cityctx.seattle-sodo.data.js +1419 -0
- package/dist/cityctx.vancouver-nature.data.d.ts +3 -0
- package/dist/cityctx.vancouver-nature.data.js +57 -0
- package/dist/context.d.ts +2 -0
- package/dist/context.js +20 -1
- package/dist/district.turn.js +61 -6
- package/dist/judging.mount.js +7 -0
- package/dist/outside.dom.d.ts +5 -0
- package/dist/outside.dom.js +13 -5
- package/dist/quality.d.ts +110 -0
- package/dist/quality.js +160 -0
- package/dist/turn-entry.d.ts +2 -0
- package/dist/turn-entry.js +1 -0
- package/dist/turn.camera.js +17 -7
- package/dist/turn.dom.d.ts +7 -0
- package/dist/turn.dom.js +198 -20
- package/dist/turn.kit.d.ts +5 -0
- package/dist/turn.markup.d.ts +16 -8
- package/dist/turn.markup.js +99 -20
- package/dist/turn.model.d.ts +13 -0
- package/dist/turn.style.js +6 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -1
package/dist/turn.markup.js
CHANGED
|
@@ -9,6 +9,8 @@ import { KYOGIJO_TURN_STYLE } from "./turn.style.js";
|
|
|
9
9
|
import { esc } from "./format.js";
|
|
10
10
|
import { turnBoardMarkup } from "./overlay.js";
|
|
11
11
|
const px = (value) => `${Math.round(value * 1000) / 1000}`;
|
|
12
|
+
/** The share of the layer at `index` (0 the floor, then the planes). */
|
|
13
|
+
const shareOf = (raster, index) => (typeof raster === "number" ? raster : (raster[index] ?? 1));
|
|
12
14
|
/**
|
|
13
15
|
* The matrix that stands a plane in the scene, before the camera: its x along `u`, its y along `v`, its corner `o`, in pixels from the middle of the scene
|
|
14
16
|
* (`centre`, in feet).
|
|
@@ -53,20 +55,88 @@ export function groupRanks(groups, yaw) {
|
|
|
53
55
|
}));
|
|
54
56
|
return rank;
|
|
55
57
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
const RAD = Math.PI / 180;
|
|
59
|
+
const prepared = new WeakMap();
|
|
60
|
+
function prepare(model) {
|
|
61
|
+
const known = prepared.get(model.planes);
|
|
62
|
+
if (known !== undefined && known.scale === model.scale && known.centre[0] === model.centre[0] && known.centre[1] === model.centre[1])
|
|
63
|
+
return known;
|
|
64
|
+
const s = model.scale;
|
|
65
|
+
const centre = model.centre;
|
|
66
|
+
const base = [];
|
|
67
|
+
const mid = [];
|
|
68
|
+
for (const p of model.planes) {
|
|
69
|
+
if (p.billboard === true) {
|
|
70
|
+
base.push(undefined);
|
|
71
|
+
mid.push(undefined);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
base.push(planeMatrix(p, s, centre));
|
|
75
|
+
if (p.under === true) {
|
|
76
|
+
mid.push(undefined);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const zs = [p.o[2], p.o[2] + p.u[2], p.o[2] + p.v[2], p.o[2] + p.u[2] + p.v[2]];
|
|
80
|
+
mid.push([(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, Math.min(...zs) * s, Math.max(...zs) * s]);
|
|
81
|
+
}
|
|
82
|
+
const made = { planes: model.planes, scale: s, centre, base, mid };
|
|
83
|
+
prepared.set(model.planes, made);
|
|
84
|
+
return made;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Whether a plane is turned away from the eye, given its matrix: the sign of the determinant of the 3 by 3 map from the plane's own x and y to the screen says which side of it faces the eye (positive: the side that its `u` x `v`
|
|
88
|
+
* points out of), and `Plane.cull` says which side is the solid's outside. A plane edge-on to the eye has no area to draw.
|
|
89
|
+
*/
|
|
90
|
+
const turnedAway = (m, side) => side * (m[0] * (m[5] * m[15] - m[13] * m[7]) - m[4] * (m[1] * m[15] - m[13] * m[3]) + m[12] * (m[1] * m[7] - m[5] * m[3])) <= 0;
|
|
91
|
+
/**
|
|
92
|
+
* Work a view out in a container `width` by `height` pixels. With `cull`, the faces of a closed solid that are turned away from the eye (`Plane.cull`) are left out: they have no transform and no place in the stack, and `culled` says
|
|
93
|
+
* which, so that a page need not write them at all; without it every plane is laid out, as a still picture needs. `raster` is the share of its size an element is made at (`rasterOf`): each element's matrix widens it back, so that the
|
|
94
|
+
* picture is the same and the layers hold `raster` squared as many pixels.
|
|
95
|
+
*/
|
|
96
|
+
export function layoutOf(model, view, width, height, lens, cull = false, raster = 1) {
|
|
58
97
|
const distance = eyeDistance(width, height, lens ?? model.lens);
|
|
59
98
|
const at = fit(model.box, { ...view, zoom: 1 }, width, height, distance);
|
|
60
99
|
const camera = cameraMatrix(view, at, distance);
|
|
61
100
|
const s = model.scale;
|
|
62
101
|
const centre = model.centre;
|
|
102
|
+
const known = prepare(model);
|
|
63
103
|
const floor = { id: "floor", kind: "ground", o: [model.viewBox.x, model.viewBox.y, model.uprights.lift], u: [model.viewBox.w, 0, 0], v: [0, model.viewBox.h, 0], svg: "" };
|
|
104
|
+
const count = model.planes.length;
|
|
105
|
+
const widen = (m, index) => {
|
|
106
|
+
const share = shareOf(raster, index);
|
|
107
|
+
if (share === 1)
|
|
108
|
+
return m;
|
|
109
|
+
const back = 1 / share;
|
|
110
|
+
for (let i = 0; i < 8; i += 1)
|
|
111
|
+
m[i] *= back;
|
|
112
|
+
return m;
|
|
113
|
+
};
|
|
114
|
+
const transforms = new Array(count + 1);
|
|
115
|
+
const culled = cull ? new Array(count + 1).fill(false) : undefined;
|
|
64
116
|
// A billboard faces the eye at this view.
|
|
65
|
-
const planes =
|
|
66
|
-
|
|
117
|
+
const planes = new Array(count);
|
|
118
|
+
for (let i = 0; i < count; i += 1)
|
|
119
|
+
planes[i] = facing(model.planes[i], view.yaw, view.pitch);
|
|
120
|
+
transforms[0] = matrix3d(widen(multiply(camera, planeMatrix(floor, s, centre)), 0));
|
|
121
|
+
for (let i = 0; i < count; i += 1) {
|
|
122
|
+
const m = widen(multiply(camera, known.base[i] ?? planeMatrix(planes[i], s, centre)), i + 1);
|
|
123
|
+
const side = planes[i].cull;
|
|
124
|
+
if (culled !== undefined && side !== undefined && turnedAway(m, side)) {
|
|
125
|
+
culled[i + 1] = true;
|
|
126
|
+
transforms[i + 1] = "";
|
|
127
|
+
}
|
|
128
|
+
else
|
|
129
|
+
transforms[i + 1] = matrix3d(m);
|
|
130
|
+
}
|
|
67
131
|
// 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
|
|
68
132
|
// 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.
|
|
69
|
-
const
|
|
133
|
+
const [sinYaw, cosYaw, sinPitch, cosPitch] = [Math.sin(view.yaw * RAD), Math.cos(view.yaw * RAD), Math.sin(view.pitch * RAD), Math.cos(view.pitch * RAD)];
|
|
134
|
+
const k = at.k * view.zoom;
|
|
135
|
+
const depthAt = (x, y, z) => (x * k * sinYaw + y * k * cosYaw) * sinPitch + z * k * cosPitch;
|
|
136
|
+
const depth = (p, i) => {
|
|
137
|
+
const pre = i < 0 ? undefined : known.mid[i];
|
|
138
|
+
if (pre !== undefined)
|
|
139
|
+
return depthAt(pre[0], pre[1], p.fadeSide === true ? (fadeOf(p, view.yaw, view.pitch) >= 1 ? pre[3] : pre[4]) : pre[2]);
|
|
70
140
|
// A see-through building's wall is a tall plane round what stands in it: a far wall is behind all of it and a near one in front of all of it, however high its middle is, so a far wall is placed by its foot and a near one by its top.
|
|
71
141
|
const zs = [p.o[2], p.o[2] + p.u[2], p.o[2] + p.v[2], p.o[2] + p.u[2] + p.v[2]];
|
|
72
142
|
const z = p.fadeSide === true ? (fadeOf(p, view.yaw, view.pitch) >= 1 ? Math.min(...zs) : Math.max(...zs)) : (p.o[2] + (p.u[2] + p.v[2]) / 2);
|
|
@@ -75,7 +145,12 @@ export function layoutOf(model, view, width, height, lens) {
|
|
|
75
145
|
return 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, z * s], view, at);
|
|
76
146
|
};
|
|
77
147
|
const raised = model.uprights.lift > 0;
|
|
78
|
-
const order = [
|
|
148
|
+
const order = [];
|
|
149
|
+
for (let i = 0; i < count; i += 1)
|
|
150
|
+
if (planes[i].kind !== "ground" && culled?.[i + 1] !== true)
|
|
151
|
+
order.push({ i: i + 1, depth: depth(planes[i], i), group: planes[i].group });
|
|
152
|
+
if (raised)
|
|
153
|
+
order.push({ i: 0, depth: depth(floor, -1), group: undefined });
|
|
79
154
|
// Buildings that stand apart are drawn one after another, the far one first; a plane of none (the floor) goes by its depth alone.
|
|
80
155
|
const rank = model.groups === undefined ? undefined : groupRanks(model.groups, view.yaw);
|
|
81
156
|
// The planes of the blocks that stand round the buildings (`APART`) are stacked by depth among themselves and then woven into the buildings' by depth, each list keeping its own order.
|
|
@@ -84,24 +159,28 @@ export function layoutOf(model, view, width, height, lens) {
|
|
|
84
159
|
order.length = 0;
|
|
85
160
|
for (let i = 0, j = 0; i < own.length || j < apart.length;)
|
|
86
161
|
order.push(j >= apart.length || (i < own.length && own[i].depth <= apart[j].depth) ? own[i++] : apart[j++]);
|
|
87
|
-
const stack = new Array(
|
|
162
|
+
const stack = new Array(count + 1).fill(0);
|
|
88
163
|
stack[0] = 1;
|
|
89
164
|
order.forEach((one, rank) => {
|
|
90
165
|
stack[one.i] = rank + 2;
|
|
91
166
|
});
|
|
92
|
-
const fade =
|
|
93
|
-
|
|
167
|
+
const fade = new Array(count + 1);
|
|
168
|
+
fade[0] = 1;
|
|
169
|
+
for (let i = 0; i < count; i += 1)
|
|
170
|
+
fade[i + 1] = fadeOf(model.planes[i], view.yaw, view.pitch);
|
|
171
|
+
return { at, transforms, stack, fade, ...(culled === undefined ? {} : { culled }) };
|
|
94
172
|
}
|
|
95
173
|
/** One plane as an element: its box in pixels and the SVG drawn on it in feet. */
|
|
96
|
-
export function planeMarkup(p, scale, transform, stack, fade = 1) {
|
|
174
|
+
export function planeMarkup(p, scale, transform, stack, fade = 1, raster = 1) {
|
|
97
175
|
const [w, h] = size(p);
|
|
98
|
-
|
|
176
|
+
const [bw, bh] = [px(w * scale * raster), px(h * scale * raster)];
|
|
177
|
+
return `<div class="ky-up ky-up-${p.kind}" data-part="${esc(p.id)}" style="width:${bw}px;height:${bh}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="${bw}" height="${bh}" aria-hidden="true" focusable="false">${p.svg}</svg></div>`;
|
|
99
178
|
}
|
|
100
179
|
/**
|
|
101
180
|
* 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
|
|
102
181
|
* description: it carries no role, title or description of its own.
|
|
103
182
|
*/
|
|
104
|
-
export function cropMarkup(model, p, transform, stack, fade = 1) {
|
|
183
|
+
export function cropMarkup(model, p, transform, stack, fade = 1, raster = 1) {
|
|
105
184
|
const [w, h] = size(p);
|
|
106
185
|
const box = `${px(p.o[0])} ${px(p.o[1])} ${px(w)} ${px(h)}`;
|
|
107
186
|
const picture = model.floor
|
|
@@ -111,12 +190,12 @@ export function cropMarkup(model, p, transform, stack, fade = 1) {
|
|
|
111
190
|
.replace(/^<svg([^>]*?)\srole="img"/, '<svg$1 aria-hidden="true"')
|
|
112
191
|
.replace(/^<svg([^>]*?)\saria-labelledby="[^"]*"/, "<svg$1")
|
|
113
192
|
.replace(/<title\b[^>]*>[\s\S]*?<\/title>|<desc\b[^>]*>[\s\S]*?<\/desc>/g, "");
|
|
114
|
-
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>`;
|
|
193
|
+
return `<div class="ky-up ky-up-${p.kind}" data-part="${esc(p.id)}" data-crop="floor" style="width:${px(w * model.scale * raster)}px;height:${px(h * model.scale * raster)}px;transform:${transform};z-index:${stack}${fade < 1 ? `;opacity:${n(fade)}` : ""}">${picture}</div>`;
|
|
115
194
|
}
|
|
116
195
|
/** The floor as an element: the flat drawing, in the pixels of the scene. */
|
|
117
|
-
export function floorMarkup(model, transform, stack) {
|
|
196
|
+
export function floorMarkup(model, transform, stack, raster = 1) {
|
|
118
197
|
const vb = model.viewBox;
|
|
119
|
-
return `<div class="ky-turn-floor" style="width:${px(vb.w * model.scale)}px;height:${px(vb.h * model.scale)}px;transform:${transform};z-index:${stack}">${model.floor}</div>`;
|
|
198
|
+
return `<div class="ky-turn-floor"${raster === 1 ? "" : ` data-raster="${raster}"`} style="width:${px(vb.w * model.scale * raster)}px;height:${px(vb.h * model.scale * raster)}px;transform:${transform};z-index:${stack}">${model.floor}</div>`;
|
|
120
199
|
}
|
|
121
200
|
/** 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. */
|
|
122
201
|
export function defsMarkup(model) {
|
|
@@ -131,8 +210,8 @@ export function worldAttributes(model) {
|
|
|
131
210
|
return model.look === undefined ? 'class="ky-turn-world"' : `class="ky-turn-world kyogijo" data-sport="${esc(model.look.sport)}" data-look="${esc(model.look.look)}"${theme === "light" || theme === "dark" ? ` data-theme="${theme}"` : ""}`;
|
|
132
211
|
}
|
|
133
212
|
/** The floor and the planes of a model, laid out. */
|
|
134
|
-
export function worldMarkup(model, layout) {
|
|
135
|
-
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("");
|
|
213
|
+
export function worldMarkup(model, layout, raster = 1) {
|
|
214
|
+
return defsMarkup(model) + floorMarkup(model, layout.transforms[0], layout.stack[0], shareOf(raster, 0)) + model.planes.map((p, i) => (p.crop === true ? cropMarkup(model, p, layout.transforms[i + 1], layout.stack[i + 1], layout.fade[i + 1], shareOf(raster, i + 1)) : planeMarkup(p, model.scale, layout.transforms[i + 1], layout.stack[i + 1], layout.fade[i + 1], shareOf(raster, i + 1)))).join("");
|
|
136
215
|
}
|
|
137
216
|
/** The buttons under the view. */
|
|
138
217
|
export function controlsMarkup(model, view, playing = false, direction = "counterclockwise") {
|
|
@@ -157,18 +236,18 @@ export function controlsMarkup(model, view, playing = false, direction = "counte
|
|
|
157
236
|
/** The size, in pixels, the first view is worked out for. */
|
|
158
237
|
export const sizeOf = (settings) => settings.size ?? { width: 960, height: 600 };
|
|
159
238
|
/** The 3D view of a model as markup, laid out for `settings.size`; a page's script then makes it turn. */
|
|
160
|
-
export function turnMarkupOf(model, settings = {}) {
|
|
239
|
+
export function turnMarkupOf(model, settings = {}, raster = 1) {
|
|
161
240
|
const words = turnWords(model);
|
|
162
241
|
const { width, height } = sizeOf(settings);
|
|
163
242
|
const view = model.view;
|
|
164
|
-
const layout = layoutOf(model, view, width, height, settings.lens);
|
|
243
|
+
const layout = layoutOf(model, view, width, height, settings.lens, false, raster);
|
|
165
244
|
const keys = `${words.keys}${model.standing === "" ? "" : ` ${model.standing}`}`;
|
|
166
245
|
const sheet = model.options.style === "none" ? "" : `<style>${KYOGIJO_TURN_STYLE}</style>`;
|
|
167
246
|
const theme = model.options.theme;
|
|
168
247
|
const sport = model.options.sport;
|
|
169
248
|
return (`<div class="ky-turn" id="${esc(model.id)}" data-sport="${esc(String(sport))}" data-mode="3d" data-touch="${settings.touch === "turn" ? "turn" : "scroll"}" data-preset="${presetOf(view, model.presets ?? sport) ?? "custom"}"${model.lighting === undefined ? "" : ` data-lighting="${model.lighting}"`}${theme === "light" || theme === "dark" ? ` data-theme="${theme}"` : ""} lang="${model.language}">` +
|
|
170
249
|
sheet +
|
|
171
|
-
`<div class="ky-turn-view" tabindex="0" role="group" aria-roledescription="${esc(words.region)}" aria-label="${esc(model.title)}" aria-describedby="${esc(model.id)}-help" aria-keyshortcuts="ArrowLeft ArrowRight ArrowUp ArrowDown + - 0 1 2 3 4 Home Space"><div ${worldAttributes(model)}>${worldMarkup(model, layout)}</div>${model.board === undefined ? "" : turnBoardMarkup(model.board)}</div>` +
|
|
250
|
+
`<div class="ky-turn-view" tabindex="0" role="group" aria-roledescription="${esc(words.region)}" aria-label="${esc(model.title)}" aria-describedby="${esc(model.id)}-help" aria-keyshortcuts="ArrowLeft ArrowRight ArrowUp ArrowDown + - 0 1 2 3 4 Home Space"><div ${worldAttributes(model)}>${worldMarkup(model, layout, raster)}</div>${model.board === undefined ? "" : turnBoardMarkup(model.board)}</div>` +
|
|
172
251
|
`<p class="ky-turn-help" id="${esc(model.id)}-help">${esc(keys)}</p>` +
|
|
173
252
|
(settings.controls === false ? "" : controlsMarkup(model, view, false, turnDirection(settings.direction))) +
|
|
174
253
|
`<div class="ky-turn-live" role="status" aria-live="polite"></div>` +
|
package/dist/turn.model.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type ResolvedBoard } from "./overlay.ts";
|
|
|
6
6
|
import type { VenueSettings } from "./venue.ts";
|
|
7
7
|
import type { Box3 } from "./turn.camera.ts";
|
|
8
8
|
import type { OutsideSpec } from "./outside.dom.ts";
|
|
9
|
+
import type { GovernorTuning, Quality, QualityTier } from "./quality.ts";
|
|
9
10
|
import type { Language, LightingOptions, LightingPreset, ScoreOptions, SurfaceOptions } from "./types.ts";
|
|
10
11
|
/** What can be asked of a 3D view. */
|
|
11
12
|
export interface TurnSettings {
|
|
@@ -53,6 +54,16 @@ export interface TurnSettings {
|
|
|
53
54
|
onDirectionChange?: (direction: TurnDirection) => void;
|
|
54
55
|
/** Called with `true` when the auto-turn starts and `false` when it stops, whatever stopped it. */
|
|
55
56
|
onPlayChange?: (playing: boolean) => void;
|
|
57
|
+
/**
|
|
58
|
+
* How much the view draws, so that it turns well on every device: `"auto"` (the default) starts on `high` and watches the frames the view makes while it turns, stepping a tier down when they run over budget for a while and back up
|
|
59
|
+
* when they have been steady for longer; `"high"` is everything as it always was; `"medium"` and `"low"` draw less (the buildings round a district stand up fewer, the trees and the crowd are thinner, a small venue is a block, and the layers
|
|
60
|
+
* are rastered at a lower pixel ratio). A tier asked for by name is kept; `setQuality` changes it at once, and the camera and the auto-turn go on. See `docs/quality.md`.
|
|
61
|
+
*/
|
|
62
|
+
quality?: Quality;
|
|
63
|
+
/** How the frames are judged in `auto` (see `GovernorTuning`): for a test or a screen that is unusual; the defaults suit a 60 Hz display. */
|
|
64
|
+
qualityTuning?: Partial<GovernorTuning>;
|
|
65
|
+
/** Called with the tier the view is drawn at when it is first mounted and each time `auto` or `setQuality` changes it. */
|
|
66
|
+
onQualityChange?: (tier: QualityTier, quality: Quality) => void;
|
|
56
67
|
/** Called after the view has changed by a key, a button or the pointer, with the view and the viewpoint it is (`undefined` when it has been turned by hand). */
|
|
57
68
|
onChange?: (view: TurnView, preset: TurnPreset | undefined) => void;
|
|
58
69
|
}
|
|
@@ -113,6 +124,8 @@ export interface TurnModel {
|
|
|
113
124
|
}[];
|
|
114
125
|
/** The board the options ask for (`board`), laid over the view: a layer of its own, never a plane of the scene. */
|
|
115
126
|
board?: ResolvedBoard;
|
|
127
|
+
/** Whether the model has tiers: a district's does (`quality`), a single surface's does not, and the view does not time its frames or make its layers smaller for one that has none. */
|
|
128
|
+
tiered?: boolean;
|
|
116
129
|
/** The crowd outside the venues of a district, asked for (`DistrictOptions.outside`): a canvas on the floor that the mount paints (`outside.dom.ts`), never a plane of the scene. */
|
|
117
130
|
outside?: OutsideSpec;
|
|
118
131
|
}
|
package/dist/turn.style.js
CHANGED
|
@@ -80,6 +80,12 @@ export const KYOGIJO_TURN_STYLE = `
|
|
|
80
80
|
.ky-turn .u-slab-top{fill:var(--ky-up-blk-roof);stroke:var(--ky-up-blk-line);stroke-width:.5}
|
|
81
81
|
.ky-turn .u-floorplate{fill:var(--ky-up-plate);stroke:var(--ky-up-plate-line);stroke-width:1.2;stroke-linejoin:round}
|
|
82
82
|
.ky-turn .u-block-roof{fill:var(--ky-up-blk-roof);stroke:var(--ky-up-blk-line);stroke-width:.5;stroke-linejoin:round}
|
|
83
|
+
/* A venue drawn as a proxy in the lower tiers (district.turn.ts): the tones of the buildings round it, darker and bluer, as a stadium's concrete and roof read against a city's. */
|
|
84
|
+
.ky-turn .u-proxy{stroke:var(--ky-up-blk-line);stroke-width:.6}
|
|
85
|
+
.ky-turn .u-proxy-a{fill:color-mix(in srgb,var(--ky-up-blk-a) 52%,#4d6fa0)}
|
|
86
|
+
.ky-turn .u-proxy-b{fill:color-mix(in srgb,var(--ky-up-blk-b) 52%,#3f5c88)}
|
|
87
|
+
.ky-turn .u-proxy-c{fill:color-mix(in srgb,var(--ky-up-blk-c) 52%,#324b72)}
|
|
88
|
+
.ky-turn .u-proxy-roof{fill:color-mix(in srgb,var(--ky-up-blk-roof) 60%,#5f7fae);stroke:var(--ky-up-blk-line);stroke-width:.6;stroke-linejoin:round}
|
|
83
89
|
.ky-turn .u-roof{fill:var(--ky-up-roof);stroke:var(--ky-up-roofline);stroke-width:.8;stroke-linejoin:round}
|
|
84
90
|
.ky-turn .u-signplate{fill:var(--ky-turn-bg);fill-opacity:.9;stroke:var(--ky-turn-rule);stroke-width:.5}
|
|
85
91
|
.ky-turn .u-sign{fill:var(--ky-turn-ink);font-family:var(--ky-font,system-ui,-apple-system,"Segoe UI","Hiragino Sans","Noto Sans JP",sans-serif);font-weight:600}
|
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.
|
|
2
|
+
export declare const VERSION = "0.45.0";
|
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.
|
|
2
|
+
export const VERSION = "0.45.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@johnmorrisdotca/kyogijo-stadiums",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "Kyogijo Stadiums 競技場, 40 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, the MMA cage, 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",
|
|
@@ -153,6 +153,11 @@
|
|
|
153
153
|
"import": "./dist/cityctx-entry.js",
|
|
154
154
|
"default": "./dist/cityctx-entry.js"
|
|
155
155
|
},
|
|
156
|
+
"./areas": {
|
|
157
|
+
"types": "./dist/areas-entry.d.ts",
|
|
158
|
+
"import": "./dist/areas-entry.js",
|
|
159
|
+
"default": "./dist/areas-entry.js"
|
|
160
|
+
},
|
|
156
161
|
"./osm": {
|
|
157
162
|
"types": "./dist/osm-entry.d.ts",
|
|
158
163
|
"import": "./dist/osm-entry.js",
|