@johnmorrisdotca/kyogijo-stadiums
v0.63.0
Published
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 ska
Maintainers
Keywords
Readme
Kyogijo Stadiums draws the places a game is played on, with the score of the game on them: the teams at their ends, the score in the middle, a label for what it was. The surfaces are drawn to scale from the rulebooks: a football field has its hash marks where the rules put them, a ballpark its fence where its published distances put it.
The showcase
Real buildings drawn in the outline OpenStreetMap maps for them, each with a plausible bowl of the seats, tiers and roof its sources give. In the rows of arenas, of halls and of districts the picture in the middle turns, slowly, and the others stand still; the other rows are still.
Arenas and stadiums (real arenas, real stadiums)
Tournament halls and judging (tournament layouts, who judges where)
Circuits (circuits)
Districts and the fly-through (districts, the fly-through)
A game on the ice (the replay in 3D, the example game)
A camera can follow the play, flat or in 3D: it closes in where the action is and pulls back as the players spread, or moves with the puck, while the view goes on turning (following the play).
The scoreboard hung over an arena's ice follows the replay: its score, period and game clock come from the same timeline and clock as the controls (the scoreboard over the arena). In a stoppage its clock stands still while the players glide to the face-off's line-up and the dead puck is out of sight, and it runs again at the drop (stoppages). A penalized player sits in his box for his time while his side plays short, and the board shows the power play and each penalty's clock (penalties).
Surfaces (the surfaces, score and layout)
The documentation has a gallery of more than a thousand pictures, each drawn from the code beside it, with search, and the demo shows every one live.
In 30 seconds
npm install @johnmorrisdotca/kyogijo-stadiumsimport { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
const svg = drawKyogijo({
sport: "nhl",
away: { name: "USA", abbr: "USA", score: 3, color: "#1c3f7a" },
home: { name: "Canada", abbr: "CAN", score: 2, color: "#d52b1e" },
status: "final-ot",
competition: "Cup Final, Game 7",
});
console.log(svg.startsWith("<svg"), svg.includes("USA 3, Canada 2"));
// true truesvg is a string of SVG: put it in a page with innerHTML, write it to a file, or send it in an email. With no build step at all:
<script type="module" src="https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kyogijo-stadiums@0/dist/element-define.js"></script>
<kyogijo-field sport="nhl" orientation="auto" away="USA" home="Canada" away-score="3" home-score="2" status="final-ot"></kyogijo-field>Who it is for
- A results page or a stats site that has a game's score and wants a picture of where it was played.
- A list of games that needs a compact strip for each, small enough for a phone.
- Anyone drawing a rink, field, court or ballpark for a poster or a lesson, with the dimensions right and the colours their own.
- A site that uses a framework or none: the drawing is a string, so it works from a server, a build step, a framework, a custom element or a frame.
Features
- Forty-three surfaces, to scale, each from its rulebook or its published distances, and each league's variants (48 of them): football fields, the NHL rink, the NBA court, soccer, baseball, curling, twelve net and racket sports, pools, athletics, skating, field sports, the budō, the MMA cage, rings and mats. The surfaces, sources.
- The score on the surface: each team's name and logo on its side, the score in the middle, wide or tall, a compact badge for a list, the situation of a game. Score and layout, the situation.
- Every ballpark and ground: The 30 current MLB parks and 44 that MLB clubs have left, and the 12 home parks of Nippon Professional Baseball with eight other NPB grounds, each with its fence drawn from the distances published for it; 64 soccer grounds at their published sizes; 167 arenas. Ballparks, grounds, arenas.
- A catalogue of venues: every venue drawn today, the ones being built and the ones wanted (every NBA, MLB, NFL, CFL and NHL venue of the season, world soccer, cricket, rugby, the Olympics, Formula One and more), with ids, names in English and Japanese and Wikidata items, as a JSON file and a typed entry. The catalogue.
- Real venues: arenas and stadiums in the outline of their buildings, districts of several venues on one plan, the crowd in the stands and outside. Ballparks, venues, districts.
- A 3D view of any surface or venue that turns by mouse, touch or keys, with the roof and the walls to switch and a quality level for every device. The 3D view, quality.
- Circuits: a famous race track as OpenStreetMap maps it, the Las Vegas Strip Circuit first, with its turns numbered and its pit building standing in 3D, and a simulated race on it: twenty made-up cars over a full race distance, with a race clock, a timing board and 1×, 10× and 60×; on a district's ground beside T-Mobile Arena among the Strip, with the Sphere, the High Roller and the Fountains of Bellagio, where the race runs too. Circuits, Las Vegas, a race on the Strip.
- Bring your own race feed: a race plays from a feed you choose, read by your own browser from an address, pasted or from a file, and followed while it is live: kyogijo's open race timeline or OpenF1-style lap rows, with our made-up sample feed first. The race feed, Where to find a feed.
- Tournaments: several surfaces on one floor, who judges where, boards laid over a surface. Layouts, judging, boards.
- Data on a surface: points, heat maps, shot and pass charts, team shapes and a replay, flat or in 3D with the players standing on the ice, in 48 providers' coordinate frames. Layers, frames, replay, an example game. Bring your own feed: a game from a file (drop several, kept in your browser), a paste or an address your browser fetches, live or after the game (feeds, where to find a feed).
- Sound: the crowd of each kind of venue at a level from quiet to a roar, heard in the room its venue makes, and its game's sounds (the goal horn, the whistle, the buzzer, the bell) from a replay or live events; made in the browser, off until turned on. Sound.
- Looks and flags: eight named looks, a flag or crest on each half, trophies and crests from Dougu Sports, flags from Hata, light and dark. Theming, the pageant.
- Four ways in: a function that returns SVG text, a helper that draws into a container, a custom element, a frame for pages with no script; renderers for a canvas, d3, Observable Plot, GeoJSON and PNG. Entry points, renderers.
- Accessible and small: each drawing is an
imgwith a title and a description, in English or Japanese; no dependencies, no network requests, nothing stored. - A docs site with a gallery of every picture drawn from the code beside it, a search, and how it compares: the documentation.
What's in it
| Part | What it is |
| --- | --- |
| drawKyogijo, drawSurface, drawScore, drawBadge | The drawing, as a string of SVG. |
| SPORTS, PARKS, COURT_THEMES, SOCCER_PITCHES, GROUNDS, EVENTS | The forty-three sports, the 94 ballparks, the court looks, the pitches, the 64 grounds, the 18 special games. |
| ./venues, ./stadiums, ./district, ./turn | Real arenas and stadiums in their buildings' outlines; districts on one plan; a surface as a 3D view that turns. |
| ./circuits | Race tracks as OpenStreetMap maps them, in 2D and 3D, and a simulated race on them with its clock and timing board (demo). |
| ./multi, ./judging, ./layouts | Several surfaces for one event (demo); who judges where; small multiples and backgrounds. |
| ./layers, ./charts, ./frames, ./zones, ./pointer, ./replay | Data layers, charts, the providers' frames, zones by the rules, a click as a place, tracking data played on a surface. |
| ./sound | A surface's crowd and its game's sounds, made in the browser with Web Audio (demo). |
| ./feeds | A game from a feed (kyogijo's open timeline, an NHL-style play-by-play) read into a replay; replay.fromUrl and replay.follow. |
| ./athletics, ./budo, ./skating | The athletics stadium, the budō (areas, dohyō, the dojo builder) and the skating rinks. |
| ./scene, ./canvas, ./d3, ./plot, ./geojson, ./png | The drawing as data, on a canvas, in d3, as an Observable Plot mark, as GeoJSON, as a PNG. |
| ./mount, ./react, ./element, ./element/define | Draw into a container; React props; the <kyogijo-field> element and its registration. |
The full list of entry points is in entry points; every export is in the API reference.
Guides
Twelve guides, each with a Japanese twin in docs/guides/ja/, written for someone using the package: every example is run against the built package by pnpm test:readme, and the guides are held with the rest of the documentation by pnpm docs:check.
| Guide | What it is for | | --- | --- | | Getting started: a results page | A strip for every game in a list, one large drawing, and the same drawing tall for a phone. | | A score on a surface | The teams, the state of the game, which side the home team is on, the three sizes. | | Looks, colours and dark mode | Eight named looks, colours from code, a court of your own, many drawings on one page. | | Embedding | A container that follows its box, the custom element, a frame for a page with no script. | | React, Vue, Svelte and Angular | The string or the element in each, and a server with no framework. | | Ballparks, grounds, arenas and real venues | From a park's fence to a district of buildings on one plan, and the catalogue of what exists. | | Data on a surface | Layers, coordinate frames, zones by the rules, a click as a place, charts. | | The 3D view | The floor that turns, what stands on it, stands and roof, quality on a phone. | | Accessibility, English and Japanese | What a drawing says for itself, and what the page around it must say. | | Architecture | The rules a drawing is made by, and the checks that keep them true. | | Troubleshooting | Nothing appears, a colour is wrong, a snapshot fails after an upgrade. | | Upgrading | What each breaking release asks of you, and how to make the next upgrade cheap. |
Use it in your project
Install
npm install @johnmorrisdotca/kyogijo-stadiums
# or: pnpm add @johnmorrisdotca/kyogijo-stadiums
# or: yarn add @johnmorrisdotca/kyogijo-stadiumsIt needs Node 22 or later on a server, and any current browser. It is plain ES modules, with types, and on the CDNs once on npm: https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kyogijo-stadiums@0/+esm is the package as one module for the browser.
Four ways in
- A string of SVG.
drawKyogijo(options)returns SVG text; it needs no DOM and the same options always give the same text. - A container in the browser.
mountKyogijo(element, options)draws into an element and, withorientation: "auto", draws again when its shape changes. - A custom element.
<kyogijo-field>: importelement/defineonce and use the tag with attributes. - A frame. For a page that cannot run scripts, the demo site serves
embed.html, which draws what its address says.
Each is shown with its code in getting started; React, Vue and Svelte are below.
Examples
The most used few; the recipes have the rest. Each example is run against the built package by pnpm test:readme.
A score on the rink
import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
const svg = drawKyogijo({
sport: "nhl",
away: { name: "USA", abbr: "USA", score: 3, color: "#1c3f7a" },
home: { name: "Canada", abbr: "CAN", score: 2, color: "#d52b1e" },
status: "final-ot",
competition: "Cup Final, Game 7",
date: "June 24",
});
console.log(svg.includes("Cup Final, Game 7"), svg.includes("Final/OT"));
// true trueA bare surface, and tall for a phone
import { drawKyogijo, drawSurface } from "@johnmorrisdotca/kyogijo-stadiums";
// No teams: just the NFL field at its true shape, 120 by 53⅓ yards with 12 feet of ground round it.
console.log(/viewBox="-12 -12 384 184"/.test(drawSurface({ sport: "nfl" })));
// true
const game = { away: { name: "Mexico", score: 27 }, home: { name: "USA", score: 24 }, status: "final" };
const wide = drawKyogijo({ sport: "nfl", ...game, orientation: "landscape" });
const tall = drawKyogijo({ sport: "nfl", ...game, orientation: "portrait" });
const box = (svg: string) => /viewBox="[^ ]+ [^ ]+ ([^ ]+) ([^ "]+)"/.exec(svg)!.slice(1).map(Number);
console.log(box(wide), box(tall));
// [ 384, 184 ] [ 184, 384 ]The surfaces lists the forty-three, with their sizes and what is drawn; score and layout has the options of a score, a strip and a compact card.
A ballpark, by name
import { PARKS, drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
const park = PARKS["hanshin-koshien-stadium"];
console.log(park.name, park.nameJa, park.points.length);
// Koshien Stadium 甲子園球場 5
const svg = drawKyogijo({ sport: "mlb", park: "hanshin-koshien-stadium", language: "ja" });
console.log(svg.includes("甲子園球場のグラウンド"), svg.includes("阪神甲子園球場のグラウンド"), svg.includes("正式名称は阪神甲子園球場です"));
// true false trueA court of your own look
import { COURT_THEMES, drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
const svg = drawKyogijo({
sport: "nba",
court: { ...COURT_THEMES.twoTone, baselineText: ["SUMMIT PEAKS", "METRO BOLTS"], paintThreePoint: true },
});
console.log(svg.includes("--ky-key:#1e4f8f"), svg.includes("METRO BOLTS"));
// true trueThe five court looks, the eight looks of every sport and every colour property are in theming.
Turn it, and see the net
import { mountKyogijoTurn } from "@johnmorrisdotca/kyogijo-stadiums/turn";
const view = mountKyogijoTurn(document.querySelector("#court")!, { sport: "volleyball", status: "live" }, { preset: "end" });
view.preset("corner");
view.setDirection("clockwise"); // the auto-turn goes the other way (`direction` in the settings says it at the start)import { turnMarkup, uprightsFor } from "@johnmorrisdotca/kyogijo-stadiums/turn";
const { items } = uprightsFor({ sport: "volleyball" }, { netHeight: "women" });
const html = turnMarkup({ sport: "volleyball" }, { preset: "end" });
console.log(items.map((item) => item.kind).join(), html.includes("preserve-3d"));
// net,netposts,antennae falseThe flat drawing is the floor, turned by a drag, a swipe, the keys or four viewpoints, with what the rulebook stands on it at its height; each part is one matrix3d. The auto-turn waits for Play, and turns either way: counterclockwise (the near side swinging to the viewer's right) by default, clockwise on the Reverse button. In the element: <kyogijo-field sport="nhl" turn turn-view="broadcast">. The 3D view.
The element in a page
<script type="module" src="https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kyogijo-stadiums@0/dist/element-define.js"></script>
<!-- score is home-away; home-score and away-score say it the other way -->
<kyogijo-field sport="nba" size="compact" orientation="auto"
home="Japan" away="Australia" score="112-108"
home-color="#c2410c" away-color="#14233f" status="final"></kyogijo-field>The attributes are the options' names in kebab case, and the parts you can style are listed in getting started.
In React
import React from "react";
import { createKyogijo, kyogijoProps } from "@johnmorrisdotca/kyogijo-stadiums/react";
// A component made from your React, which measures its box for orientation="auto":
const Kyogijo = createKyogijo(React);
export const Game = () => (
<Kyogijo sport="nhl" orientation="auto" away={{ name: "USA", score: 3 }} home={{ name: "Canada", score: 2 }} status="final" />
);
// Or props to spread onto your own element; nothing here imports React:
export const Plain = () => <div {...kyogijoProps({ sport: "nba" })} />;In Vue
<script setup>
import "@johnmorrisdotca/kyogijo-stadiums/element/define";
</script>
<template>
<kyogijo-field sport="nfl" orientation="auto" away="Mexico" home="USA" away-score="27" home-score="24" status="final" />
</template>Tell Vue the tag is a custom element with compilerOptions.isCustomElement: (tag) => tag === "kyogijo-field".
In Svelte
<script>
import "@johnmorrisdotca/kyogijo-stadiums/element/define";
import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
export let home = 0;
export let away = 0;
$: svg = drawKyogijo({ sport: "nhl", away: { name: "USA", score: away }, home: { name: "Canada", score: home } });
</script>
<!-- the string of SVG, or the element: either works -->
{@html svg}
<kyogijo-field sport="nhl" away="USA" home="Canada" away-score={away} home-score={home} />A page that moves (mountKyogijo), a file written on a server and a frame for a page with no script are in getting started, and every framework below has its own guide.
In Angular
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@johnmorrisdotca/kyogijo-stadiums/element/define";
@Component({
selector: "app-game",
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<kyogijo-field sport="nhl" orientation="auto" away="USA" home="Canada" [attr.away-score]="away" [attr.home-score]="home"></kyogijo-field>`,
})
export class GameComponent {
away = 3;
home = 2;
}From a CDN, as a module
<div id="game"></div>
<script type="module">
import { drawKyogijo } from "https://cdn.jsdelivr.net/npm/@johnmorrisdotca/kyogijo-stadiums@0/+esm";
document.querySelector("#game").innerHTML = drawKyogijo({ sport: "nba", away: { name: "Australia", score: 108 }, home: { name: "Japan", score: 112 }, status: "final" });
</script>With a bundler and TypeScript
import { SPORTS, drawKyogijo, type ScoreOptions, type Sport } from "@johnmorrisdotca/kyogijo-stadiums";
// The options are typed, so an editor lists the sports, the statuses and every option with its doc comment; a sport is one of SPORTS.
const sport: Sport = "nhl";
const game: ScoreOptions = { sport, home: { name: "Japan", score: 7 }, away: { name: "Canada", score: 5 }, status: "final" };
console.log(SPORTS.includes(sport), drawKyogijo(game).includes("Canada 5, Japan 7"));
// true trueA bundler (Vite, webpack, esbuild or Rollup) needs nothing set: each entry is its own file, so import ... from "@johnmorrisdotca/kyogijo-stadiums/parks" brings in the parks and nothing else.
// vite.config.ts: nothing is needed for the package. Tell Vue the tag is a custom element, if you use it.
import vue from "@vitejs/plugin-vue";
export default { plugins: [vue({ template: { compilerOptions: { isCustomElement: (tag: string) => tag === "kyogijo-field" } } })] };In a frame, with no script of your own
<iframe
src="https://johnmorrisdotca.github.io/kyogijo-stadiums/embed.html?sport=nhl&away=USA&home=Canada&ascore=3&hscore=2&status=final-ot"
title="USA 3, Canada 2, Final/OT"
loading="lazy"
style="width:100%;aspect-ratio:2.3;border:0"
></iframe>On a server
import { createServer } from "node:http";
import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
// An image address: the same options give the same bytes, so a CDN can keep it.
createServer((request, response) => {
const sport = new URL(request.url ?? "/", "http://localhost").searchParams.get("sport") === "nba" ? "nba" : "nhl";
response.writeHead(200, { "content-type": "image/svg+xml", "cache-control": "public, max-age=3600" });
response.end(drawKyogijo({ sport, away: { name: "USA", score: 3 }, home: { name: "Canada", score: 2 }, status: "final" }));
}).listen(6900);Shots on the rink, in the provider's numbers
import { drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
import { zoneAt } from "@johnmorrisdotca/kyogijo-stadiums/zones";
// The NHL API's numbers are feet from centre ice: `from` puts them on the rink, and `zoneAt` says where one is by the rules.
const shots = [{ x: 69, y: 22, team: "home", outcome: "goal" }, { x: -61, y: 12, team: "away", outcome: "blocked" }];
const svg = drawKyogijo({ sport: "nhl", layers: [{ kind: "points", name: "shots", from: "nhl-api", data: shots }] });
console.log(svg.includes("2 shots"), zoneAt("nhl", [69, 22], { frame: "nhl-api" }).subzone);
// true faceoff-circleIn Japanese
import { describe, drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
const game = { sport: "nhl", away: { name: "USA", score: 3 }, home: { name: "Canada", score: 2 }, status: "final" } as const;
console.log(describe({ ...game, language: "ja" }).title, drawKyogijo({ ...game, language: "ja" }).includes("試合終了"));
// USA 3、Canada 2、試合終了 trueAs data, for d3, a canvas, GeoJSON or a PNG
import { sceneToGeoJSON } from "@johnmorrisdotca/kyogijo-stadiums/geojson";
// The same drawing as features, in feet from the left end of the rink.
const features = sceneToGeoJSON({ sport: "nhl", id: "rink" });
console.log(features.type, features.features.length > 10);
// FeatureCollection trueimport { writeFileSync } from "node:fs";
import { toPNG } from "@johnmorrisdotca/kyogijo-stadiums/png";
// Needs the optional package @resvg/resvg-js; without it the call says so (PNG_PEER_MISSING).
writeFileSync("rink.png", await toPNG({ sport: "nhl", away: { name: "USA", score: 3 }, home: { name: "Canada", score: 2 }, status: "final" }, { width: 1200 }));API
The API reference lists every export of every entry point with its signature and doc comment, made from the source by pnpm site. Entry points says what each holds: the main one draws, the data and geometry ones stand apart, and /mount, /turn, /react, /element and /element/define put a drawing in a page.
Every function is pure: it returns new values and never changes what it was given.
Theming
Nothing is branded. The drawing is coloured by custom properties on its svg, with a light set and a dark set that follow the device (or data-theme, or theme in the options); a page's own rule always wins. Each property is listed in theming.
Limits
Each is held by a test: forty-three sports, ten soccer pitches and ten providers, 94 ballparks, 64 grounds, six units, forty-eight frames, a drawing of under 22 kB. The table, made from the code, is limits.
Accessibility
- Each drawing is an
imgwith a<title>and a<desc>that say the teams, the score, the surface and the result, in English or Japanese. - A score is also text, words stay upright when the surface lies tall, colour is never the only sign, and each data layer has a table for a screen reader.
- Nothing moves by itself: a replay plays when asked, steps for a reader who prefers reduced motion, and pauses when the page is hidden.
The rest is in accessibility.
Browser and runtime support
Any browser with ES modules, :where() and SVG 2's href on images: Chrome and Edge 88, Safari 14, Firefox 78, all from 2021 on. The custom element needs shadow DOM and part. The drawing function runs on Node 22 or later and in any runtime: it touches no DOM. The demo is played in Chromium and WebKit, at a phone's width and a desk's, before every release.
Languages
English and Japanese: the title, the description and the statuses of a drawing, the sentence of each change in eraChanges, and the demo. The words are listed beside their English in the Japanese of Kyogijo. Team names, competitions and dates are written as you give them, in any language. Not yet: the Japanese read by a native reader (the demo says so when it is shown).
Roadmap
Not here yet, each welcome as an issue:
- More surfaces: the FIBA and college courts, the international rink, rugby pitches, soccer's beach and street formats.
- More real venues: the NBA's, NFL's and MLB's, and more districts.
- More parks of the past: the 19th-century grounds, and the parks whose articles give no distances yet.
- More charts on data layers: a formation chart, a pass sonar chart and a Voronoi chart of their own (the layers exist; see team shape).
- Football in a different standard: the college and high-school hash marks.
Left out on purpose: statistics, rosters and schedules.
Architecture
The drawing is plain functions over plain data with no DOM and no dependency. The dimensions are in one file, the ballparks are generated from a reviewed list, and each surface is a function that returns its markup and the places the teams and the score go. Every entry point stands apart. The files are in architecture.
The name
Kyogijo (競技場, kyōgijō, きょうぎじょう) is Japanese for a sports ground, the place a contest is held, written with 競技, "contest", and 場, "place". "Stadiums" is added in English so that the name says what it draws. The long vowels are written without a macron, as in the other packages of the family.
Where it comes from, and where it is used
Kyogijo Stadiums was made for SPX Stats, the historical record of the NHL, NBA, MLB, NFL and CFL, to show the score of a game or a championship on the surface it was played on, with each team's name and logo at its side. Its Japanese names and parks are there because the same author makes a Japanese study app and a site for Japanese board games.
Used by
- SPX Stats, planned, for the score of a game or a championship.
Using Kyogijo Stadiums in something? Open an Add my project issue and we will add you.
The family
Kyogijo Stadiums is one of thirty-two packages, each made for the same site, each at github.com/johnmorrisdotca or github.com/spxis. The code of every one is MIT.
Games — board
- Domino (ドミノ): dominoes and Mexican Train. Demo.
- Gunjin (軍人): five hidden-rank strategy games with pass-the-device play. Demo.
- Narabe (並べ): one rules engine for abstract board games, from gomoku and Reversi to Go and checkers. Demo.
- Sugoroku (双六): backgammon and its variants, with the doubling cube and match play. Demo.
- Tenka (天下): world conquest for two to six, on a map of the real world. Demo.
Games — cards & tiles
- Hitotsu (一つ): a colour-card shedding game for two to eight, with the house rules people play. Demo.
- Jarajara (ジャラジャラ): mahjong tiles drawn as SVG, stacked layouts, and the matching solitaire Awase. Demo.
- Kumimoji (組み文字): a crossword tile race, in English and Japanese kana. Demo.
- Toranpu (トランプ): a deck of playing cards, card games with computer players, and solitaires. Demo.
Games — puzzles
- Houseki (宝石): gem and stone matching puzzles: falling triplets, stone collapse, colour chains and gem swap. Demo.
- Jirai (地雷): minesweeper on shaped grids with verified no-guess boards. Demo.
- Karakuri (からくり): eight hyper-casual puzzle games, some of them physics: draw a shield, pull pins, cut ropes, slide blocks, pour tubes. Demo.
- Kazu (数): grid number puzzles: Sudoku and its variants, Futoshiki and Skyscrapers. Demo.
- Kyuubu (キューブ): a turning cube for the browser, 2×2 to 7×7, with record solves to replay. Demo.
- Meikyuu (迷宮): mazes on squares, hexagons, triangles and circles, made from a seed and drawn through with a finger or the mouse. Demo.
- Suido (水道): a pipe puzzle: turn the pieces until the water reaches every drain. Demo.
- Tobiishi (飛び石): peg solitaire with nine boards and seeded solvable challenges. Demo.
- Tsunagi (繋ぎ): a line-joining logic puzzle whose every level has exactly one answer. Demo.
Games — dice & random
- Korokoro (コロコロ): dice, with notation, exact odds, real sounds and the dice of many games. Demo.
- Tane (種): seeded random numbers and daily seeds, the same in every browser and on every server. Demo.
Language
- Bushu (部首): find a kanji by the parts it is made of. Demo.
- Hikidashi (引き出し): a drawer of small Japanese text tools: era dates, kanji numerals, readings and sentence difficulty. Demo.
- Kotoba (言葉): word lists and word-game rules in English, French, German and Japanese. Demo.
Geography & data
- address-plus (アドレスプラス): parse and format addresses in the United States, Canada, Japan, Australia, France, Germany and the United Kingdom. Demo.
- Chizu (地図): maps of the world and of countries' regions, in English and Japanese, with a quiz and callouts. Demo.
- Hata (旗): country and regional flags as SVG, at their true proportions and keyed by ISO code. Demo.
- Kuni (国): countries and their regions, with ISO codes and names in English and Japanese. Demo.
Sports
- Dougu Sports (道具): sports emblems as SVG: trophies, medals, crests, and the ball and gear of every sport, with optional 3D turning. Demo.
- Kyogijo Stadiums (競技場): sports fields, rinks, courts and ballparks drawn to scale as SVG, with each team and the score on them. Demo.
- Senshu Jerseys (選手): sports jerseys, sweaters, kits, caps, helmets and retired-number banners as SVG, front and back, with optional 2.5D turning. Demo.
- Taisen Brackets (対戦): a sport-agnostic tournament bracket, drawn as SVG, from a list of ties. Demo.
Developer tools
- REST in Pieces (レスト・イン・ピーシーズ): seeded test data and REST APIs for frontend development, with latency and error drills. Demo.
This package is Kyogijo Stadiums. The demos of all thirty-two share one header and footer, so each links the rest.
Development
pnpm install
pnpm check # lint, types, every test, the build and the packed package
pnpm test:package # pack, install and import it, as a user would
pnpm test:demo # build the site and play it in a real browser, at a phone's width and a desk's
pnpm site # build the demo and the docs site into site/, as the Pages workflow publishes it
pnpm screenshots:readme # remake every README picture from the built demo, in light and dark
pnpm test:readme # run every example in the README and the docs against the built package
pnpm docs:make # rewrite what the docs make from the source: the Japanese words and the tablesContributing
See CONTRIBUTING.md. The commands are under Development.
Please follow the code of conduct. Text, a colour or a logo address that gets out of the drawing, or a name that makes it run for a very long time, is for the security policy, not a public issue.
Changes
See CHANGELOG.md. The first release, 0.1.0, draws the twenty surfaces and the 94 ballparks, with scores, badges, wide and tall layouts, a custom element and a frame.
Licence
The code is MIT © John Morris. The ballparks' fence distances are facts published in Wikipedia's articles, re-expressed as numbers, with each article and revision cited in NOTICE.md (shipped in the package) and docs/references.md. The surfaces' dimensions are facts from the rulebooks and diagrams, cited in docs/sources.md.
| Data | Made from | Terms | | --- | --- | --- | | The dimensions of the football fields, the rink and the court | The NFL, CFL, IFAF, NHL and NBA rules and diagrams | Facts; no text or drawing copied | | The soccer pitch's dimensions and the providers' coordinates | The IFAB and FIFA Futsal Laws of the Game, UEFA, MLS, NCAA and FA documents, and each provider's own pages (docs/sources.md) | Facts; no text or drawing copied | | 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 | | The Wikidata item of each ballpark | Wikidata, as linked from the cited article | CC0 | | The outlines of the real venues and stadiums | OpenStreetMap, read 2026-10-20, kept as returned | ODbL 1.0, (c) OpenStreetMap contributors, in files of their own; a drawing carries the credit | | 64 soccer grounds | English Wikipedia articles at the revision cited; Wikidata | Facts; CC BY-SA 4.0 articles, no text used; CC0 | | 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 | | The demo's country flags | 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 | | The demo's trophies, medals, balls and crests | 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 |
