@johnmorrisdotca/kyogijo-stadiums 0.7.0 → 0.9.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 +28 -0
- package/NOTICE.md +1 -0
- package/README.md +22 -20
- package/dist/budo/looks.js +1 -1
- package/dist/budo/room.d.ts +34 -2
- package/dist/budo/room.js +39 -7
- package/dist/budo/types.d.ts +6 -1
- package/dist/budo.style.d.ts +1 -1
- package/dist/budo.style.js +6 -3
- package/dist/charts.athletics.js +4 -3
- package/dist/charts.d.ts +8 -0
- package/dist/charts.js +13 -0
- package/dist/charts.skating.js +9 -7
- package/dist/crowd.d.ts +4 -0
- package/dist/crowd.draw.d.ts +5 -0
- package/dist/crowd.draw.js +34 -5
- package/dist/crowd.js +6 -1
- package/dist/draw.js +28 -15
- package/dist/element-entry.d.ts +2 -0
- package/dist/element-entry.js +1 -0
- package/dist/element.d.ts +3 -3
- package/dist/element.js +20 -3
- package/dist/flags-source.d.ts +37 -0
- package/dist/flags-source.js +60 -0
- package/dist/halls.js +4 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/layers.env.js +5 -2
- package/dist/layers.js +2 -1
- package/dist/logo.d.ts +6 -0
- package/dist/logo.js +8 -0
- package/dist/pool.labels.js +5 -3
- package/dist/pool.race.d.ts +2 -0
- package/dist/pool.race.js +1 -0
- package/dist/pool.types.d.ts +2 -0
- package/dist/strings.d.ts +7 -1
- package/dist/strings.js +6 -4
- package/dist/surfaces/budo.js +22 -2
- package/dist/team.lineup.js +2 -2
- package/dist/team.types.d.ts +2 -0
- package/dist/turn-entry.d.ts +2 -0
- package/dist/turn-entry.js +1 -0
- package/dist/turn.dom.d.ts +8 -0
- package/dist/turn.dom.js +147 -8
- package/dist/turn.kit.d.ts +5 -3
- package/dist/turn.kit.js +1 -1
- package/dist/turn.markup.d.ts +8 -1
- package/dist/turn.markup.js +18 -4
- package/dist/turn.model.d.ts +26 -0
- package/dist/turn.model.js +34 -3
- package/dist/turn.style.js +58 -4
- package/dist/types.d.ts +11 -0
- package/dist/uprights.d.ts +7 -0
- package/dist/uprights.js +15 -1
- package/dist/venue.d.ts +31 -0
- package/dist/venue.geom.d.ts +53 -0
- package/dist/venue.geom.js +225 -0
- package/dist/venue.js +172 -0
- package/dist/venue.room.d.ts +9 -0
- package/dist/venue.room.js +240 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,34 @@ All notable changes to this project are written here. The format follows
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-10-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Country flags from a plug-in: `useFlags(render)` and the `flags` option.** A team takes a country's code, `flag: "CA"`, and the flag is drawn by a function you plug in, as the emblems are by `useEmblems`. The renderer is `(code, { shape, size, theme }) => string` (an SVG document, or nothing for a code it has no flag for), synchronous because a drawing is a pure function of its options: it is the shape [Taisen Brackets](https://www.npmjs.com/package/@johnmorrisdotca/taisen-brackets) takes, so one adapter over [Hata](https://github.com/johnmorrisdotca/hata) serves both. `shape` is `round` (a round mark, a pageant's stage), `rect` (a plain mark, a banner, a badge, a pageant's carpet, in its own proportions) or `square`; `size` is a nominal width in pixels; `theme` is `light`, `dark` or `inherit`. `useFlags` is in the main entry and in `/element`; `flags: render` in the options of a drawing (or the `surface` of a chart) wins over it for that drawing. The same code works for `Swimmer.country` and `LineupPlayer.country` (where `flag` is missing), for the `country` of an athlete or a skater of a lane draw or a start list, a layer's mark of the shape `logo` for a team, and the element's `home-flag` and `away-flag` attributes. A team's `flag` wins over its `logo` where the renderer has a flag for the code; with no renderer, or none for the code, a drawing is the text it was (and a code that is not a code is never asked about). A round flag turns with its team's name as a round logo does. Kyogijo imports no flag and keeps no dependencies; `@johnmorrisdotca/hata` 1.5.0 is a development dependency (for the demo and the tests) and an optional peer one. [Flags](./docs/flags.md).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **The demo's teams are real countries, drawn with Hata's flags.** The made-up teams (Harbour City Gulls and the rest) and the sixteen made-up nations of `demo/nations.js` are replaced by Canada, USA, Japan, Mexico, Australia, Brazil, England, Korea, Germany, France and Italy, each with its national flag through the plug-in (the build loads the flags it draws from Hata into the page), and the pool's swimmers, who still do not exist, swim for real countries. The demo's teams have a new "Flag" logo choice, the default; "Own logo" shows a logo of your own beside it: a maple leaf with the word CANADA, a red sun disc with the word JAPAN and, for the others, a roundel of their letters, all drawn in the demo's code. No federation's crest or logo, and no Olympic rings, is used. The embedded frame takes `aflag` and `hflag`. The made-up nations stay, for the tests only, in `src/nations.fixture.ts`, so that no drawing in a test changed.
|
|
19
|
+
|
|
20
|
+
## [0.8.0] - 2026-10-14
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **The venue in the 3D view** ([docs/turn.md](./docs/turn.md#the-venue)): the stands, roofs and rooms round a surface are raised from the data the package already has, so that a whole stadium, ballpark, arena or dojo turns by mouse drag, finger, keys and buttons. Every tier of `crowdStands()` is a strip of raked planes (a quad to each straight side, three to each corner, a ballpark's points, 28 round an oval) from the height of its first row to its last, with the crowd's own pattern as texture (people, empty seats, row lines, aisles, the visitors' block, the tifo), the walks between the tiers, a low wall under the first row, and the places the stands are left open left open. A ballpark gets its grandstands and bleachers and, where the park has them, the seats on top of the wall (Fenway Park's Green Monster at 37 ft 2 in). A dojo gets its cream walls over a wood wainscot, painted in the floor's own look, with the doors and windows of `dojoRoom()`, the dais, the banner, the shrine, the balconies as steps of seats behind a rail with the crowd in them, overlooking the floor, and the thickness of the mats at their edge. `venue: true | false | { roof, detail }` is the switch: on when the drawing has a `crowd` or is a dojo, off with `uprights: false`; `roof: true` adds a canopy over the top tier or a lid over a hall. The stands and walls fade on the side nearest the eye as the boards do, so the surface is never hidden. A full soccer bowl is about 110 planes and 500 elements and the biggest venues under 1,000, whatever the seats taken; `detail` cuts the curves coarser or finer. The element reads `turn-venue="false"` and `turn-roof`; the demo has a Roof toggle in 3D.
|
|
25
|
+
- **An auto-turn for the 3D view**, a trophy case's slow turn: an Auto-turn toggle button (`aria-pressed`, 44 pixels or more, in English and Japanese) and Space start and stop it; `autoPlay` (`true`, or `"force"`) is the opt-in start, `speed` its degrees a second, `onPlayChange` its callback, and the handle has `playing`, `play()`, `pause()` and `togglePlay()`. It holds while the pointer holds the view, does nothing on a hidden page or off the screen, is stopped by the arrow keys, a viewpoint, the reset or `set`, starts paused for a reader who prefers reduced motion, and moves nothing until Play is pressed unless `autoPlay` asks. The element reads `turn-autoplay` and `turn-speed`.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **The Kodokan's gallery is as its owner counts it, in 2D and 3D.** `dojo.balcony` takes `rows` and `sections` (the seats in each block of a row, with an aisle between blocks, the same on every side): the main dojo has `{ rows: 3, sections: [5, 8, 8, 8, 5] }`, 34 seats to a row and 102 to a side, per the owner and his photographs. `dojoRoom()`'s balconies carry `sections`, `seatWidth`, `aisle`, `aisles` (the shares of a side the aisles lie at) and `sectionsBasis`, and `dojoGallery()` returns `sections` and `aisles`; a side with no `sections` is cut into blocks of about 9 m (ours). The gallery is 3 rows deep by default and its seats are empty: a dojo's crowd density defaults to 0 and people are drawn only when `density` or `attendance` asks. In 2D the aisles lie across the band and each row is dashed cushions with a darker line of backs; in 3D the seats are dark brown cushions and backs in blocks on dark treads, the aisles lighter wood with their stairs, a white rail, honey wood panelling on the walls under the gallery, plain off-white above it with a clock, two doors and three windows, the kamiza's alcove with a framed shrine, a scroll and a plain purple banner, and, with `roof: true`, a pale ceiling band with box lights. The surround of a dojo (when it has one) is polished hardwood: the basketball floor's boards and seams, at half strength, under a warm satin sheen.
|
|
30
|
+
|
|
31
|
+
- **A dojo's gallery is a proper balcony in 3D and neat seat rows in 2D.** In 3D each balcony has a floor slab that projects over the room (with its thickness showing), a white rail with two bars and posts on its edge, and four tiers of seats drawn as cushions and backs, a seat every 0.6 m, on light treads. In 2D, from above, the gallery is rows of seats along its band (a dashed line to a row, in the gallery's brown) and not a ring of round heads; `crowd` still gives the people in the 3D balcony. The Kodokan's four areas are the IJF's block (8 m areas, 4 m shared safety between them, 3.2 m round in the 26.4 m square of 420 jō): the pale areas are 256 m² of 697.
|
|
32
|
+
|
|
33
|
+
- **The mats look like mats, in 2D and 3D.** The seams between tatami are drawn a few per cent darker than the mat (ink at 12%, they were 26%), the weave is dark ridges 3% deep at most (it had white ridges 14% deep), the faint light line on the mat edges is a 4% dark one, and the heri, which drew heavy dark bands between the mats, is as faint as a seam unless `colours.heri` names a colour (`--ky-bud-hop` then restores its 0.82). A contest area is just another colour of mat. The walls of every look are a light cream, not a dark grey. This is the drawing of the dojo, judo, karate and kendo themselves, so every drawing of them changes (their fingerprints in the identity test are made again).
|
|
34
|
+
- **The dojo's room is a storey high and its gallery is on the upper level.** A dojo with a gallery has walls 4.5 m high, the gallery's floor level with their tops (it was 3 m walls under a gallery at 4 m), the gallery as steps of seats behind a white rail, three large windows high in the wall behind it on the east side, and, with `roof: true`, a pale ceiling over it; `dojoRoom()` gives `upperWindows` and `ceiling` (all ours). The Kodokan's main dojo has a polished wood floor 4 m wide all round the mats (it was 1 m), so its walls stand far out.
|
|
35
|
+
|
|
36
|
+
- A 3D view with a crowd no longer lays the flat crowd on its floor: the stands are planes, and the floor is the surface with the ground they stand on. `venue: false` gives the flat crowd back. The crowd's `patterns()` take an optional row-lines argument (the 2D drawing is byte for byte as it was).
|
|
37
|
+
|
|
10
38
|
## [0.7.0] - 2026-10-14
|
|
11
39
|
|
|
12
40
|
### Removed
|
package/NOTICE.md
CHANGED
|
@@ -45,6 +45,7 @@ picture or code of the sources is copied; each source is named here so that the
|
|
|
45
45
|
| `parks`: the coordinates of each ballpark (`lat`, `lon`) and the years it opened and closed (`opened`, `closed`) | The item's coordinate location (P625), its date of official opening or inception (P1619, P571) and of official closure or dissolution (P3999, P576), read with the Wikidata API by `scripts/fetch-park-coordinates.mjs` and checked by `scripts/check-parks.mjs` (ES CON Field's opening, 2023, is read from its article) | Wikidata's data is CC0 (https://creativecommons.org/publicdomain/zero/1.0/) |
|
|
46
46
|
| `events`: the special games, their days, venues, hosts and where a surface stood | The English Wikipedia articles of each game and of its venue, at the revision cited below, and three articles of the press (Sports Video Group, NHL.com, The Boston Globe), named below with their authors and dates; the size of a carrier from the Nimitz class's article | Facts, CC BY-SA 4.0 articles as above; no text copied |
|
|
47
47
|
| The atlas (`@johnmorrisdotca/kyogijo-stadiums/atlas`): the places and their map | The parks, grounds and arenas above, joined; the demo's and docs/atlas.md's map is drawn by chizu (MIT) from Natural Earth, which is in the public domain (https://www.naturalearthdata.com/about/terms-of-use/) | Facts and CC0 data; Natural Earth is public domain; chizu is a development dependency and none of it is in the package |
|
|
48
|
+
| The demo's country flags | [Hata](https://github.com/johnmorrisdotca/hata) (`@johnmorrisdotca/hata`, a development dependency): the flags of the countries in `demo/nations.js`, loaded when the demo is built and written into the demo site with Hata's licence and notice (`site/hata/`); the package itself draws no flag | Hata is MIT; each flag's own source, author and licence are in Hata's NOTICE.md |
|
|
48
49
|
|
|
49
50
|
## The ballparks' articles
|
|
50
51
|
|
package/README.md
CHANGED
|
@@ -20,14 +20,14 @@ The NFL, CFL and IFAF football fields, the NHL rink, the NBA court, the soccer p
|
|
|
20
20
|
<td align="center" valign="top">
|
|
21
21
|
<picture>
|
|
22
22
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/hero-desk-dark.webp">
|
|
23
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/hero-desk-light.webp" alt="The demo on a desk, in English: the heading Kyogijo Stadiums with the language chooser, the Docs and API reference links, five cloth patches and the Help switch, and an NHL rink drawn wide on green felt, with a made-up game on it, the
|
|
23
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/hero-desk-light.webp" alt="The demo on a desk, in English: the heading Kyogijo Stadiums with the language chooser, the Docs and API reference links, five cloth patches and the Help switch, and an NHL rink drawn wide on green felt, with a made-up game on it, the USA and its flag on the left, Canada and its flag on the right, and a panel of the score 3 to 2, Final/OT, in the middle. The controls on the right list the sports, from the NFL and the NHL to handball, and then the layout and the teams." width="640">
|
|
24
24
|
</picture>
|
|
25
25
|
<br><em>The demo on a desk: a rink, with the teams on their sides and the score in the middle.</em>
|
|
26
26
|
</td>
|
|
27
27
|
<td align="center" valign="top">
|
|
28
28
|
<picture>
|
|
29
29
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/hero-phone-dark.webp">
|
|
30
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/hero-phone-light.webp" alt="The demo on a phone: the heading Kyogijo Stadiums over the page's controls, and under them a football field turned a quarter to stand tall,
|
|
30
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/hero-phone-light.webp" alt="The demo on a phone: the heading Kyogijo Stadiums over the page's controls, and under them a football field turned a quarter to stand tall, Mexico's green end zone at the top and the USA's navy end zone at the bottom, each with its flag and name written across it, the yard numbers upright, and a score panel at midfield reading 27 to 24, Final." width="240">
|
|
31
31
|
</picture>
|
|
32
32
|
<br><em>On a phone the same surface stands tall, the words still upright.</em>
|
|
33
33
|
</td>
|
|
@@ -47,12 +47,12 @@ import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
|
|
|
47
47
|
|
|
48
48
|
const svg = drawKyogijo({
|
|
49
49
|
sport: "nhl",
|
|
50
|
-
away: { name: "
|
|
51
|
-
home: { name: "
|
|
50
|
+
away: { name: "USA", abbr: "USA", score: 3, color: "#1c3f7a" },
|
|
51
|
+
home: { name: "Canada", abbr: "CAN", score: 2, color: "#d52b1e" },
|
|
52
52
|
status: "final-ot",
|
|
53
53
|
competition: "Cup Final, Game 7",
|
|
54
54
|
});
|
|
55
|
-
console.log(svg.startsWith("<svg"), svg.includes("
|
|
55
|
+
console.log(svg.startsWith("<svg"), svg.includes("USA 3, Canada 2"));
|
|
56
56
|
// true true
|
|
57
57
|
```
|
|
58
58
|
|
|
@@ -60,7 +60,7 @@ console.log(svg.startsWith("<svg"), svg.includes("Northern Owls 3, Lakeshore Anc
|
|
|
60
60
|
|
|
61
61
|
```html
|
|
62
62
|
<script type="module" src="https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kyogijo-stadiums@0/dist/element-define.js"></script>
|
|
63
|
-
<kyogijo-field sport="nhl" orientation="auto" away="
|
|
63
|
+
<kyogijo-field sport="nhl" orientation="auto" away="USA" home="Canada" away-score="3" home-score="2" status="final-ot"></kyogijo-field>
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## Who it is for
|
|
@@ -94,6 +94,7 @@ console.log(svg.startsWith("<svg"), svg.includes("Northern Owls 3, Lakeshore Anc
|
|
|
94
94
|
- **Lineups.** A `lineup` layer places a team's players by position code (`GK`, `CB`, `HK`, `C`) with no coordinates: it reads where each stands from a formation (36 of them, in 13 sports), draws a disc or a jersey with the shirt number and the name under it, a captain's C and a flag, and puts the visitors at the other end. A drawing with a lineup puts the score in the strip under it, so the panel hides no player. [Lineups](./docs/team-shape.md#lineups).
|
|
95
95
|
- **A pageant.** Each team's flag or crest laid large over its half of the surface, as a stadium lays giant flags and crests for a final: `pageant: "carpet"` (a flag at its own ratio with a border and a gentle fabric) or `"stage"` (a crest on a round disc with a gold ring), an emblem or a trophy of your own in the centre circle, the score in the middle or in the strip, upright wide and tall, in light and dark, with an entrance in CSS for readers who have not asked for less motion. [The pageant](./docs/pageant.md).
|
|
96
96
|
- **Trophies, medals, balls and crests, by id.** `useEmblems(renderEmblem)` plugs in the sister package [Dougu Sports 道具](https://johnmorrisdotca.github.io/dougu-sports/) in one line, and an id goes wherever a logo, a flag or a mark is taken: `logo: "crest:shield"` (a crest in the team's colour with its letters), `pageant: { emblem: "trophy:hockey-cup" }`, `"sport:nhl/line"`, `"ball:puck"`, `"cup"`. Kyogijo bundles no emblem and keeps zero dependencies; without the plug-in an id is refused like any unsafe address. [Emblems](./docs/emblems.md).
|
|
97
|
+
- **Country flags, by code.** `useFlags(render)` plugs in the sister package [Hata 旗](https://github.com/johnmorrisdotca/hata) through a small adapter, and a team's `flag: "CA"` is its flag: round in a round mark, at its own proportions on a banner, a badge or a pageant's carpet. The same adapter serves [Taisen Brackets](https://github.com/johnmorrisdotca/taisen-brackets). Kyogijo bundles no flag and keeps zero dependencies; without the plug-in a code is ignored. [Flags](./docs/flags.md).
|
|
97
98
|
- **Zoom to a part of a surface.** `range: "offensive-zone"` crops a drawing to a rink's zone, a half court, the paint, the red zone, a soccer half, third or penalty area, the infield, a curling house, or a box of your own in any frame, with its data, heat, labels and score following. [Display ranges](./docs/ranges.md).
|
|
98
99
|
- **Wide, tall or fit the box.** Every surface lies wide or tall: tall turns it a quarter, keeps every word upright and puts the teams top and bottom. With `orientation: "auto"` the browser helpers follow the box.
|
|
99
100
|
- **Where a point lies, by the rules, and a click as a place.** `zoneAt("nhl", [69, 22], { frame: "nhl-api" })` names the zone and the area in it from the rink's, court's, pitch's, park's or field's own figures (the offensive zone and its face-off circle, the frontcourt and the corner three, the attacking third and the six-yard box, the infield and the warning track, the red zone and between the hashes), with `isThreePointer`, `inSlot`, `inPenaltyArea`, `isFair`, `overWall` and the like, and `isHomeRun(park, point, { height })` from the park's fence and wall; `clientPointToField(svg, x, y, { provider })` is a pointer's place in any of the frames, with the zone, and `fieldPointToClient` the way back. `marks: true` writes `data-mark-id`, `data-index` and `data-zone` on every mark of a layer, for one listener to link it to a table. [Zones](./docs/zones.md), [pointing](./docs/pointer.md).
|
|
@@ -101,7 +102,7 @@ console.log(svg.startsWith("<svg"), svg.includes("Northern Owls 3, Lakeshore Anc
|
|
|
101
102
|
- **Data on the surface.** Points, lines, arrows, text, heat maps, hexagons, zone charts and density contours over any surface, in its feet or a data provider's frame, cut to its outline, with a table for each layer; ready-made shot and pass charts (the road to a tournament's final moved to [`@johnmorrisdotca/taisen-brackets`](https://www.npmjs.com/package/@johnmorrisdotca/taisen-brackets), its `/road` entry). [Data layers](./docs/layers.md), [charts](./docs/charts.md).
|
|
102
103
|
- **Small multiples and backgrounds.** `drawGrid` puts many drawings in one SVG, under a title and a subtitle, over a credit line, with a key they share, in a size for a social card, a square post or a phone; `background` lays a quiet pattern (felt, grass, wood, ice, paper, a grid, dots) or a photograph behind a drawing or a grid. [Layouts and backgrounds](./docs/layouts.md).
|
|
103
104
|
- **Replay.** Tracking data played on any surface: the players with their numbers, the ball and its trail, and the passes, shots and goals as they happen, with controls, the keyboard and a live region, steps for a reader who prefers reduced motion, and a pause when the page is hidden. [Replay](./docs/replay.md).
|
|
104
|
-
- **A 3D view.** Any surface as a floor that turns by mouse, touch, wheel or keys, with four viewpoints (overhead, broadcast, end-on, low corner) and a reset, and what the rulebook stands on it at its height: the net and antennae of volleyball, the nets of tennis, badminton, pickleball and table tennis, baskets and stanchions, rink boards and glass, goals, the posts of football, rugby, Gaelic and Australian football, stumps, a ballpark's fence, the walls of padel, squash and racquetball (cut away on the side nearest the eye), a swimming pool's blocks and flags, a diving well's boards and platforms, a water polo goal, a jump's uprights and bar, a throwing cage, the hurdles, and the padding of a skating track. Plain DOM and CSS over the same SVG, flat where 3D is not drawn. [The 3D view](./docs/turn.md).
|
|
105
|
+
- **A 3D view.** Any surface as a floor that turns by mouse, touch, wheel or keys, with four viewpoints (overhead, broadcast, end-on, low corner) and a reset, and what the rulebook stands on it at its height: the net and antennae of volleyball, the nets of tennis, badminton, pickleball and table tennis, baskets and stanchions, rink boards and glass, goals, the posts of football, rugby, Gaelic and Australian football, stumps, a ballpark's fence, the walls of padel, squash and racquetball (cut away on the side nearest the eye), a swimming pool's blocks and flags, a diving well's boards and platforms, a water polo goal, a jump's uprights and bar, a throwing cage, the hurdles, and the padding of a skating track; and the venue round it, raised from the same data (the raked stands of a `crowd` with the people on them, a ballpark's grandstands and the seats on its wall, roofs on request, a dojo's walls, dais, banner and gallery), faded on the side nearest the eye, with an auto-turn toggle. Plain DOM and CSS over the same SVG, flat where 3D is not drawn. [The 3D view](./docs/turn.md).
|
|
105
106
|
- **Renderers.** The same drawing as plain data (a scene), on a canvas (a browser's or a Node canvas), in a d3 selection, as a mark of an Observable Plot, as GeoJSON and as a PNG in Node, each an entry of its own that imports nothing from outside the package. [Renderers](./docs/renderers.md).
|
|
106
107
|
- **Units and frames.** Each surface in its rulebook's unit and any other, and 48 coordinate frames (ten soccer providers, the NHL API, HockeyTech, NBA stats, NFL tracking, MLBAM, Retrosheet, a curling stone's place from the button, a place from the net in each net sport (from the centre of the court in squash, racquetball, roundnet and netball), the centre of each field sport's surface, the middle of the water of each pool, the middle of the athletics stadium and of each skating rink) to move a provider's points onto a surface. [Units](./docs/units.md), [coordinate frames](./docs/frames.md).
|
|
107
108
|
- **A compact badge and a compact card.** One strip for a list, or the surface with that strip under it.
|
|
@@ -165,8 +166,8 @@ import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
|
|
|
165
166
|
|
|
166
167
|
const svg = drawKyogijo({
|
|
167
168
|
sport: "nhl",
|
|
168
|
-
away: { name: "
|
|
169
|
-
home: { name: "
|
|
169
|
+
away: { name: "USA", abbr: "USA", score: 3, color: "#1c3f7a" },
|
|
170
|
+
home: { name: "Canada", abbr: "CAN", score: 2, color: "#d52b1e" },
|
|
170
171
|
status: "final-ot",
|
|
171
172
|
competition: "Cup Final, Game 7",
|
|
172
173
|
date: "June 24",
|
|
@@ -178,7 +179,7 @@ console.log(svg.includes("Cup Final, Game 7"), svg.includes("Final/OT"));
|
|
|
178
179
|
<p align="center">
|
|
179
180
|
<picture>
|
|
180
181
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/football-desk-dark.webp">
|
|
181
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/football-desk-light.webp" alt="A football field drawn wide on the demo's felt:
|
|
182
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/football-desk-light.webp" alt="A football field drawn wide on the demo's felt: Mexico's green end zone on the left with its flag and its name written along it, the USA's navy end zone on the right with its flag, the yard lines, hash marks and upright and upside-down yard numbers between them, and the score panel at midfield reading 27 to 24, Final, Championship Game." width="720">
|
|
182
183
|
</picture>
|
|
183
184
|
<br><em>A football field: the end zones in the teams' colours, the score at midfield.</em>
|
|
184
185
|
</p>
|
|
@@ -223,7 +224,7 @@ console.log(box(wide), box(tall));
|
|
|
223
224
|
<p align="center">
|
|
224
225
|
<picture>
|
|
225
226
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/tall-phone-dark.webp">
|
|
226
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/tall-phone-light.webp" alt="A hockey rink standing tall on a phone, the same game as on the desk: the
|
|
227
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/tall-phone-light.webp" alt="A hockey rink standing tall on a phone, the same game as on the desk: the USA's flag and name in the upper zone, Canada's in the lower, each reading upright, the score panel between them over the centre line." width="240">
|
|
227
228
|
</picture>
|
|
228
229
|
<br><em>The same game tall: the teams top and bottom, every word upright.</em>
|
|
229
230
|
</p>
|
|
@@ -258,7 +259,7 @@ console.log(svg.includes("甲子園球場のグラウンド"), svg.includes("阪
|
|
|
258
259
|
<p align="center">
|
|
259
260
|
<picture>
|
|
260
261
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/ballpark-desk-dark.webp">
|
|
261
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/ballpark-desk-light.webp" alt="The baseball field of Hanshin Koshien Stadium with the outfield fence drawn through its published distances, 95 metres at the lines and 118 metres in the alleys and the middle, with mown arcs on the grass, the warning track, the infield dirt, and a red and a
|
|
262
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/ballpark-desk-light.webp" alt="The baseball field of Hanshin Koshien Stadium with the outfield fence drawn through its published distances, 95 metres at the lines and 118 metres in the alleys and the middle, with mown arcs on the grass, the warning track, the infield dirt, and a red and a navy panel in the foul ground at the bottom for the teams' dugouts, each with its country's flag, Japan's and the USA's." width="640">
|
|
262
263
|
</picture>
|
|
263
264
|
<br><em>A ballpark's fence, drawn through the distances its article publishes.</em>
|
|
264
265
|
</p>
|
|
@@ -317,7 +318,7 @@ console.log(/viewBox="0 0 440 64"/.test(badge));
|
|
|
317
318
|
<p align="center">
|
|
318
319
|
<picture>
|
|
319
320
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/badges-desk-dark.webp">
|
|
320
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/badges-desk-light.webp" alt="A list of eight score strips in the demo, each a team block with its
|
|
321
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/badges-desk-light.webp" alt="A list of eight score strips in the demo, each a team block with its country's flag, a short name and its score at each end, in the team's colour, and in the middle a small picture of the sport and the state of the game, such as Final, Final/OT and 2nd period." width="640">
|
|
321
322
|
</picture>
|
|
322
323
|
<br><em>Badges for a list of games.</em>
|
|
323
324
|
</p>
|
|
@@ -338,7 +339,7 @@ console.log(svg.includes("--ky-key:#1e4f8f"), svg.includes("METRO BOLTS"));
|
|
|
338
339
|
<p align="center">
|
|
339
340
|
<picture>
|
|
340
341
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/court-desk-dark.webp">
|
|
341
|
-
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/court-desk-light.webp" alt="A basketball court in the two-tone look: a pale floor with a deep blue key, centre circle and border, the words
|
|
342
|
+
<img src="https://raw.githubusercontent.com/johnmorrisdotca/kyogijo-stadiums/main/docs/images/court-desk-light.webp" alt="A basketball court in the two-tone look: a pale floor with a deep blue key, centre circle and border, the words AUSTRALIA and JAPAN along the baselines, each country's flag and name on its half, and the score panel at centre court reading 108 to 112, Finals, Game 6." width="640">
|
|
342
343
|
</picture>
|
|
343
344
|
<br><em>A court in a look of its own: the paint, the border and the words on the baselines are options.</em>
|
|
344
345
|
</p>
|
|
@@ -396,8 +397,8 @@ import { drawKyogijo, soccerSpec } from "@johnmorrisdotca/kyogijo-stadiums";
|
|
|
396
397
|
|
|
397
398
|
const svg = drawKyogijo({
|
|
398
399
|
sport: "soccer",
|
|
399
|
-
away: { name: "
|
|
400
|
-
home: { name: "
|
|
400
|
+
away: { name: "USA", abbr: "USA", score: 2, penalties: 4, color: "#1c3f7a" },
|
|
401
|
+
home: { name: "Canada", abbr: "CAN", score: 2, penalties: 2, color: "#d52b1e" },
|
|
401
402
|
status: "final-pens",
|
|
402
403
|
ground: "metlife-stadium",
|
|
403
404
|
});
|
|
@@ -511,7 +512,7 @@ import { createKyogijo, kyogijoProps } from "@johnmorrisdotca/kyogijo-stadiums/r
|
|
|
511
512
|
// A component made from your React, which measures its box for orientation="auto":
|
|
512
513
|
const Kyogijo = createKyogijo(React);
|
|
513
514
|
export const Game = () => (
|
|
514
|
-
<Kyogijo sport="nhl" orientation="auto" away={{ name: "
|
|
515
|
+
<Kyogijo sport="nhl" orientation="auto" away={{ name: "USA", score: 3 }} home={{ name: "Canada", score: 2 }} status="final" />
|
|
515
516
|
);
|
|
516
517
|
|
|
517
518
|
// Or props to spread onto your own element; nothing here imports React:
|
|
@@ -540,12 +541,12 @@ Tell Vue the tag is a custom element with `compilerOptions.isCustomElement: (tag
|
|
|
540
541
|
import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
|
|
541
542
|
export let home = 0;
|
|
542
543
|
export let away = 0;
|
|
543
|
-
$: svg = drawKyogijo({ sport: "nhl", away: { name: "
|
|
544
|
+
$: svg = drawKyogijo({ sport: "nhl", away: { name: "USA", score: away }, home: { name: "Canada", score: home } });
|
|
544
545
|
</script>
|
|
545
546
|
|
|
546
547
|
<!-- the string of SVG, or the element: either works -->
|
|
547
548
|
{@html svg}
|
|
548
|
-
<kyogijo-field sport="nhl" away="
|
|
549
|
+
<kyogijo-field sport="nhl" away="USA" home="Canada" away-score={away} home-score={home} />
|
|
549
550
|
```
|
|
550
551
|
|
|
551
552
|
A page that moves (`mountKyogijo`), a file written on a server and a frame for a page with no script are in [getting started](./docs/getting-started.md).
|
|
@@ -684,5 +685,6 @@ The code is [MIT](./LICENSE) © John Morris. The ballparks' fence distances are
|
|
|
684
685
|
| The fence distances of 94 ballparks | The English and Japanese Wikipedia articles of each, at the revision cited | Facts; the articles are CC BY-SA 4.0 and none of their text is used |
|
|
685
686
|
| The Wikidata item of each ballpark | Wikidata, as linked from the cited article | CC0 |
|
|
686
687
|
| 64 soccer grounds | English Wikipedia articles at the revision cited; Wikidata | Facts; CC BY-SA 4.0 articles, no text used; CC0 |
|
|
687
|
-
| The demo's
|
|
688
|
+
| The demo's countries and their logos | The names and codes of real countries; the maple leaf, the sun disc and the roundels are drawn for this package | MIT |
|
|
689
|
+
| The demo's country flags | [Hata](https://github.com/johnmorrisdotca/hata), a development dependency whose flags are loaded into the demo site with its licence and notice; the package itself draws none | MIT, and its flags' own licences in its NOTICE.md |
|
|
688
690
|
| The demo's trophies, medals, balls and crests | [Dougu Sports](https://github.com/johnmorrisdotca/dougu-sports), a development dependency copied into the demo site with its licences; the package itself draws none | MIT, and its sources' licences in its NOTICE.md |
|
package/dist/budo/looks.js
CHANGED
|
@@ -15,7 +15,7 @@ function pair(light, k = 0.34) {
|
|
|
15
15
|
return { light, dark };
|
|
16
16
|
}
|
|
17
17
|
const FLOOR = "#c9a26a";
|
|
18
|
-
const WALLS = "#
|
|
18
|
+
const WALLS = "#d8d0bd";
|
|
19
19
|
const COMMON = { apron: "#d6d3cb", free: "#e8e4d8", floor: FLOOR, boards: WALLS };
|
|
20
20
|
const MATS = {
|
|
21
21
|
"yellow-red": pair({ ...COMMON, surface: "#f4c430", alt: "#c9343b", red: "#b32a2f" }),
|
package/dist/budo/room.d.ts
CHANGED
|
@@ -33,6 +33,16 @@ export interface RoomBalcony {
|
|
|
33
33
|
rowRise: number;
|
|
34
34
|
/** The height of the rail along the front edge. */
|
|
35
35
|
rail: number;
|
|
36
|
+
/** The seats in each block of a row, from one end of the side to the other: an aisle lies between one block and the next. The same in every row. */
|
|
37
|
+
sections: number[];
|
|
38
|
+
/** How wide a seat is, in metres: the side's length less its aisles, over its seats (a seat is 0.6 m or a little more). */
|
|
39
|
+
seatWidth: number;
|
|
40
|
+
/** The width of an aisle, in metres (ours). */
|
|
41
|
+
aisle: number;
|
|
42
|
+
/** Where the aisles' middles lie along the side, as shares of its length from 0 to 1. */
|
|
43
|
+
aisles: number[];
|
|
44
|
+
/** Whether the blocks of seats are the options' (`given`) or cut by us from the side's length. */
|
|
45
|
+
sectionsBasis: "given" | "ours";
|
|
36
46
|
}
|
|
37
47
|
/** The room round a budō surface. */
|
|
38
48
|
export interface DojoRoom {
|
|
@@ -74,6 +84,19 @@ export interface DojoRoom {
|
|
|
74
84
|
balconies: RoomBalcony[];
|
|
75
85
|
doors: RoomOpening[];
|
|
76
86
|
windows: RoomOpening[];
|
|
87
|
+
/** The windows high in the wall behind a gallery (a clerestory): the side, the stretch along the wall from its start (metres), the sill and the head, ours. */
|
|
88
|
+
upperWindows: {
|
|
89
|
+
side: Compass;
|
|
90
|
+
from: number;
|
|
91
|
+
to: number;
|
|
92
|
+
sill: number;
|
|
93
|
+
head: number;
|
|
94
|
+
}[];
|
|
95
|
+
/** How high the room goes above a gallery's floor, for a ceiling over the gallery, and the height of that floor: undefined for a room with no gallery (ours). */
|
|
96
|
+
ceiling: {
|
|
97
|
+
gallery: number;
|
|
98
|
+
height: number;
|
|
99
|
+
} | undefined;
|
|
77
100
|
/** The shrine of a dojo (the shinzen), with its height. */
|
|
78
101
|
shrine: {
|
|
79
102
|
box: MBox;
|
|
@@ -94,6 +117,9 @@ export interface DojoGallery {
|
|
|
94
117
|
offset: number;
|
|
95
118
|
depth: number;
|
|
96
119
|
rows: number;
|
|
120
|
+
/** The seats in each block of a row, and where the aisles lie along a side (shares of its length). */
|
|
121
|
+
sections: number[];
|
|
122
|
+
aisles: number[];
|
|
97
123
|
height: [number, number];
|
|
98
124
|
}
|
|
99
125
|
/** Our heights, in metres, where no source gives one. */
|
|
@@ -107,13 +133,19 @@ export declare const ROOM_HEIGHTS: Readonly<{
|
|
|
107
133
|
windowHead: 2.4;
|
|
108
134
|
shrine: 1.2;
|
|
109
135
|
rail: 1;
|
|
110
|
-
balcony: 4;
|
|
136
|
+
balcony: 4.5;
|
|
137
|
+
ceiling: 4.5;
|
|
111
138
|
mat: 0.05;
|
|
112
139
|
rowRise: 0.4;
|
|
113
140
|
rowDepth: 0.8;
|
|
114
141
|
balconyDepth: 2.4;
|
|
115
|
-
balconyRows:
|
|
142
|
+
balconyRows: 3;
|
|
143
|
+
aisle: 1.2;
|
|
144
|
+
seat: 0.6;
|
|
145
|
+
blockLength: 9.14;
|
|
116
146
|
}>;
|
|
147
|
+
/** The blocks of a row along a side `length` metres long: the options' `given`, else as many as a block of about 9 m allows (two at least), each as many seats as fit at 0.6 m with the aisles between. */
|
|
148
|
+
export declare function sectionsFor(length: number, given?: readonly number[]): number[];
|
|
117
149
|
/**
|
|
118
150
|
* The room of a budō surface as data: what a 3D view raises. A dojo has its walls (3 m, ours), wood surround, dais, banner, balconies, doors, windows and shrine as its spec asks for them; the other
|
|
119
151
|
* surfaces have what they have (the mats' thickness, the dohyō's platform at its height, the Budokan's octagon). Heights that no source gives are ours and are listed in `notes`.
|
package/dist/budo/room.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { dojoSpecOf } from "./dojo.js";
|
|
2
2
|
import { BUDOKAN_ARENA, budoPlan } from "./plan.js";
|
|
3
3
|
/** Our heights, in metres, where no source gives one. */
|
|
4
|
-
export const ROOM_HEIGHTS = Object.freeze({ wall: 3, dais: 0.3, bannerBottom: 1, bannerTop: 3, door: 2, windowSill: 1, windowHead: 2.4, shrine: 1.2, rail: 1, balcony: 4, mat: 0.05, rowRise: 0.4, rowDepth: 0.8, balconyDepth: 2.4, balconyRows:
|
|
4
|
+
export const ROOM_HEIGHTS = Object.freeze({ wall: 3, dais: 0.3, bannerBottom: 1, bannerTop: 3, door: 2, windowSill: 1, windowHead: 2.4, shrine: 1.2, rail: 1, balcony: 4.5, ceiling: 4.5, mat: 0.05, rowRise: 0.4, rowDepth: 0.8, balconyDepth: 2.4, balconyRows: 3, aisle: 1.2, seat: 0.6, blockLength: 9.14 });
|
|
5
|
+
/** The blocks of a row along a side `length` metres long: the options' `given`, else as many as a block of about 9 m allows (two at least), each as many seats as fit at 0.6 m with the aisles between. */
|
|
6
|
+
export function sectionsFor(length, given) {
|
|
7
|
+
if (given !== undefined && given.length > 0 && given.every((k) => Number.isInteger(k) && k > 0))
|
|
8
|
+
return [...given];
|
|
9
|
+
const blocks = Math.max(2, Math.round(length / ROOM_HEIGHTS.blockLength));
|
|
10
|
+
const seats = Math.max(1, Math.floor((length - (blocks - 1) * ROOM_HEIGHTS.aisle) / blocks / ROOM_HEIGHTS.seat));
|
|
11
|
+
return Array.from({ length: blocks }, () => seats);
|
|
12
|
+
}
|
|
5
13
|
const SIDES = ["north", "east", "south", "west"];
|
|
6
14
|
const COMPASS = { north: "north", south: "south", east: "east", west: "west", top: "north", bottom: "south", left: "west", right: "east" };
|
|
7
15
|
/**
|
|
@@ -24,7 +32,7 @@ export function dojoRoom(o) {
|
|
|
24
32
|
const mv = (b) => ({ x0: b.x0 - ox, y0: b.y0 - oy, x1: b.x1 - ox, y1: b.y1 - oy });
|
|
25
33
|
const floor = mv(plan.box);
|
|
26
34
|
const notes = [];
|
|
27
|
-
const room = { sport: o.sport, unit: "m", floor, mats: undefined, surround: undefined, walls: [], platforms: [], banners: [], balconies: [], doors: [], windows: [], shrine: undefined, hall: undefined, notes };
|
|
35
|
+
const room = { sport: o.sport, unit: "m", floor, mats: undefined, surround: undefined, walls: [], platforms: [], banners: [], balconies: [], doors: [], windows: [], upperWindows: [], ceiling: undefined, shrine: undefined, hall: undefined, notes };
|
|
28
36
|
if (plan.judo !== undefined) {
|
|
29
37
|
const fig = plan.figures;
|
|
30
38
|
room.mats = { thickness: fig.tatami.thickness, edge: "rounded", basis: "source" };
|
|
@@ -35,6 +43,10 @@ export function dojoRoom(o) {
|
|
|
35
43
|
room.mats = { thickness: ROOM_HEIGHTS.mat, edge: "square", basis: "ours" };
|
|
36
44
|
if (L.surround > 0)
|
|
37
45
|
room.surround = { outer: mv(L.room), inner: mv(L.floor), width: L.surround, material: "wood" };
|
|
46
|
+
// A dojo with a gallery is a storey high: the gallery's floor is level with the top of the walls, and the walls are as high as the gallery's floor (4.5 m, ours).
|
|
47
|
+
const gallery = spec.balcony !== undefined && spec.balcony !== false;
|
|
48
|
+
const galleryOwn = typeof spec.balcony === "object" && spec.balcony !== null ? spec.balcony : {};
|
|
49
|
+
const wallHeight = gallery ? galleryOwn.height ?? ROOM_HEIGHTS.balcony : ROOM_HEIGHTS.wall;
|
|
38
50
|
if (L.wall > 0) {
|
|
39
51
|
const r = mv(L.room);
|
|
40
52
|
const w = L.wall;
|
|
@@ -45,8 +57,8 @@ export function dojoRoom(o) {
|
|
|
45
57
|
["west", [r.x0 - w / 2, r.y1 + w / 2], [r.x0 - w / 2, r.y0 - w / 2]],
|
|
46
58
|
];
|
|
47
59
|
for (const [side, from, to] of ring)
|
|
48
|
-
room.walls.push({ id: `wall-${side}`, side, from, to, thickness: w, height:
|
|
49
|
-
notes.push(`The walls are ${
|
|
60
|
+
room.walls.push({ id: `wall-${side}`, side, from, to, thickness: w, height: wallHeight, basis: "ours" });
|
|
61
|
+
notes.push(`The walls are ${wallHeight} m high (ours)${gallery ? ", a storey: the gallery's floor is level with their tops" : ""}.`);
|
|
50
62
|
}
|
|
51
63
|
if (L.dais !== undefined) {
|
|
52
64
|
room.platforms.push({ id: "dais", box: mv(L.dais), height: ROOM_HEIGHTS.dais, basis: "ours" });
|
|
@@ -70,9 +82,29 @@ export function dojoRoom(o) {
|
|
|
70
82
|
for (const side of sides) {
|
|
71
83
|
const box = side === "north" ? { x0: outer.x0 - depth, y0: outer.y0 - depth, x1: outer.x1 + depth, y1: outer.y0 } : side === "south" ? { x0: outer.x0 - depth, y0: outer.y1, x1: outer.x1 + depth, y1: outer.y1 + depth } : side === "west" ? { x0: outer.x0 - depth, y0: outer.y0, x1: outer.x0, y1: outer.y1 } : { x0: outer.x1, y0: outer.y0, x1: outer.x1 + depth, y1: outer.y1 };
|
|
72
84
|
const rows = own.rows ?? ROOM_HEIGHTS.balconyRows;
|
|
73
|
-
|
|
85
|
+
// The blocks of seats along the side, the seats spread over its length with an aisle between the blocks.
|
|
86
|
+
const length = side === "north" || side === "south" ? box.x1 - box.x0 : box.y1 - box.y0;
|
|
87
|
+
const sections = sectionsFor(length, own.sections);
|
|
88
|
+
const seats = sections.reduce((a, k) => a + k, 0);
|
|
89
|
+
const aisle = ROOM_HEIGHTS.aisle;
|
|
90
|
+
const seatWidth = (length - (sections.length - 1) * aisle) / seats;
|
|
91
|
+
let run = 0;
|
|
92
|
+
const aisles = sections.slice(0, -1).map((k, i) => {
|
|
93
|
+
run += k * seatWidth;
|
|
94
|
+
return (run + i * aisle + aisle / 2) / length;
|
|
95
|
+
});
|
|
96
|
+
room.balconies.push({ side, box, height: own.height ?? ROOM_HEIGHTS.balcony, depth, rows, rowDepth: depth / rows, rowRise: ROOM_HEIGHTS.rowRise, rail: ROOM_HEIGHTS.rail, sections, seatWidth, aisle, aisles, sectionsBasis: own.sections === undefined ? "ours" : "given" });
|
|
97
|
+
}
|
|
98
|
+
// The windows above the gallery, on the east side (ours): three tall panes high in the wall behind its last row.
|
|
99
|
+
const east = room.balconies.find((x) => x.side === "east");
|
|
100
|
+
if (east !== undefined) {
|
|
101
|
+
const along = east.box.y1 - east.box.y0;
|
|
102
|
+
const top = east.height + east.rows * east.rowRise + east.rail;
|
|
103
|
+
for (let i = 0; i < 3; i += 1)
|
|
104
|
+
room.upperWindows.push({ side: "east", from: along * (0.12 + i * 0.29), to: along * (0.12 + i * 0.29 + 0.25), sill: top + 0.4, head: top + ROOM_HEIGHTS.ceiling - 0.6 });
|
|
74
105
|
}
|
|
75
|
-
|
|
106
|
+
room.ceiling = { gallery: own.height ?? ROOM_HEIGHTS.balcony, height: (own.height ?? ROOM_HEIGHTS.balcony) + (own.rows ?? ROOM_HEIGHTS.balconyRows) * ROOM_HEIGHTS.rowRise + ROOM_HEIGHTS.rail + ROOM_HEIGHTS.ceiling };
|
|
107
|
+
notes.push("The balcony's height (4.5 m, a storey), depth and its 3 rows are ours, as are the windows above it and the ceiling, 4.5 m over its last row; where a source gives its seats (the Kodokan's gallery, about 900) the atlas hall says so.");
|
|
76
108
|
}
|
|
77
109
|
}
|
|
78
110
|
if (plan.sumo !== undefined)
|
|
@@ -107,5 +139,5 @@ export function dojoGallery(o) {
|
|
|
107
139
|
return undefined;
|
|
108
140
|
const f = room.floor;
|
|
109
141
|
const offset = Math.min(...room.balconies.map((x) => (x.side === "north" ? f.y0 - x.box.y1 : x.side === "south" ? x.box.y0 - f.y1 : x.side === "west" ? f.x0 - x.box.x1 : x.box.x0 - f.x1)));
|
|
110
|
-
return { offset, depth: b.depth, rows: b.rows, height: [b.height, b.height + b.rows * b.rowRise] };
|
|
142
|
+
return { offset, depth: b.depth, rows: b.rows, sections: b.sections, aisles: b.aisles, height: [b.height, b.height + b.rows * b.rowRise] };
|
|
111
143
|
}
|
package/dist/budo/types.d.ts
CHANGED
|
@@ -168,12 +168,17 @@ export interface DojoSpec {
|
|
|
168
168
|
texture?: "weave" | "none";
|
|
169
169
|
/** The wood round the mats, between them and the walls, in metres (none by default; the Kodokan's main dojo has a polished wood surround). */
|
|
170
170
|
surround?: number;
|
|
171
|
-
/**
|
|
171
|
+
/**
|
|
172
|
+
* A spectators' balcony above the floor, a storey up, as `dojoRoom()` gives it (it is not part of the plan's drawing; `crowd` draws the stands): `true` for all four sides, or the sides, depth in metres (2.4 by
|
|
173
|
+
* default), seat rows (3) and height above the mats (4.5 m). `sections` is the number of seats in each block of a row, from one end of a side to the other, with an aisle between blocks (the same on every side): `[5, 8, 8, 8, 5]`
|
|
174
|
+
* is the Kodokan's, 34 to a row; without it a side is cut into blocks of about 9 m. The seats are spread over the side's length, so a seat is as wide as that makes it.
|
|
175
|
+
*/
|
|
172
176
|
balcony?: boolean | {
|
|
173
177
|
sides?: readonly Side4[];
|
|
174
178
|
depth?: number;
|
|
175
179
|
rows?: number;
|
|
176
180
|
height?: number;
|
|
181
|
+
sections?: readonly number[];
|
|
177
182
|
};
|
|
178
183
|
/** The seat of honour's platform: a raised wooden dais at the middle of the kamiza wall (a chair stands on it in the Kodokan's main dojo). Off by default. */
|
|
179
184
|
dais?: boolean;
|
package/dist/budo.style.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The rules of a dojo's gallery, the stands of a crowd in a dojo: brown seats and a rail, a few neutral people. */
|
|
2
|
-
export declare const KYOGIJO_BUDO_GALLERY_STYLE = "\n.kyogijo .ky-bud-gbed.ky-bud-gbed{fill:var(--ky-bud-gal,#7a5a3c)}\n.kyogijo .ky-bud-gblk.ky-bud-gblk{fill:var(--ky-bud-gpeople,#a89a86)}\n.kyogijo .ky-bud-gseat.ky-bud-gseat{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.3}\n.kyogijo .ky-bud-rail{stroke:var(--ky-bud-grail,#3a2c1f);stroke-width:1.6;stroke-opacity:.85}\n";
|
|
2
|
+
export declare const KYOGIJO_BUDO_GALLERY_STYLE = "\n.kyogijo .ky-bud-gbed.ky-bud-gbed{fill:var(--ky-bud-gal,#7a5a3c)}\n.kyogijo .ky-bud-gblk.ky-bud-gblk{fill:var(--ky-bud-gpeople,#a89a86)}\n.kyogijo .ky-bud-gseat.ky-bud-gseat{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.3}\n.kyogijo .ky-bud-grow{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.42}\n.kyogijo .ky-bud-gback{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.75}\n.kyogijo .ky-bud-gaisle{stroke:var(--ky-bud-gaisle,#a98863)}\n.kyogijo .ky-bud-rail{stroke:var(--ky-bud-grail,#3a2c1f);stroke-width:1.6;stroke-opacity:.85}\n";
|
|
3
3
|
/** The rules of a drawing of a budō sport in a look: the shared rules and the look's colours. Nothing for another sport. */
|
|
4
4
|
export declare function budoStyle(sport: string, look?: string): string;
|
|
5
5
|
/** Every budō sport's rules and every look, for a page that draws with `style: "none"` and supplies the stylesheet itself. */
|
package/dist/budo.style.js
CHANGED
|
@@ -5,8 +5,8 @@ const CLASSES = `
|
|
|
5
5
|
.kyogijo .ky-bud-t1{fill:var(--ky-surface)}
|
|
6
6
|
.kyogijo .ky-bud-t2{fill:var(--ky-surface-alt,var(--ky-surface))}
|
|
7
7
|
.kyogijo .ky-bud-t3{fill:var(--ky-red)}
|
|
8
|
-
.kyogijo .ky-bud-heri{fill:var(--ky-bud-heri,var(--ky-ink));fill-opacity
|
|
9
|
-
.kyogijo .ky-bud-seam{stroke:var(--ky-ink);stroke-opacity:.
|
|
8
|
+
.kyogijo .ky-bud-heri{fill:var(--ky-bud-heri,var(--ky-ink));fill-opacity:var(--ky-bud-hop,.07)}
|
|
9
|
+
.kyogijo .ky-bud-seam{stroke:var(--ky-ink);stroke-opacity:.12;fill:none;stroke-linejoin:round}
|
|
10
10
|
.kyogijo .ky-bud-line{stroke:var(--ky-line);fill:none}
|
|
11
11
|
.kyogijo .ky-bud-ink{stroke:var(--ky-ink);fill:none}
|
|
12
12
|
.kyogijo .ky-bud-floor{fill:var(--ky-bud-floor,var(--ky-boards))}
|
|
@@ -18,7 +18,7 @@ const CLASSES = `
|
|
|
18
18
|
.kyogijo .ky-bud-desk{fill:var(--ky-ink);fill-opacity:.55}
|
|
19
19
|
.kyogijo .ky-bud-seat{fill:var(--ky-ink);fill-opacity:.42}
|
|
20
20
|
.kyogijo .ky-bud-shrine{fill:var(--ky-red)}
|
|
21
|
-
.kyogijo .ky-bud-edge{stroke
|
|
21
|
+
.kyogijo .ky-bud-edge{stroke:var(--ky-ink);stroke-opacity:.04;stroke-width:.03;fill:none}
|
|
22
22
|
.kyogijo .ky-bud-dais{fill:var(--ky-bud-floor,var(--ky-boards));stroke:var(--ky-ink);stroke-opacity:.5;stroke-width:.04}
|
|
23
23
|
.kyogijo .ky-bud-banner{fill:var(--ky-ink);fill-opacity:.85}
|
|
24
24
|
.kyogijo .ky-bud-clay{fill:var(--ky-dirt)}
|
|
@@ -54,6 +54,9 @@ export const KYOGIJO_BUDO_GALLERY_STYLE = `
|
|
|
54
54
|
.kyogijo .ky-bud-gbed.ky-bud-gbed{fill:var(--ky-bud-gal,#7a5a3c)}
|
|
55
55
|
.kyogijo .ky-bud-gblk.ky-bud-gblk{fill:var(--ky-bud-gpeople,#a89a86)}
|
|
56
56
|
.kyogijo .ky-bud-gseat.ky-bud-gseat{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.3}
|
|
57
|
+
.kyogijo .ky-bud-grow{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.42}
|
|
58
|
+
.kyogijo .ky-bud-gback{stroke:var(--ky-bud-grail,#3a2c1f);stroke-opacity:.75}
|
|
59
|
+
.kyogijo .ky-bud-gaisle{stroke:var(--ky-bud-gaisle,#a98863)}
|
|
57
60
|
.kyogijo .ky-bud-rail{stroke:var(--ky-bud-grail,#3a2c1f);stroke-width:1.6;stroke-opacity:.85}
|
|
58
61
|
`;
|
|
59
62
|
/** The rules of a drawing of a budō sport in a look: the shared rules and the look's colours. Nothing for another sport. */
|
package/dist/charts.athletics.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// race (every runner on the curve of the lane, the stagger as the rules put it), and the attempts of a field event as marks in the sector or the pit with the best mark picked out. Written for this
|
|
3
3
|
// package from the Track and Field Facilities Manual (2019, 2.2.1.6) and Book C2.1's Technical Rules (14, 17, 25 to 38); nothing of any other package is used. The flags are the caller's: an SVG
|
|
4
4
|
// document as text, or an address, as a team's logo is.
|
|
5
|
-
import { assemble, clean, drawingOptions, languageOf, round, wordsOf } from "./charts.js";
|
|
5
|
+
import { assemble, clean, drawingOptions, entryFlag, languageOf, round, wordsOf } from "./charts.js";
|
|
6
6
|
import { athleticsPlan } from "./athletics/plan.js";
|
|
7
7
|
import { raceById, fieldEventById } from "./athletics/events.js";
|
|
8
8
|
import { fieldEventName } from "./athletics/describe.js";
|
|
@@ -101,9 +101,10 @@ export function laneDraw(entries, options = {}) {
|
|
|
101
101
|
const back = (d) => [start.x - fx * d, start.y - fy * d];
|
|
102
102
|
const [nx, ny] = back(nameAt);
|
|
103
103
|
names.push(clean({ x: nx, y: ny, text: e.name, anchor: "end", size: nameSize, rotate: portrait ? -90 : 0, title: e.country === undefined ? undefined : `${e.name}, ${e.country}` }));
|
|
104
|
-
|
|
104
|
+
const flag = entryFlag(e, options);
|
|
105
|
+
if (flag !== undefined) {
|
|
105
106
|
const [px, py] = back(flagAt);
|
|
106
|
-
flags.push(clean({ x: px, y: py, shape: "logo", logo:
|
|
107
|
+
flags.push(clean({ x: px, y: py, shape: "logo", logo: flag, size: flagSide / 1.8, title: e.country }));
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
const at = { from: "athletics", units: "m" };
|
package/dist/charts.d.ts
CHANGED
|
@@ -42,6 +42,14 @@ export interface KeyPlace {
|
|
|
42
42
|
export declare const isKey: (layer: Layer) => boolean;
|
|
43
43
|
/** The key of a chart as data, from its entries and looks. */
|
|
44
44
|
export declare function keyItems(entries: readonly KeyEntry[], looks: Readonly<Record<string, Look>>): KeyItem[];
|
|
45
|
+
/**
|
|
46
|
+
* The picture of an entry's flag: the `flag` it gives, else the flag of its `country` code by the renderer of flags the chart's `surface.flags` (or `useFlags`) plugs in, in its own proportions;
|
|
47
|
+
* `undefined` where there is none, so that a chart without a renderer lays out as it always did.
|
|
48
|
+
*/
|
|
49
|
+
export declare function entryFlag(entry: {
|
|
50
|
+
flag?: string;
|
|
51
|
+
country?: string;
|
|
52
|
+
}, options: ChartOptions): string | undefined;
|
|
45
53
|
/** Put a chart together: the options, the layers and the ways to draw them. */
|
|
46
54
|
export declare function assemble<T>(options: SurfaceOptions, layers: Layer[], parts: {
|
|
47
55
|
title: string;
|
package/dist/charts.js
CHANGED
|
@@ -8,7 +8,9 @@ import { fromSurface, frameByName, toSurface } from "./frames.js";
|
|
|
8
8
|
import { zoneCounts } from "./heat.js";
|
|
9
9
|
import { isPortrait } from "./common.js";
|
|
10
10
|
import { envFor, isNum, place, unitOfLayer } from "./layers.env.js";
|
|
11
|
+
import { withFlags } from "./flags-source.js";
|
|
11
12
|
import { layerTable } from "./layers.js";
|
|
13
|
+
import { flagPicture } from "./logo.js";
|
|
12
14
|
import { outlineOf } from "./outline.js";
|
|
13
15
|
import { KYOGIJO_STRINGS, fill } from "./strings.js";
|
|
14
16
|
import { textWidth } from "./text.js";
|
|
@@ -102,6 +104,17 @@ export const isKey = (layer) => layer.id === "key-marks" || layer.id === "key-te
|
|
|
102
104
|
export function keyItems(entries, looks) {
|
|
103
105
|
return entries.map((e) => ({ outcome: e.outcome ?? "", label: e.label, shape: looks[e.outcome ?? ""]?.shape ?? "circle", hollow: looks[e.outcome ?? ""]?.hollow === true }));
|
|
104
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* The picture of an entry's flag: the `flag` it gives, else the flag of its `country` code by the renderer of flags the chart's `surface.flags` (or `useFlags`) plugs in, in its own proportions;
|
|
109
|
+
* `undefined` where there is none, so that a chart without a renderer lays out as it always did.
|
|
110
|
+
*/
|
|
111
|
+
export function entryFlag(entry, options) {
|
|
112
|
+
if (entry.flag !== undefined)
|
|
113
|
+
return entry.flag;
|
|
114
|
+
if (entry.country === undefined)
|
|
115
|
+
return undefined;
|
|
116
|
+
return withFlags(options.surface?.flags, () => flagPicture(entry.country, "rect", 24, options.surface?.theme));
|
|
117
|
+
}
|
|
105
118
|
/** Put a chart together: the options, the layers and the ways to draw them. */
|
|
106
119
|
export function assemble(options, layers, parts) {
|
|
107
120
|
const all = { ...options, layers };
|
package/dist/charts.skating.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// with their medals, times and splits, a replay of the race (every skater on his own way round the track, the lane changed once a lap), and the elements of a figure skating programme as marks on the ice.
|
|
3
3
|
// Written for this package from the ISU's Special Regulations and Technical Rules for speed skating (Rules 203, 227, 253, 254 and 280) and short track speed skating (Rule 280); nothing of any other package
|
|
4
4
|
// is used. The flags are the caller's: an SVG document as text, or an address, as a team's logo is.
|
|
5
|
-
import { assemble, clean, drawingOptions, languageOf, round, wordsOf } from "./charts.js";
|
|
5
|
+
import { assemble, clean, drawingOptions, entryFlag, languageOf, round, wordsOf } from "./charts.js";
|
|
6
6
|
import { esc } from "./format.js";
|
|
7
7
|
import { fill } from "./strings.js";
|
|
8
8
|
import { ELEMENT_KINDS, ELEMENT_NAMES, raceById } from "./skating/events.js";
|
|
@@ -122,11 +122,12 @@ export function skatingPairs(pairs, options = {}) {
|
|
|
122
122
|
const back = (d) => [base.x - fx * d, base.y - fy * d];
|
|
123
123
|
const [bx, by] = back(1.6);
|
|
124
124
|
bands.push({ x: bx, y: by, shape: "circle", size: 1.2, color: ARMBAND[laneName], title: laneName === "inner" ? w.data.lanes.inner : w.data.lanes.outer });
|
|
125
|
-
|
|
125
|
+
const flag = entryFlag(entry, options);
|
|
126
|
+
if (flag !== undefined) {
|
|
126
127
|
const [px, py] = back(3.6);
|
|
127
|
-
flags.push(clean({ x: px, y: py, shape: "logo", logo:
|
|
128
|
+
flags.push(clean({ x: px, y: py, shape: "logo", logo: flag, size: 1.6, title: entry.country }));
|
|
128
129
|
}
|
|
129
|
-
const [nx, ny] = back(
|
|
130
|
+
const [nx, ny] = back(flag !== undefined ? 5.4 : 3);
|
|
130
131
|
names.push(clean({ x: nx, y: ny, text: entry.name, anchor: fx < 0 ? "start" : "end", size: 1.9, title: entry.country === undefined ? undefined : `${entry.name}, ${entry.country}` }));
|
|
131
132
|
}
|
|
132
133
|
const layers = [];
|
|
@@ -189,9 +190,10 @@ export function skatingGrid(starters, options = {}) {
|
|
|
189
190
|
const spot = spots[s.position - 1];
|
|
190
191
|
// The skaters go left along the top straight and right along the bottom one: the names stand behind the line.
|
|
191
192
|
const dir = top ? -1 : 1;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
const flag = entryFlag(s, opts);
|
|
194
|
+
names.push(clean({ x: spot.x - dir * (flag === undefined ? 1.2 : 2.6), y: spot.y, text: s.name, anchor: top ? "start" : "end", size: 0.9, title: s.country === undefined ? undefined : `${s.name}, ${s.country}` }));
|
|
195
|
+
if (flag !== undefined)
|
|
196
|
+
flags.push(clean({ x: spot.x - dir * 1.4, y: spot.y, shape: "logo", logo: flag, size: 0.8, title: s.country }));
|
|
195
197
|
}
|
|
196
198
|
const layers = [];
|
|
197
199
|
if (flags.length > 0)
|
package/dist/crowd.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export interface StandRing {
|
|
|
42
42
|
rake: number;
|
|
43
43
|
/** The share of its seats that are taken, relative to the stands' (the upper tier is emptier). */
|
|
44
44
|
fill: number;
|
|
45
|
+
/** A hall's gallery: the rows of seats the band holds. */
|
|
46
|
+
rows?: number;
|
|
45
47
|
/** The seats the band holds, at a seat's 2 by 2.3 feet. */
|
|
46
48
|
seats: number;
|
|
47
49
|
/** The aisles and vomitories across the band, each from a point on its inner edge to its outer: across the sides, fanning round the corners. */
|
|
@@ -154,6 +156,8 @@ export interface LayoutInput {
|
|
|
154
156
|
offset: number;
|
|
155
157
|
depth: number;
|
|
156
158
|
height: [number, number];
|
|
159
|
+
rows?: number;
|
|
160
|
+
aisles?: readonly number[];
|
|
157
161
|
};
|
|
158
162
|
/** The ballpark's fence as points on the field, for a ballpark (see `parkLayout`). */
|
|
159
163
|
fence?: readonly Pt[];
|
package/dist/crowd.draw.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { type Crowd, type CrowdStands } from "./crowd.ts";
|
|
2
|
+
/** The tiles a crowd needs: the home tile, the home tile of the upper tiers (emptier) and the visitors', and the display tiles. */
|
|
3
|
+
export declare function patterns(id: string, crowd: Crowd, density: number, tifo: {
|
|
4
|
+
home: boolean;
|
|
5
|
+
away: boolean;
|
|
6
|
+
} | undefined, neutral?: boolean, rows?: boolean): string;
|
|
2
7
|
/** How the crowd is drawn: the prefix of ids, the options read, the share of seats taken, the detail, and the class of the ground the stands stand on. */
|
|
3
8
|
export interface DrawInput {
|
|
4
9
|
id: string;
|