@johnmorrisdotca/kyogijo-stadiums 0.4.0 → 0.6.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 +133 -0
- package/NOTICE.md +182 -2
- package/README.md +106 -19
- package/dist/annotate.js +1 -1
- package/dist/arenas-entry.d.ts +4 -0
- package/dist/arenas-entry.js +3 -0
- package/dist/arenas.d.ts +125 -0
- package/dist/arenas.data.d.ts +2 -0
- package/dist/arenas.data.js +3763 -0
- package/dist/arenas.js +72 -0
- package/dist/athletics/describe.d.ts +8 -0
- package/dist/athletics/describe.js +41 -0
- package/dist/athletics/events.d.ts +17 -0
- package/dist/athletics/events.js +48 -0
- package/dist/athletics/facilities.d.ts +80 -0
- package/dist/athletics/facilities.js +176 -0
- package/dist/athletics/infield.d.ts +79 -0
- package/dist/athletics/infield.js +166 -0
- package/dist/athletics/layout.d.ts +13 -0
- package/dist/athletics/layout.js +98 -0
- package/dist/athletics/oval.d.ts +57 -0
- package/dist/athletics/oval.js +116 -0
- package/dist/athletics/plan.d.ts +97 -0
- package/dist/athletics/plan.js +355 -0
- package/dist/athletics/races.d.ts +102 -0
- package/dist/athletics/races.js +355 -0
- package/dist/athletics/steeplechase.d.ts +72 -0
- package/dist/athletics/steeplechase.js +196 -0
- package/dist/athletics/stencil.d.ts +13 -0
- package/dist/athletics/stencil.js +85 -0
- package/dist/athletics/track.d.ts +54 -0
- package/dist/athletics/track.js +105 -0
- package/dist/athletics/types.d.ts +77 -0
- package/dist/athletics/types.js +1 -0
- package/dist/athletics-entry.d.ts +17 -0
- package/dist/athletics-entry.js +11 -0
- package/dist/athletics.style.d.ts +16 -0
- package/dist/athletics.style.js +51 -0
- package/dist/atlas-entry.d.ts +6 -2
- package/dist/atlas-entry.js +4 -2
- package/dist/atlas.d.ts +117 -23
- package/dist/atlas.js +197 -12
- package/dist/background.js +2 -1
- package/dist/budo/describe.d.ts +13 -0
- package/dist/budo/describe.js +120 -0
- package/dist/budo/dojo.api.d.ts +64 -0
- package/dist/budo/dojo.api.js +46 -0
- package/dist/budo/dojo.d.ts +72 -0
- package/dist/budo/dojo.js +300 -0
- package/dist/budo/judo.d.ts +61 -0
- package/dist/budo/judo.js +109 -0
- package/dist/budo/karate.d.ts +29 -0
- package/dist/budo/karate.js +80 -0
- package/dist/budo/kendo.d.ts +18 -0
- package/dist/budo/kendo.js +44 -0
- package/dist/budo/kimarite.d.ts +19 -0
- package/dist/budo/kimarite.js +33 -0
- package/dist/budo/kit.d.ts +16 -0
- package/dist/budo/kit.js +24 -0
- package/dist/budo/kyudo.d.ts +28 -0
- package/dist/budo/kyudo.js +66 -0
- package/dist/budo/looks.d.ts +28 -0
- package/dist/budo/looks.js +58 -0
- package/dist/budo/parts.d.ts +32 -0
- package/dist/budo/parts.js +10 -0
- package/dist/budo/plan.d.ts +64 -0
- package/dist/budo/plan.js +139 -0
- package/dist/budo/room.d.ts +133 -0
- package/dist/budo/room.js +111 -0
- package/dist/budo/sumo.d.ts +31 -0
- package/dist/budo/sumo.js +71 -0
- package/dist/budo/tatami.d.ts +55 -0
- package/dist/budo/tatami.js +156 -0
- package/dist/budo/types.d.ts +192 -0
- package/dist/budo/types.js +2 -0
- package/dist/budo-entry.d.ts +22 -0
- package/dist/budo-entry.js +13 -0
- package/dist/budo.board.d.ts +28 -0
- package/dist/budo.board.js +81 -0
- package/dist/budo.score.d.ts +18 -0
- package/dist/budo.score.js +52 -0
- package/dist/budo.style.d.ts +6 -0
- package/dist/budo.style.js +67 -0
- package/dist/charts-entry.d.ts +6 -1
- package/dist/charts-entry.js +3 -0
- package/dist/charts.athletics.d.ts +183 -0
- package/dist/charts.athletics.js +455 -0
- package/dist/charts.baseball.js +1 -1
- package/dist/charts.curling.heat.d.ts +24 -0
- package/dist/charts.curling.heat.js +116 -0
- package/dist/charts.curling.js +14 -3
- package/dist/charts.js +4 -4
- package/dist/charts.pool.d.ts +67 -0
- package/dist/charts.pool.js +76 -0
- package/dist/charts.skating.d.ts +204 -0
- package/dist/charts.skating.js +426 -0
- package/dist/charts.soccer.js +3 -3
- package/dist/charts.types.d.ts +63 -1
- package/dist/colour.d.ts +4 -4
- package/dist/colour.js +4 -4
- package/dist/court.d.ts +85 -2
- package/dist/court.js +102 -7
- package/dist/court.more.d.ts +46 -0
- package/dist/court.more.js +219 -0
- package/dist/courts.style.d.ts +14 -2
- package/dist/courts.style.js +51 -4
- package/dist/crowd.d.ts +164 -0
- package/dist/crowd.draw.d.ts +17 -0
- package/dist/crowd.draw.js +204 -0
- package/dist/crowd.js +480 -0
- package/dist/crowd.park.d.ts +19 -0
- package/dist/crowd.park.js +153 -0
- package/dist/curling.stats.d.ts +271 -0
- package/dist/curling.stats.js +301 -0
- package/dist/draw.d.ts +16 -0
- package/dist/draw.js +462 -54
- package/dist/element-entry.d.ts +3 -1
- package/dist/element-entry.js +2 -1
- package/dist/element.d.ts +13 -2
- package/dist/element.js +79 -4
- package/dist/emblems-source.d.ts +50 -0
- package/dist/emblems-source.js +56 -0
- package/dist/eras.d.ts +3 -1
- package/dist/eras.js +8 -3
- package/dist/features.js +204 -0
- package/dist/field.data.d.ts +16 -0
- package/dist/field.data.js +50 -0
- package/dist/fields.kit.d.ts +2 -2
- package/dist/fields.types.d.ts +24 -4
- package/dist/formations.js +18 -7
- package/dist/formations.sports.d.ts +8 -0
- package/dist/formations.sports.js +251 -0
- package/dist/frames.providers.js +71 -8
- package/dist/geojson.js +3 -0
- package/dist/geometry-entry.d.ts +2 -1
- package/dist/geometry-entry.js +2 -1
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.js +78 -1
- package/dist/grounds.d.ts +4 -0
- package/dist/grounds.data.js +12 -0
- package/dist/halls.d.ts +65 -0
- package/dist/halls.js +122 -0
- package/dist/hardwood.d.ts +31 -0
- package/dist/hardwood.js +157 -0
- package/dist/heat.js +21 -13
- package/dist/heat.types.d.ts +5 -0
- package/dist/heat.zones.d.ts +4 -2
- package/dist/heat.zones.js +207 -7
- package/dist/homeside.js +24 -0
- package/dist/index.d.ts +30 -4
- package/dist/index.js +18 -2
- package/dist/layers-entry.d.ts +2 -1
- package/dist/layers-entry.js +1 -0
- package/dist/layers.d.ts +2 -1
- package/dist/layers.env.d.ts +12 -1
- package/dist/layers.env.js +36 -4
- package/dist/layers.js +32 -13
- package/dist/layers.types.d.ts +9 -2
- package/dist/leagues/athletics.d.ts +63 -0
- package/dist/leagues/athletics.js +87 -0
- package/dist/leagues/budo.d.ts +196 -0
- package/dist/leagues/budo.js +105 -0
- package/dist/leagues/courts.d.ts +269 -4
- package/dist/leagues/courts.js +155 -1
- package/dist/leagues/hockey.js +41 -19
- package/dist/leagues/skating.d.ts +145 -0
- package/dist/leagues/skating.js +73 -0
- package/dist/leagues/sources.js +41 -0
- package/dist/leagues/types.d.ts +1 -1
- package/dist/leagues-entry.d.ts +4 -2
- package/dist/leagues-entry.js +2 -1
- package/dist/leagues.d.ts +17 -4
- package/dist/leagues.js +246 -5
- package/dist/lineup.codes.d.ts +23 -0
- package/dist/lineup.codes.js +122 -0
- package/dist/logo.d.ts +25 -0
- package/dist/logo.js +47 -0
- package/dist/look.d.ts +3 -3
- package/dist/look.js +39 -6
- package/dist/outline.d.ts +1 -1
- package/dist/outline.js +46 -4
- package/dist/pageant.d.ts +120 -0
- package/dist/pageant.draw.d.ts +21 -0
- package/dist/pageant.draw.js +171 -0
- package/dist/pageant.js +211 -0
- package/dist/pageant.style.d.ts +8 -0
- package/dist/pageant.style.js +42 -0
- package/dist/png.d.ts +8 -1
- package/dist/png.js +21 -1
- package/dist/pointer-entry.d.ts +2 -0
- package/dist/pointer-entry.js +2 -0
- package/dist/pointer.d.ts +113 -0
- package/dist/pointer.js +151 -0
- package/dist/pool.d.ts +176 -0
- package/dist/pool.figures.d.ts +306 -0
- package/dist/pool.figures.js +148 -0
- package/dist/pool.js +304 -0
- package/dist/pool.kit.d.ts +48 -0
- package/dist/pool.kit.js +141 -0
- package/dist/pool.labels.d.ts +20 -0
- package/dist/pool.labels.js +258 -0
- package/dist/pool.race.d.ts +65 -0
- package/dist/pool.race.js +140 -0
- package/dist/pool.replay.d.ts +46 -0
- package/dist/pool.replay.js +127 -0
- package/dist/pool.section.d.ts +13 -0
- package/dist/pool.section.js +83 -0
- package/dist/pool.style.d.ts +20 -0
- package/dist/pool.style.js +169 -0
- package/dist/pool.types.d.ts +145 -0
- package/dist/pool.types.js +3 -0
- package/dist/pool.words.d.ts +13 -0
- package/dist/pool.words.js +101 -0
- package/dist/ranges.names.js +53 -3
- package/dist/replay-entry.d.ts +3 -0
- package/dist/replay-entry.js +2 -0
- package/dist/restyle.js +1 -1
- package/dist/road.draw.js +3 -2
- package/dist/road.js +2 -1
- package/dist/road.types.d.ts +3 -0
- package/dist/rules.d.ts +138 -0
- package/dist/rules.js +511 -0
- package/dist/rules.types.d.ts +4 -0
- package/dist/rules.types.js +64 -0
- package/dist/score.d.ts +3 -0
- package/dist/score.js +93 -6
- package/dist/sheet.d.ts +3 -0
- package/dist/sheet.js +7 -3
- package/dist/situation.d.ts +135 -0
- package/dist/situation.draw.d.ts +34 -0
- package/dist/situation.draw.js +202 -0
- package/dist/situation.js +337 -0
- package/dist/situation.style.d.ts +2 -0
- package/dist/situation.style.js +45 -0
- package/dist/situation.types.d.ts +77 -0
- package/dist/situation.types.js +3 -0
- package/dist/situation.widgets.d.ts +39 -0
- package/dist/situation.widgets.js +129 -0
- package/dist/skating/describe.d.ts +7 -0
- package/dist/skating/describe.js +44 -0
- package/dist/skating/events.d.ts +24 -0
- package/dist/skating/events.js +47 -0
- package/dist/skating/figure.d.ts +24 -0
- package/dist/skating/figure.js +37 -0
- package/dist/skating/long.d.ts +54 -0
- package/dist/skating/long.js +111 -0
- package/dist/skating/parts.d.ts +43 -0
- package/dist/skating/parts.js +40 -0
- package/dist/skating/plan.d.ts +55 -0
- package/dist/skating/plan.js +197 -0
- package/dist/skating/short.d.ts +47 -0
- package/dist/skating/short.js +89 -0
- package/dist/skating/track.d.ts +66 -0
- package/dist/skating/track.js +94 -0
- package/dist/skating/types.d.ts +57 -0
- package/dist/skating/types.js +3 -0
- package/dist/skating-entry.d.ts +17 -0
- package/dist/skating-entry.js +11 -0
- package/dist/skating.style.d.ts +4 -0
- package/dist/skating.style.js +24 -0
- package/dist/strings.d.ts +470 -0
- package/dist/strings.js +674 -13
- package/dist/style.d.ts +2 -0
- package/dist/style.js +19 -2
- package/dist/surfaces/artistic.d.ts +9 -0
- package/dist/surfaces/artistic.js +94 -0
- package/dist/surfaces/athletics.d.ts +16 -0
- package/dist/surfaces/athletics.js +132 -0
- package/dist/surfaces/baseball.js +17 -0
- package/dist/surfaces/basketball.floor.d.ts +27 -0
- package/dist/surfaces/basketball.floor.js +83 -0
- package/dist/surfaces/basketball.gear.d.ts +27 -0
- package/dist/surfaces/basketball.gear.js +90 -0
- package/dist/surfaces/basketball.js +44 -22
- package/dist/surfaces/budo.d.ts +6 -0
- package/dist/surfaces/budo.js +104 -0
- package/dist/surfaces/curling.d.ts +16 -0
- package/dist/surfaces/curling.fold.d.ts +67 -0
- package/dist/surfaces/curling.fold.js +107 -0
- package/dist/surfaces/curling.js +37 -3
- package/dist/surfaces/dive.d.ts +9 -0
- package/dist/surfaces/dive.js +128 -0
- package/dist/surfaces/field.d.ts +7 -2
- package/dist/surfaces/field.js +15 -9
- package/dist/surfaces/football.js +7 -0
- package/dist/surfaces/hockey.js +4 -2
- package/dist/surfaces/net.d.ts +2 -1
- package/dist/surfaces/net.js +160 -15
- package/dist/surfaces/polo.d.ts +12 -0
- package/dist/surfaces/polo.js +159 -0
- package/dist/surfaces/pool.d.ts +27 -0
- package/dist/surfaces/pool.js +198 -0
- package/dist/surfaces/skating.d.ts +6 -0
- package/dist/surfaces/skating.js +62 -0
- package/dist/surfaces/soccer.js +2 -1
- package/dist/surfaces/surface.d.ts +76 -0
- package/dist/surfaces/venue.d.ts +15 -0
- package/dist/surfaces/venue.js +95 -0
- package/dist/target-entry.d.ts +2 -0
- package/dist/target-entry.js +2 -0
- package/dist/target.d.ts +200 -0
- package/dist/target.js +525 -0
- package/dist/team.common.d.ts +1 -1
- package/dist/team.common.js +3 -3
- package/dist/team.formation.d.ts +3 -1
- package/dist/team.formation.js +3 -3
- package/dist/team.layers.d.ts +2 -2
- package/dist/team.layers.js +4 -1
- package/dist/team.lineup.d.ts +27 -0
- package/dist/team.lineup.js +207 -0
- package/dist/team.network.js +6 -5
- package/dist/team.shape.js +5 -5
- package/dist/team.types.d.ts +40 -1
- package/dist/tenants.d.ts +77 -0
- package/dist/tenants.data.d.ts +8 -0
- package/dist/tenants.data.js +1793 -0
- package/dist/tenants.js +46 -0
- package/dist/turn-entry.d.ts +12 -0
- package/dist/turn-entry.js +7 -0
- package/dist/turn.camera.d.ts +116 -0
- package/dist/turn.camera.js +184 -0
- package/dist/turn.dom.d.ts +40 -0
- package/dist/turn.dom.js +353 -0
- package/dist/turn.kit.d.ts +86 -0
- package/dist/turn.kit.js +110 -0
- package/dist/turn.markup.d.ts +48 -0
- package/dist/turn.markup.js +108 -0
- package/dist/turn.model.d.ts +78 -0
- package/dist/turn.model.js +91 -0
- package/dist/turn.style.d.ts +5 -0
- package/dist/turn.style.js +56 -0
- package/dist/types.d.ts +221 -20
- package/dist/units.d.ts +1 -1
- package/dist/units.js +22 -1
- package/dist/uprights.board.d.ts +17 -0
- package/dist/uprights.board.js +59 -0
- package/dist/uprights.budo.d.ts +17 -0
- package/dist/uprights.budo.js +87 -0
- package/dist/uprights.d.ts +37 -0
- package/dist/uprights.fields.d.ts +32 -0
- package/dist/uprights.fields.js +172 -0
- package/dist/uprights.goal.d.ts +49 -0
- package/dist/uprights.goal.js +69 -0
- package/dist/uprights.js +169 -0
- package/dist/uprights.more.d.ts +7 -0
- package/dist/uprights.more.js +183 -0
- package/dist/uprights.net.d.ts +12 -0
- package/dist/uprights.net.js +109 -0
- package/dist/uprights.netkit.d.ts +28 -0
- package/dist/uprights.netkit.js +67 -0
- package/dist/uprights.pools.d.ts +8 -0
- package/dist/uprights.pools.js +190 -0
- package/dist/uprights.rinks.d.ts +27 -0
- package/dist/uprights.rinks.js +106 -0
- package/dist/uprights.track.d.ts +50 -0
- package/dist/uprights.track.js +246 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/zones-entry.d.ts +2 -0
- package/dist/zones-entry.js +2 -0
- package/package.json +56 -3
package/dist/look.js
CHANGED
|
@@ -8,9 +8,12 @@ const PROPERTY = {
|
|
|
8
8
|
red: "--ky-red", blue: "--ky-blue", dirt: "--ky-dirt", foul: "--ky-foul", infield: "--ky-infield", crease: "--ky-crease", key: "--ky-key", court: "--ky-court",
|
|
9
9
|
post: "--ky-post", pylon: "--ky-pylon", rgo: "--ky-rg-o", rgm: "--ky-rg-m", rgi: "--ky-rg-i", rgb: "--ky-rg-b", hog: "--ky-hog", hack: "--ky-hack",
|
|
10
10
|
fgz: "--ky-fgz", pebble: "--ky-pebble", free: "--ky-free", net: "--ky-net", area: "--ky-area",
|
|
11
|
+
ropeg: "--ky-pg", ropeb: "--ky-pb", ropey: "--ky-py", roper: "--ky-pr", ropew: "--ky-pw", pad: "--ky-pd", block: "--ky-pk",
|
|
12
|
+
track: "--ky-track", sand: "--ky-sand", mat: "--ky-mat", water: "--ky-water", concrete: "--ky-concrete", trackpad: "--ky-pad",
|
|
13
|
+
markY: "--ky-ath-y", markB: "--ky-ath-b", markG: "--ky-ath-g", markR: "--ky-ath-r",
|
|
11
14
|
};
|
|
12
15
|
/** The sports of each group. */
|
|
13
|
-
const GROUP_SPORTS = { football: ["nfl", "cfl", "ifaf"], nhl: ["nhl"], nba: ["nba"], mlb: ["mlb"], soccer: ["soccer"], curling: ["curling"], net: ["tennis", "volleyball", "badminton", "pickleball", "tabletennis"] };
|
|
16
|
+
const GROUP_SPORTS = { football: ["nfl", "cfl", "ifaf"], nhl: ["nhl", "skating"], nba: ["nba"], mlb: ["mlb"], soccer: ["soccer"], curling: ["curling"], net: ["tennis", "volleyball", "badminton", "pickleball", "tabletennis", "padel", "squash", "racquetball", "sepaktakraw", "teqball", "roundnet", "netball"], pool: ["swimming", "waterpolo", "diving", "artisticswimming"], athletics: ["athletics"] };
|
|
14
17
|
/** The group a sport is painted with, or `undefined` for a surface with no palette of its own (it takes the look's base). */
|
|
15
18
|
export const groupOf = (sport) => Object.keys(GROUP_SPORTS).find((group) => GROUP_SPORTS[group].includes(sport));
|
|
16
19
|
// ---- The looks. ----
|
|
@@ -25,6 +28,8 @@ const GRASS = {
|
|
|
25
28
|
soccer: { surface: "#4c9b56", alt: "#438f4d", apron: "#c9d2bd" },
|
|
26
29
|
curling: { surface: "#eaf3f9", apron: "#cfd8de", boards: "#8d98a0", line: "#23292d", rgo: "#2a5db0", rgm: "#ffffff", rgi: "#c8372d", rgb: "#ffffff", hog: "#c8372d", hack: "#3a4046", fgz: "rgba(42,93,176,.1)", pebble: "rgba(110,140,165,.4)" },
|
|
27
30
|
net: { surface: "#3d78bd", alt: "#3d78bd", free: "#2f5f9a", apron: "#dcd8c9", area: "#4a86c8", net: "#20262b" },
|
|
31
|
+
pool: { surface: "#3fb4e6", alt: "#2a9bd2", apron: "#e3e1d9", boards: "#f7f6f1", line: "#0c3a5c", ropeg: "#1fa35a", ropeb: "#1b66d3", ropey: "#f4c514", roper: "#e0392f", ropew: "#fbfcfd", pad: "#f3d32c", block: "#454f59" },
|
|
32
|
+
athletics: { surface: "#4c9b56", alt: "#438f4d", apron: "#d9d6c8", track: "#c05a46", sand: "#e3cf9d", mat: "#3d6fb5", water: "#7cc4ee", concrete: "#a9adb0", trackpad: "#40454a" },
|
|
28
33
|
},
|
|
29
34
|
},
|
|
30
35
|
dark: {
|
|
@@ -36,6 +41,8 @@ const GRASS = {
|
|
|
36
41
|
soccer: { surface: "#2d6c3e", alt: "#276136", apron: "#1b1f1c" },
|
|
37
42
|
curling: { surface: "#8fa6b7", apron: "#1a2025", boards: "#4b5156", line: "#11171b", rgo: "#3f6cc0", rgm: "#dfe8ef", rgi: "#c9473e", rgb: "#dfe8ef", hog: "#8a1f19", hack: "#161b1f", fgz: "rgba(20,40,90,.18)", pebble: "rgba(80,105,125,.4)" },
|
|
38
43
|
net: { surface: "#2f5f99", alt: "#2f5f99", free: "#244a78", apron: "#1b1f1c", area: "#3a6fae", net: "#e6e9ec" },
|
|
44
|
+
pool: { surface: "#1d7aa8", alt: "#176b97", apron: "#1f252a", boards: "#3a434b", line: "#031118", ropeg: "#2bb169", ropeb: "#3d86ea", ropey: "#efc22a", roper: "#e65248", ropew: "#e9eef2", pad: "#dcc23a", block: "#6a7683" },
|
|
45
|
+
athletics: { surface: "#2d6c3e", alt: "#276136", apron: "#1b1f1c", track: "#9a4636", sand: "#a89568", mat: "#2c528a", water: "#4d8fb8", concrete: "#6e7377", trackpad: "#1f2326" },
|
|
39
46
|
},
|
|
40
47
|
},
|
|
41
48
|
};
|
|
@@ -47,6 +54,7 @@ const NIGHT_DARK = {
|
|
|
47
54
|
mlb: { surface: "#1d4a2c" },
|
|
48
55
|
soccer: { surface: "#1d4a2c" },
|
|
49
56
|
curling: { surface: "#2a3a47", boards: "#3a4652", line: "#e6eef5", rgo: "#6a97ff", rgm: "#dfe8ef", rgi: "#ff6b5e", rgb: "#dfe8ef", hog: "#ff7a6e", hack: "#c9d3da", fgz: "rgba(120,160,255,.12)", pebble: "rgba(190,210,225,.35)" },
|
|
57
|
+
pool: { surface: "#14587a", alt: "#104a68", apron: "#070a10", boards: "#232b38", line: "#d4e9f5", ropeg: "#2bb169", ropeb: "#3d86ea", ropey: "#efc22a", roper: "#e65248", ropew: "#e9eef2", pad: "#dcc23a", block: "#6a7683" },
|
|
50
58
|
},
|
|
51
59
|
};
|
|
52
60
|
const NIGHT = {
|
|
@@ -56,6 +64,7 @@ const NIGHT = {
|
|
|
56
64
|
};
|
|
57
65
|
const chalkboard = (surface, alt, apron) => ({
|
|
58
66
|
base: { ink: "#eef0e6", line: "#f4f1e6", apron, surface, alt, zone: "#26332d", boards: "#4a5a52", red: "#f1a8a0", blue: "#a5c8ee", dirt: "#3e4a42", foul: "#26312b", infield: "#34423a", crease: "#3b4d58", key: "#3a463f", court: "#2e4655", post: "#f2e6a8", pylon: "#f1b98a", rgo: "#a5c8ee", rgm: "#f4f1e6", rgi: "#f1a8a0", rgb: "#f4f1e6", hog: "#f1a8a0", hack: "#d8d4c4", fgz: "rgba(165,200,238,.12)", pebble: "rgba(244,241,230,.25)" },
|
|
67
|
+
groups: { pool: { ropeg: "#9fd8a8", ropeb: "#a5c8ee", ropey: "#f2e6a8", roper: "#f1a8a0", ropew: "#f4f1e6", pad: "#f2e6a8", block: "#5d6e65" } },
|
|
59
68
|
});
|
|
60
69
|
const CHALKBOARD = {
|
|
61
70
|
about: "Chalk on a slate board: white lines, pink and blue chalk for the red and blue ones, for a teaching diagram.",
|
|
@@ -64,6 +73,7 @@ const CHALKBOARD = {
|
|
|
64
73
|
};
|
|
65
74
|
const blueprint = (surface, alt, apron, boards) => ({
|
|
66
75
|
base: { ink: "#e6f1ff", line: "#e6f1ff", apron, surface, alt, zone: alt, boards, red: "#ffd1c9", blue: "#bfe0ff", dirt: "#2a64a8", foul: alt, infield: "#2358a0", crease: "#2f6aae", key: "#164277", court: surface, post: "#ffe08a", pylon: "#ffb86b", rgo: "#8ec1ff", rgm: "#e6f1ff", rgi: "#ffd1c9", rgb: "#e6f1ff", hog: "#ffd1c9", hack: "#cfe3fb", fgz: "rgba(190,224,255,.14)", pebble: "rgba(230,241,255,.25)" },
|
|
76
|
+
groups: { pool: { ropeg: "#8fe0c0", ropeb: "#8ec1ff", ropey: "#ffe08a", roper: "#ffd1c9", ropew: "#e6f1ff", pad: "#ffe08a", block: "#2c63a6" } },
|
|
67
77
|
});
|
|
68
78
|
const BLUEPRINT = {
|
|
69
79
|
about: "White lines on blueprint blue, as a drawing office would print the rulebook's plan.",
|
|
@@ -74,9 +84,11 @@ const PRINT = {
|
|
|
74
84
|
about: "Black on white with greys for the parts a colour would tell apart: for a printer that has no colour (dark: the same as white on black).",
|
|
75
85
|
light: {
|
|
76
86
|
base: { ink: "#111111", line: "#111111", apron: "#ffffff", surface: "#ffffff", alt: "#f0f0f0", zone: "#d9d9d9", boards: "#888888", red: "#444444", blue: "#111111", dirt: "#d6d6d6", foul: "#fafafa", infield: "#ececec", crease: "#e4e4e4", key: "#d4d4d4", court: "#e8e8e8", post: "#333333", pylon: "#333333", rgo: "#666666", rgm: "#eeeeee", rgi: "#999999", rgb: "#ffffff", hog: "#444444", hack: "#222222", fgz: "rgba(0,0,0,.08)", pebble: "rgba(0,0,0,.18)" },
|
|
87
|
+
groups: { pool: { ropeg: "#555555", ropeb: "#8a8a8a", ropey: "#bdbdbd", roper: "#333333", ropew: "#ffffff", pad: "#dddddd", block: "#444444" } },
|
|
77
88
|
},
|
|
78
89
|
dark: {
|
|
79
90
|
base: { ink: "#f2f2f2", line: "#f2f2f2", apron: "#000000", surface: "#111111", alt: "#1a1a1a", zone: "#2a2a2a", boards: "#777777", red: "#cfcfcf", blue: "#ffffff", dirt: "#333333", foul: "#0a0a0a", infield: "#1e1e1e", crease: "#262626", key: "#2e2e2e", court: "#1c1c1c", post: "#dddddd", pylon: "#dddddd", rgo: "#aaaaaa", rgm: "#222222", rgi: "#777777", rgb: "#000000", hog: "#cfcfcf", hack: "#eeeeee", fgz: "rgba(255,255,255,.1)", pebble: "rgba(255,255,255,.2)" },
|
|
91
|
+
groups: { pool: { ropeg: "#cfcfcf", ropeb: "#8f8f8f", ropey: "#5c5c5c", roper: "#e6e6e6", ropew: "#ffffff", pad: "#777777", block: "#cfcfcf" } },
|
|
80
92
|
},
|
|
81
93
|
};
|
|
82
94
|
const BROADCAST_LIGHT = {
|
|
@@ -85,6 +97,7 @@ const BROADCAST_LIGHT = {
|
|
|
85
97
|
nhl: { surface: "#f4f9ff", alt: "#ecf3fb", boards: "#3b4d66", red: "#d11f17", blue: "#1a49c4" },
|
|
86
98
|
nba: { surface: "#b97a2e", alt: "#af7228", key: "#1d4ed8", boards: "#6b4318" },
|
|
87
99
|
curling: { surface: "#f4f9ff", boards: "#3b4d66", line: "#0d1b2e", rgo: "#1a49c4", rgm: "#ffffff", rgi: "#d11f17", rgb: "#ffffff", hog: "#d11f17", hack: "#1a2a40", fgz: "rgba(26,73,196,.12)", pebble: "rgba(80,110,150,.4)" },
|
|
100
|
+
pool: { surface: "#1b9ad6", alt: "#1480b8", apron: "#0d1b2e", boards: "#1a2a40", line: "#06243a", ropeg: "#17b45e", ropeb: "#1f56d6", ropey: "#ffd21f", roper: "#e0342b", ropew: "#ffffff", pad: "#ffd21f", block: "#2c3a50" },
|
|
88
101
|
},
|
|
89
102
|
};
|
|
90
103
|
const BROADCAST = {
|
|
@@ -96,6 +109,7 @@ const BROADCAST = {
|
|
|
96
109
|
nhl: { surface: "#2f4e6e", alt: "#2a4766", boards: "#223047", red: "#ff8a80", blue: "#8db6ff" },
|
|
97
110
|
nba: { surface: "#8f5b1f", alt: "#865418", key: "#1d4ed8", boards: "#4a2f10" },
|
|
98
111
|
curling: { surface: "#7f9db8", boards: "#223047", line: "#0d1b2e", rgo: "#1a49c4", rgm: "#e6eef5", rgi: "#b3140d", rgb: "#e6eef5", hog: "#8f0f09", hack: "#0d1b2e", fgz: "rgba(26,73,196,.15)", pebble: "rgba(40,70,100,.35)" },
|
|
112
|
+
pool: { surface: "#1479ad", alt: "#10688f", apron: "#060d18", boards: "#223047", line: "#021018", ropeg: "#17b45e", ropeb: "#3d86ea", ropey: "#ffd21f", roper: "#e0342b", ropew: "#ffffff", pad: "#ffd21f", block: "#2c3a50" },
|
|
99
113
|
},
|
|
100
114
|
},
|
|
101
115
|
};
|
|
@@ -103,9 +117,23 @@ const HIGH_CONTRAST = {
|
|
|
103
117
|
about: "Black on white, or white on black: every line at the highest contrast the colours allow (WCAG AAA), for low vision and for projectors.",
|
|
104
118
|
light: {
|
|
105
119
|
base: { ink: "#000000", line: "#000000", apron: "#ffffff", surface: "#ffffff", alt: "#e6e6e6", zone: "#e6e6e6", boards: "#000000", red: "#b00020", blue: "#0030c0", dirt: "#d0d0d0", foul: "#f2f2f2", infield: "#e0e0e0", crease: "#dcdcdc", key: "#cfcfcf", court: "#e6e6e6", post: "#000000", pylon: "#000000", rgo: "#0030c0", rgm: "#ffffff", rgi: "#b00020", rgb: "#ffffff", hog: "#b00020", hack: "#000000", fgz: "rgba(0,48,192,.12)", pebble: "rgba(0,0,0,.25)" },
|
|
120
|
+
groups: { pool: { ropeg: "#006b2d", ropeb: "#0030c0", ropey: "#7a5c00", roper: "#b00020", ropew: "#000000", pad: "#e0e0e0", block: "#000000" } },
|
|
106
121
|
},
|
|
107
122
|
dark: {
|
|
108
123
|
base: { ink: "#ffffff", line: "#ffffff", apron: "#000000", surface: "#000000", alt: "#141414", zone: "#141414", boards: "#ffffff", red: "#ff6b6b", blue: "#7fb2ff", dirt: "#3a3a3a", foul: "#0a0a0a", infield: "#222222", crease: "#1a2a40", key: "#333333", court: "#0a0a0a", post: "#ffeb3b", pylon: "#ffeb3b", rgo: "#7fb2ff", rgm: "#000000", rgi: "#ff6b6b", rgb: "#000000", hog: "#ff6b6b", hack: "#ffffff", fgz: "rgba(127,178,255,.18)", pebble: "rgba(255,255,255,.3)" },
|
|
124
|
+
groups: { pool: { ropeg: "#4ade80", ropeb: "#7fb2ff", ropey: "#ffeb3b", roper: "#ff6b6b", ropew: "#ffffff", pad: "#444444", block: "#ffffff" } },
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const LINE_DRAWING = {
|
|
128
|
+
about: "Ink only: black lines on white and nothing filled, for a plan that prints on any printer and copies cleanly (dark: white lines on black).",
|
|
129
|
+
light: {
|
|
130
|
+
base: { ink: "#000000", line: "#000000", apron: "#ffffff", surface: "#ffffff", alt: "#ffffff", zone: "#ffffff", boards: "#000000", red: "#000000", blue: "#000000", dirt: "#ffffff", foul: "#ffffff", infield: "#ffffff", crease: "#ffffff", key: "#ffffff", court: "#ffffff", post: "#000000", pylon: "#000000", rgo: "#ffffff", rgm: "#ffffff", rgi: "#ffffff", rgb: "#ffffff", hog: "#000000", hack: "#000000", fgz: "rgba(0,0,0,0)", pebble: "rgba(0,0,0,0)", markY: "#000000", markB: "#000000", markG: "#000000", markR: "#000000" },
|
|
131
|
+
// An athletics stadium in ink: nothing filled but the pads of a pole vault box, so that a pit, a mat, a circle and the track are their outlines.
|
|
132
|
+
groups: { athletics: { track: "#ffffff", sand: "#ffffff", mat: "#ffffff", water: "#ffffff", concrete: "#ffffff", trackpad: "#000000" } },
|
|
133
|
+
},
|
|
134
|
+
dark: {
|
|
135
|
+
base: { ink: "#ffffff", line: "#ffffff", apron: "#000000", surface: "#000000", alt: "#000000", zone: "#000000", boards: "#ffffff", red: "#ffffff", blue: "#ffffff", dirt: "#000000", foul: "#000000", infield: "#000000", crease: "#000000", key: "#000000", court: "#000000", post: "#ffffff", pylon: "#ffffff", rgo: "#000000", rgm: "#000000", rgi: "#000000", rgb: "#000000", hog: "#ffffff", hack: "#ffffff", fgz: "rgba(0,0,0,0)", pebble: "rgba(0,0,0,0)", markY: "#ffffff", markB: "#ffffff", markG: "#ffffff", markR: "#ffffff" },
|
|
136
|
+
groups: { athletics: { track: "#000000", sand: "#000000", mat: "#000000", water: "#000000", concrete: "#000000", trackpad: "#ffffff" } },
|
|
109
137
|
},
|
|
110
138
|
};
|
|
111
139
|
/**
|
|
@@ -115,22 +143,24 @@ const HIGH_CONTRAST = {
|
|
|
115
143
|
* import { LOOKS, drawKyogijo } from "@johnmorrisdotca/kyogijo-stadiums";
|
|
116
144
|
* const svg = drawKyogijo({ sport: "nhl", look: "chalkboard" });
|
|
117
145
|
* console.log(Object.keys(LOOKS).length, svg.includes('data-palette="chalkboard"'));
|
|
118
|
-
* //
|
|
146
|
+
* // 8 true
|
|
119
147
|
* ```
|
|
120
148
|
*/
|
|
121
|
-
export const LOOKS = { grass: GRASS, night: NIGHT, chalkboard: CHALKBOARD, blueprint: BLUEPRINT, print: PRINT, broadcast: BROADCAST, "high-contrast": HIGH_CONTRAST };
|
|
149
|
+
export const LOOKS = { grass: GRASS, night: NIGHT, chalkboard: CHALKBOARD, blueprint: BLUEPRINT, print: PRINT, broadcast: BROADCAST, "high-contrast": HIGH_CONTRAST, "line-drawing": LINE_DRAWING };
|
|
122
150
|
/** The names of the looks, in the order a menu lists them. */
|
|
123
151
|
export const LOOK_NAMES = Object.freeze(Object.keys(LOOKS));
|
|
124
152
|
/** True when a value names a look. */
|
|
125
153
|
export const isLook = (value) => typeof value === "string" && Object.prototype.hasOwnProperty.call(LOOKS, value);
|
|
126
154
|
/** What the net sports' courts paint besides the surface and the apron, when a look does not say: the free zone in the second tone, a painted area in the key's, the net in the line's. */
|
|
127
155
|
const withNet = (palette) => ({ free: palette.alt, area: palette.key, net: palette.line, ...palette });
|
|
156
|
+
/** What an athletics stadium paints besides the surface and the apron, when a look does not say: the track in the dirt's colour, the sand and the concrete in the boards', the mat in the court's, the water in the crease's, the pads in the ink. */
|
|
157
|
+
const withTrack = (palette) => ({ track: palette.dirt, sand: palette.boards, mat: palette.court, water: palette.crease, concrete: palette.boards, pad: palette.ink, ...palette });
|
|
128
158
|
/** A look's palette for a sport in one mode: the look's base with what the sport's group changes. */
|
|
129
159
|
export function lookPalette(look, mode, sport) {
|
|
130
160
|
const m = LOOKS[look][mode];
|
|
131
161
|
const group = groupOf(sport);
|
|
132
162
|
const merged = { ...m.base, ...(group === undefined ? {} : m.groups?.[group]) };
|
|
133
|
-
return group === "net" ? withNet(merged) : merged;
|
|
163
|
+
return group === "net" ? withNet(merged) : group === "athletics" ? withTrack(merged) : merged;
|
|
134
164
|
}
|
|
135
165
|
/**
|
|
136
166
|
* The pairs of a palette that must read: what is painted on what, as `[ink, ground, least contrast]` (WCAG 2.2's 3:1 for a line, 4.5:1 for text). The words
|
|
@@ -146,6 +176,8 @@ export const LOOK_PAIRS = {
|
|
|
146
176
|
soccer: [["line", "surface", 3], ["line", "alt", 3], ["line", "court", 3]],
|
|
147
177
|
curling: [["line", "surface", 3], ["hog", "surface", 3], ["hack", "surface", 3]],
|
|
148
178
|
net: [["line", "surface", 3], ["line", "free", 3], ["line", "area", 3]],
|
|
179
|
+
pool: [["line", "surface", 3], ["line", "alt", 3]],
|
|
180
|
+
athletics: [["line", "surface", 3], ["line", "track", 3]],
|
|
149
181
|
};
|
|
150
182
|
/** The contrast ratio of two colours (WCAG 2.2): 1 to 21, or `undefined` when a colour cannot be read without a browser. */
|
|
151
183
|
export function contrastOf(a, b) {
|
|
@@ -163,12 +195,13 @@ const declarations = (palette) => Object.keys(palette)
|
|
|
163
195
|
/** The rules of one mode of one look, for the base and each group, behind a selector that says which mode it is. */
|
|
164
196
|
function modeRules(name, mode, wrap) {
|
|
165
197
|
const out = [`${wrap(`.kyogijo[data-palette=${name}]`)}{${declarations(mode.base)}}`];
|
|
166
|
-
const groups = new Set([...Object.keys(mode.groups ?? {}), "net"]);
|
|
198
|
+
const groups = new Set([...Object.keys(mode.groups ?? {}), "net", "athletics"]);
|
|
167
199
|
for (const group of groups) {
|
|
168
200
|
const palette = mode.groups?.[group] ?? {};
|
|
169
201
|
// A net sport's court has three colours the other surfaces have not: the group's rule carries them, made from the base where the look gives none.
|
|
170
202
|
const net = group === "net" ? withNet({ ...mode.base, ...palette }) : {};
|
|
171
|
-
const
|
|
203
|
+
const track = group === "athletics" ? withTrack({ ...mode.base, ...palette }) : {};
|
|
204
|
+
const written = group === "net" ? { ...palette, free: net.free, area: net.area, net: net.net } : group === "athletics" ? { ...palette, track: track.track, sand: track.sand, mat: track.mat, water: track.water, concrete: track.concrete, trackpad: track.pad } : palette;
|
|
172
205
|
out.push(`${wrap(GROUP_SPORTS[group].map((sport) => `.kyogijo[data-palette=${name}][data-sport=${sport}]`).join(","))}{${declarations(written)}}`);
|
|
173
206
|
}
|
|
174
207
|
return out;
|
package/dist/outline.d.ts
CHANGED
|
@@ -22,4 +22,4 @@ export declare const frameSizeOf: (o: Pick<SurfaceOptions, "sport" | "league">,
|
|
|
22
22
|
unit: "ft";
|
|
23
23
|
} | undefined;
|
|
24
24
|
/** The outline of the surface the options draw. */
|
|
25
|
-
export declare function outlineOf(o: Pick<SurfaceOptions, "sport" | "park" | "fence" | "units" | "pitch" | "league" | "year" | "sheet" | "net"> & Partial<Pick<SurfaceOptions, "field" | "detail">>): Outline;
|
|
25
|
+
export declare function outlineOf(o: Pick<SurfaceOptions, "sport" | "park" | "fence" | "units" | "pitch" | "league" | "year" | "sheet" | "net"> & Partial<Pick<SurfaceOptions, "field" | "detail" | "pool" | "athletics" | "skating" | "budo" | "dojo" | "arena">>): Outline;
|
package/dist/outline.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// a ballpark's x is across the field and its y minus the distance out from home plate): where a data layer is cut, and the size
|
|
3
3
|
// its marks follow.
|
|
4
4
|
import { FEET_PER_METRE, FOOTBALL, NBA, NHL, footballLength, surfaceSize } from "./geometry.js";
|
|
5
|
+
import { arenaById, arenaCourtIn, arenaRinkIn } from "./arenas.js";
|
|
5
6
|
import { chooseLeague, courtOf, diamondOf, fieldOf, rinkOf } from "./leagues.js";
|
|
6
7
|
import { diamondFence } from "./leagues/baseball.js";
|
|
7
8
|
import { fenceFor, parkById } from "./parks.js";
|
|
@@ -14,6 +15,10 @@ import { courtFor, courtSize, isNetSport } from "./court.js";
|
|
|
14
15
|
import { fieldPlan, isFieldSport } from "./fields.js";
|
|
15
16
|
import { inOutline, outlineD } from "./fields.kit.js";
|
|
16
17
|
import { sheetFor } from "./sheet.js";
|
|
18
|
+
import { isPoolSport, poolBox } from "./pool.js";
|
|
19
|
+
import { athleticsPlan } from "./athletics/plan.js";
|
|
20
|
+
import { skatingPlan } from "./skating/plan.js";
|
|
21
|
+
import { budoPlan, isBudoSport } from "./budo/plan.js";
|
|
17
22
|
const inBox = (box, x, y) => x >= box.x && x <= box.x + box.w && y >= box.y && y <= box.y + box.h;
|
|
18
23
|
const rect = (w, h) => {
|
|
19
24
|
const box = { x: 0, y: 0, w, h };
|
|
@@ -31,7 +36,7 @@ function inPolygon(points, x, y) {
|
|
|
31
36
|
return inside;
|
|
32
37
|
}
|
|
33
38
|
/** The size a provider's frame is fitted to: the drawn surface's own `box`, for a soccer pitch, a curling sheet, a net sport's court and a league's surface; none for a sport's own fixed one. */
|
|
34
|
-
export const frameSizeOf = (o, box) => o.sport === "soccer" || o.sport === "curling" || isNetSport(o.sport) || isFieldSport(o.sport) || chooseLeague(o).league !== undefined ? { length: box.w, width: box.h, unit: "ft" } : undefined;
|
|
39
|
+
export const frameSizeOf = (o, box) => o.sport === "soccer" || o.sport === "curling" || isNetSport(o.sport) || isFieldSport(o.sport) || isPoolSport(o.sport) || o.sport === "athletics" || o.sport === "skating" || isBudoSport(o.sport) || chooseLeague(o).league !== undefined ? { length: box.w, width: box.h, unit: "ft" } : undefined;
|
|
35
40
|
/** The outline of the surface the options draw. */
|
|
36
41
|
export function outlineOf(o) {
|
|
37
42
|
const { sport, league } = chooseLeague(o);
|
|
@@ -47,7 +52,8 @@ export function outlineOf(o) {
|
|
|
47
52
|
}
|
|
48
53
|
case "nhl": {
|
|
49
54
|
const rink = league?.family === "hockey" ? rinkOf(league, o.year) : undefined;
|
|
50
|
-
const
|
|
55
|
+
const sized = league === undefined ? arenaRinkIn(arenaById(o.arena), o.year) : undefined;
|
|
56
|
+
const [length, width, r] = rink !== undefined ? [rink.length, rink.width, rink.cornerRadius] : sized !== undefined ? [sized.length, sized.width, NHL.cornerRadius] : [NHL.length, NHL.width, NHL.cornerRadius];
|
|
51
57
|
const box = { x: 0, y: 0, w: length, h: width };
|
|
52
58
|
// A rectangle with quarter-circle corners: outside only when a point is in a corner's square but beyond its arc.
|
|
53
59
|
const contains = (x, y) => {
|
|
@@ -64,7 +70,8 @@ export function outlineOf(o) {
|
|
|
64
70
|
const court = courtOf(league, o.year);
|
|
65
71
|
return rect(court.length, court.width);
|
|
66
72
|
}
|
|
67
|
-
|
|
73
|
+
const sized = league === undefined ? arenaCourtIn(arenaById(o.arena), o.year) : undefined;
|
|
74
|
+
return sized === undefined ? rect(NBA.length, NBA.width) : rect(sized.length, sized.width);
|
|
68
75
|
}
|
|
69
76
|
case "mlb": {
|
|
70
77
|
const generic = league?.family === "baseball" ? diamondFence(diamondOf(league, o.year)) : undefined;
|
|
@@ -89,7 +96,14 @@ export function outlineOf(o) {
|
|
|
89
96
|
case "volleyball":
|
|
90
97
|
case "badminton":
|
|
91
98
|
case "pickleball":
|
|
92
|
-
case "tabletennis":
|
|
99
|
+
case "tabletennis":
|
|
100
|
+
case "padel":
|
|
101
|
+
case "squash":
|
|
102
|
+
case "racquetball":
|
|
103
|
+
case "sepaktakraw":
|
|
104
|
+
case "teqball":
|
|
105
|
+
case "roundnet":
|
|
106
|
+
case "netball": {
|
|
93
107
|
const { length, width } = courtSize(courtFor({ ...o, sport }));
|
|
94
108
|
return rect(length, width);
|
|
95
109
|
}
|
|
@@ -103,6 +117,34 @@ export function outlineOf(o) {
|
|
|
103
117
|
const plan = fieldPlan({ ...o, sport });
|
|
104
118
|
return { d: outlineD(plan.length, plan.width, plan.outline), box: { x: 0, y: 0, w: plan.length, h: plan.width }, contains: (x, y) => inOutline(plan.length, plan.width, plan.outline, x, y) };
|
|
105
119
|
}
|
|
120
|
+
case "swimming":
|
|
121
|
+
case "waterpolo":
|
|
122
|
+
case "diving":
|
|
123
|
+
case "artisticswimming": {
|
|
124
|
+
// The water of the pool: the deck round it is the margin. A natatorium's is the whole hall.
|
|
125
|
+
const { w, h } = poolBox({ ...o, sport });
|
|
126
|
+
return rect(w, h);
|
|
127
|
+
}
|
|
128
|
+
case "skating": {
|
|
129
|
+
const plan = skatingPlan(o);
|
|
130
|
+
const k = 1 / 0.3048;
|
|
131
|
+
return rect((plan.box.x1 - plan.box.x0) * k, (plan.box.y1 - plan.box.y0) * k);
|
|
132
|
+
}
|
|
133
|
+
case "judo":
|
|
134
|
+
case "karate":
|
|
135
|
+
case "kendo":
|
|
136
|
+
case "sumo":
|
|
137
|
+
case "kyudo":
|
|
138
|
+
case "dojo": {
|
|
139
|
+
const plan = budoPlan({ ...o, sport, detail: o.detail });
|
|
140
|
+
const k = 1 / 0.3048;
|
|
141
|
+
return rect((plan.box.x1 - plan.box.x0) * k, (plan.box.y1 - plan.box.y0) * k);
|
|
142
|
+
}
|
|
143
|
+
case "athletics": {
|
|
144
|
+
const plan = athleticsPlan(o);
|
|
145
|
+
const k = 1 / 0.3048;
|
|
146
|
+
return rect((plan.box.x1 - plan.box.x0) * k, (plan.box.y1 - plan.box.y0) * k);
|
|
147
|
+
}
|
|
106
148
|
default: {
|
|
107
149
|
// A surface added later with one size is a rectangle until it says otherwise.
|
|
108
150
|
const size = surfaceSize(o.sport, "ft");
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Outline } from "./outline.ts";
|
|
2
|
+
import type { Surface } from "./surfaces/surface.ts";
|
|
3
|
+
import type { PageantStyle, Side, Sport, SurfaceOptions, Team } from "./types.ts";
|
|
4
|
+
/** The border band of a carpet, as a share of its shorter side: the least, the most and the usual. */
|
|
5
|
+
export declare const PAGEANT_BORDER: {
|
|
6
|
+
readonly min: 0.02;
|
|
7
|
+
readonly max: 0.15;
|
|
8
|
+
readonly usual: 0.06;
|
|
9
|
+
};
|
|
10
|
+
/** The least and the most a carpet or a stage is scaled to, as a share of the room its half gives it. */
|
|
11
|
+
export declare const PAGEANT_SCALE: {
|
|
12
|
+
readonly min: 0.4;
|
|
13
|
+
readonly max: 1;
|
|
14
|
+
};
|
|
15
|
+
/** The ratio of a carpet's width over its height: a flag of 3 to 2 unless the team or its SVG says otherwise, held between a square and 3 to 1. */
|
|
16
|
+
export declare const PAGEANT_RATIO: {
|
|
17
|
+
readonly min: 1;
|
|
18
|
+
readonly max: 3;
|
|
19
|
+
readonly usual: 1.5;
|
|
20
|
+
};
|
|
21
|
+
/** How far a filled carpet's ratio may differ from its flag's, as a factor either way: the art is stretched and cropped by its square root. */
|
|
22
|
+
export declare const PAGEANT_FILL_LIMIT = 1.75;
|
|
23
|
+
/** What a pageant is, with every choice made. */
|
|
24
|
+
export interface Pageant {
|
|
25
|
+
style: PageantStyle;
|
|
26
|
+
border: "dark" | "team" | string;
|
|
27
|
+
borderWidth: number;
|
|
28
|
+
fabric: boolean;
|
|
29
|
+
lines: "over" | "under" | "through";
|
|
30
|
+
ring: "gold" | "team" | string;
|
|
31
|
+
emblem?: {
|
|
32
|
+
href: string;
|
|
33
|
+
shape: "round" | "plain";
|
|
34
|
+
fit: "contain" | "cover";
|
|
35
|
+
name?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Where the score goes: the plate in the middle, the compact strip under the drawing, or `auto`, which the drawing decides once it has laid the pictures out (`autoScore`). */
|
|
38
|
+
score: "auto" | "centre" | "strip";
|
|
39
|
+
scale: number;
|
|
40
|
+
fit: "fill" | "ratio";
|
|
41
|
+
names: boolean | undefined;
|
|
42
|
+
animate: "none" | "unfurl" | "fade";
|
|
43
|
+
}
|
|
44
|
+
/** The sports whose score is a plate that a pageant can shrink: a curling sheet's and a net court's boards are drawn to the room they are given and are not. */
|
|
45
|
+
export declare const plateShrinks: (sport: Sport) => boolean;
|
|
46
|
+
/**
|
|
47
|
+
* What the options ask of a pageant, or `undefined` for none: `pageant` unset or `false`, a drawing with no score, one of the badge size, or a special game. A choice that is not one of
|
|
48
|
+
* the values is the default's; a colour must pass `safeColour`, the emblem `safeLogo`, a number is held to its range.
|
|
49
|
+
*/
|
|
50
|
+
export declare function pageantOf(o: SurfaceOptions & {
|
|
51
|
+
home?: unknown;
|
|
52
|
+
away?: unknown;
|
|
53
|
+
size?: unknown;
|
|
54
|
+
}): Pageant | undefined;
|
|
55
|
+
/** How wide a team's carpet is for its height: the team's `logoRatio`, else its SVG logo's own, else 3 to 2; held between a square and 3 to 1. */
|
|
56
|
+
export declare function ratioOf(team: Pick<Team, "logo" | "logoRatio">): number;
|
|
57
|
+
/** A team as the pageant lays it out: a picture or none, its colours and the ratio of its carpet. */
|
|
58
|
+
export interface PageantTeam {
|
|
59
|
+
side: Side;
|
|
60
|
+
role: "home" | "away";
|
|
61
|
+
name: string;
|
|
62
|
+
abbr: string;
|
|
63
|
+
state: "win" | "lose" | "none";
|
|
64
|
+
href: string | undefined;
|
|
65
|
+
/** `cover` fills a carpet or a stage with the picture, `contain` shows it whole on a plain ground. */
|
|
66
|
+
fit: "cover" | "contain";
|
|
67
|
+
ratio: number;
|
|
68
|
+
color: string | undefined;
|
|
69
|
+
ink: string | undefined;
|
|
70
|
+
}
|
|
71
|
+
/** One picture's place, in the surface's frame and in the eye's: the centre, and the size as the eye sees it (a stage's `r` is its radius). */
|
|
72
|
+
export interface Placed {
|
|
73
|
+
team: PageantTeam;
|
|
74
|
+
/** The place it fills: the first (left) or the second (right) of the surface. */
|
|
75
|
+
spot: "left" | "right";
|
|
76
|
+
cx: number;
|
|
77
|
+
cy: number;
|
|
78
|
+
w: number;
|
|
79
|
+
h: number;
|
|
80
|
+
r?: number;
|
|
81
|
+
/** A carpet that fills its room: its art is fitted to it by stretching and cropping, not by its own ratio. */
|
|
82
|
+
filled?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/** Where everything of a pageant goes. */
|
|
85
|
+
export interface PageantLayout {
|
|
86
|
+
pictures: Placed[];
|
|
87
|
+
emblem?: {
|
|
88
|
+
cx: number;
|
|
89
|
+
cy: number;
|
|
90
|
+
r: number;
|
|
91
|
+
};
|
|
92
|
+
/** The size the plate is drawn at in the middle, as a share of its own. */
|
|
93
|
+
plateScale: number;
|
|
94
|
+
}
|
|
95
|
+
/** What the layout is given besides the surface. */
|
|
96
|
+
export interface LayoutInput {
|
|
97
|
+
pageant: Pageant;
|
|
98
|
+
surface: Surface;
|
|
99
|
+
outline: Outline;
|
|
100
|
+
left: PageantTeam;
|
|
101
|
+
right: PageantTeam;
|
|
102
|
+
/** True when the drawing lies tall: the halves are then the top and the bottom as the eye sees them, and each picture is turned back upright. */
|
|
103
|
+
turned: boolean;
|
|
104
|
+
sport: Sport;
|
|
105
|
+
/** True when the plate is drawn in the middle of the surface (a full-size score with its score in the centre). */
|
|
106
|
+
plate: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Where each team's picture and the emblem go. A picture is sized to the room its half gives it (less a margin) at its own ratio, and is moved in until it lies inside the surface's outline
|
|
110
|
+
* (a rink's rounded corners, a ballpark's fence, an oval's curve). The middle is kept clear of the emblem and of the plate: the pictures are narrower where they must be.
|
|
111
|
+
* @returns `undefined` when the surface has no playing area to lay a picture on.
|
|
112
|
+
*/
|
|
113
|
+
export declare function pageantLayout(input: LayoutInput): PageantLayout | undefined;
|
|
114
|
+
/** How much of their width the pictures must keep with the plate in the middle, against without it, before the plate in the middle gives way to the strip. */
|
|
115
|
+
export declare const PLATE_COST = 0.7;
|
|
116
|
+
/**
|
|
117
|
+
* Where the score goes when the options say `auto` and there is no emblem or board: the plate stays in the middle if the pictures lose little of their size to it, otherwise the score
|
|
118
|
+
* goes to the strip under the drawing and the pictures take the room.
|
|
119
|
+
*/
|
|
120
|
+
export declare function autoScore(input: LayoutInput): "centre" | "strip";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Pageant, PageantLayout } from "./pageant.ts";
|
|
2
|
+
/** What a drawing gives the pageant to draw with. */
|
|
3
|
+
export interface PageantDraw {
|
|
4
|
+
/** The prefix of the ids: unique in the drawing. */
|
|
5
|
+
id: string;
|
|
6
|
+
turned: boolean;
|
|
7
|
+
/** Small, or `detail: "simple"`: no fabric, no hairlines, no name pills. */
|
|
8
|
+
simple: boolean;
|
|
9
|
+
parts: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** The pictures of a pageant: each team's carpet or stage, drawn in its place. Under the surface's lines (`lines: "over"`) or over them (`"under"`). */
|
|
12
|
+
export declare function picturesMarkup(layout: PageantLayout, p: Pageant, o: PageantDraw): {
|
|
13
|
+
markup: string;
|
|
14
|
+
defs: string;
|
|
15
|
+
names: string;
|
|
16
|
+
};
|
|
17
|
+
/** The emblem: a competition's picture or a trophy on a disc with a ring in the centre circle, or as it is for a cut-out. */
|
|
18
|
+
export declare function emblemMarkup(layout: PageantLayout, p: Pageant, o: PageantDraw): {
|
|
19
|
+
markup: string;
|
|
20
|
+
defs: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// The pageant drawn: a carpet (a flag or logo laid flat, with a border band and a gentle fabric of light and shade) or a stage (a crest on a round disc with a ring) for each team, and the
|
|
2
|
+
// emblem on a disc in the centre. Every picture is drawn in the eye's frame (its group is turned back when the drawing lies tall), so a flag is always the right way up for a reader.
|
|
3
|
+
import { inkOn } from "./colour.js";
|
|
4
|
+
import { el, esc, num } from "./format.js";
|
|
5
|
+
import { roundMarkup } from "./mark.js";
|
|
6
|
+
import { LINE_HEIGHT, fitLines } from "./text.js";
|
|
7
|
+
/** The gold of a stage's ring, light to dark to light, as a gradient across the disc. */
|
|
8
|
+
const GOLD = [[0, "#f7e6a6"], [0.3, "#d8ae4a"], [0.62, "#a67a1d"], [1, "#ecca6c"]];
|
|
9
|
+
const gradient = (id, x1, y1, x2, y2, stops) => el("linearGradient", { id, gradientUnits: "userSpaceOnUse", x1: num(x1), y1: num(y1), x2: num(x2), y2: num(y2) }, stops.map(([offset, colour, opacity]) => el("stop", { offset: num(offset), style: `stop-color:${colour}${opacity === undefined ? "" : `;stop-opacity:${num(opacity)}`}` })).join(""));
|
|
10
|
+
/**
|
|
11
|
+
* The fabric of a carpet: two gentle waves of light and of shade, as linear gradients across it at slightly different angles, fixed numbers and no random. They lie over the picture at
|
|
12
|
+
* a few hundredths of opacity, so that a flag reads as cloth and its colours stay its own.
|
|
13
|
+
*/
|
|
14
|
+
function fabric(id, w, h) {
|
|
15
|
+
const light = [0, 0.1, 0, 0.07, 0, 0.1, 0, 0.06, 0];
|
|
16
|
+
const shade = [0.07, 0, 0.09, 0, 0.06, 0, 0.09, 0, 0.05];
|
|
17
|
+
const stops = (values, colour) => values.map((v, i) => [i / (values.length - 1), colour, v]);
|
|
18
|
+
const defs = gradient(`${id}-a`, -w / 2, -h * 0.28, w / 2, h * 0.28, stops(light, "#fff")) + gradient(`${id}-b`, -w * 0.46, h * 0.34, w * 0.5, -h * 0.3, stops(shade, "#000"));
|
|
19
|
+
return { defs, markup: (x, y, cw, ch) => el("rect", { class: "ky-pg-fabric", x: num(x), y: num(y), width: num(cw), height: num(ch), fill: `url(#${id}-a)` }) + el("rect", { class: "ky-pg-fabric", x: num(x), y: num(y), width: num(cw), height: num(ch), fill: `url(#${id}-b)` }) };
|
|
20
|
+
}
|
|
21
|
+
/** The group a picture lies in: moved to its centre and turned back upright when the drawing lies tall. */
|
|
22
|
+
function standing(cx, cy, turned, classes, inner, o, part, title, data = {}) {
|
|
23
|
+
return el("g", { class: classes, transform: `translate(${num(cx)} ${num(cy)})${turned ? " rotate(-90)" : ""}`, part: o.parts ? part : undefined, "data-pg": "1", ...data }, (title === undefined ? "" : `<title>${esc(title)}</title>`) + el("g", { class: "ky-pg-art" }, inner));
|
|
24
|
+
}
|
|
25
|
+
const colourVars = (team) => {
|
|
26
|
+
const parts = [team.color === undefined ? undefined : `--c:${team.color}`, team.ink === undefined && team.color === undefined ? undefined : `--ci:${team.ink ?? inkOn(team.color)}`].filter((part) => part !== undefined);
|
|
27
|
+
return parts.length === 0 ? undefined : parts.join(";");
|
|
28
|
+
};
|
|
29
|
+
/** A team's name on its picture, in a pill straddling the picture's lower edge. */
|
|
30
|
+
function pill(team, w, h, bottom, simple) {
|
|
31
|
+
if (simple)
|
|
32
|
+
return "";
|
|
33
|
+
const ph = Math.max(h * 0.17, 0.2);
|
|
34
|
+
const fit = fitLines(team.name, w * 0.78, ph * 0.62, ph * 0.46);
|
|
35
|
+
const pw = Math.min(w * 0.92, fit.width + ph * 1.1);
|
|
36
|
+
return el("g", { class: "ky-pg-label" }, el("rect", { class: "ky-pg-pill", x: num(-pw / 2), y: num(bottom - ph / 2), width: num(pw), height: num(ph), rx: num(ph / 2) }) + el("text", { class: "ky-text ky-pg-pilltext", x: 0, y: num(bottom + fit.size * 0.36), "font-size": num(fit.size) }, esc(fit.lines[0])));
|
|
37
|
+
}
|
|
38
|
+
/** The words of a team with no picture, on a band across its carpet: its name, or its letters when the name would be too small to read. */
|
|
39
|
+
function bandText(team, w, bandH) {
|
|
40
|
+
const fit = fitLines(team.name, w * 0.88, bandH * 0.82, bandH * 0.6);
|
|
41
|
+
const small = fit.size < bandH * 0.22;
|
|
42
|
+
const lines = small ? [team.abbr] : fit.lines;
|
|
43
|
+
const size = small ? Math.min(bandH * 0.6, (w * 0.8) / Math.max(1, [...team.abbr].length * 0.75)) : fit.size;
|
|
44
|
+
const step = size * LINE_HEIGHT;
|
|
45
|
+
return lines.map((row, i) => el("text", { class: "ky-text ky-pg-name", x: 0, y: num((i - (lines.length - 1) / 2) * step + size * 0.36), "font-size": num(size) }, esc(row))).join("");
|
|
46
|
+
}
|
|
47
|
+
/** A carpet: the border band, then the picture at its own ratio, then the fabric. */
|
|
48
|
+
function carpet(pl, p, o, names) {
|
|
49
|
+
const { team, w, h } = pl;
|
|
50
|
+
const b = Math.min(w, h) * p.borderWidth;
|
|
51
|
+
const x = -w / 2 + b;
|
|
52
|
+
const y = -h / 2 + b;
|
|
53
|
+
const iw = w - 2 * b;
|
|
54
|
+
const ih = h - 2 * b;
|
|
55
|
+
const base = `${o.id}-pg-${pl.spot}`;
|
|
56
|
+
let defs = el("clipPath", { id: `${base}-c` }, el("rect", { x: num(x), y: num(y), width: num(iw), height: num(ih) }));
|
|
57
|
+
const borderFill = p.border === "dark" ? undefined : p.border === "team" ? team.color : p.border;
|
|
58
|
+
let inner = "";
|
|
59
|
+
const drop = Math.min(w, h) * 0.03;
|
|
60
|
+
inner += el("rect", { class: "ky-pg-shadow", x: num(-w / 2 + drop * 0.6), y: num(-h / 2 + drop), width: num(w), height: num(h), rx: num(Math.min(w, h) * 0.012) });
|
|
61
|
+
inner += el("rect", { class: "ky-pg-border", x: num(-w / 2), y: num(-h / 2), width: num(w), height: num(h), style: borderFill === undefined ? undefined : `fill:${borderFill}` });
|
|
62
|
+
let picture = "";
|
|
63
|
+
let top;
|
|
64
|
+
if (team.href !== undefined && team.fit !== "contain") {
|
|
65
|
+
if (pl.filled === true) {
|
|
66
|
+
// Made to the size of the half: the art is stretched and cropped to fit, each by the square root of how far the carpet's shape is from the flag's.
|
|
67
|
+
const shape = Math.sqrt(team.ratio * (iw / ih));
|
|
68
|
+
const wb = Math.max(iw, ih * shape);
|
|
69
|
+
picture += el("image", { class: "ky-logo ky-pg-picture", href: team.href, x: num(-wb / 2), y: num(-wb / shape / 2), width: num(wb), height: num(wb / shape), preserveAspectRatio: "none" });
|
|
70
|
+
}
|
|
71
|
+
else
|
|
72
|
+
picture += el("image", { class: "ky-logo ky-pg-picture", href: team.href, x: num(x), y: num(y), width: num(iw), height: num(ih), preserveAspectRatio: "xMidYMid slice" });
|
|
73
|
+
}
|
|
74
|
+
else if (team.href !== undefined) {
|
|
75
|
+
const pad = Math.min(iw, ih) * 0.1;
|
|
76
|
+
picture += el("rect", { class: "ky-pg-plain", x: num(x), y: num(y), width: num(iw), height: num(ih), style: colourVars(team)?.split(";")[0] });
|
|
77
|
+
picture += el("image", { class: "ky-logo ky-pg-picture", href: team.href, x: num(x + pad), y: num(y + pad), width: num(iw - 2 * pad), height: num(ih - 2 * pad), preserveAspectRatio: "xMidYMid meet" });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// No flag or logo: the team's colours as a carpet of two, with its name across a band.
|
|
81
|
+
const band = ih * 0.38;
|
|
82
|
+
picture += el("rect", { class: "ky-pg-ground", x: num(x), y: num(y), width: num(iw), height: num(ih), style: colourVars(team) });
|
|
83
|
+
picture += el("rect", { class: "ky-pg-band", x: num(x), y: num(-band / 2), width: num(iw), height: num(band), style: colourVars(team) });
|
|
84
|
+
// The name is written over the surface's lines, whichever way they lie, so that a crease or a net does not cross it.
|
|
85
|
+
if (p.names !== false)
|
|
86
|
+
top = el("g", { style: colourVars(team) }, bandText(team, iw, band));
|
|
87
|
+
}
|
|
88
|
+
inner += el("g", { "clip-path": `url(#${base}-c)` }, picture);
|
|
89
|
+
if (p.fabric && !o.simple) {
|
|
90
|
+
const f = fabric(`${base}-f`, iw, ih);
|
|
91
|
+
defs += f.defs;
|
|
92
|
+
inner += el("g", { "clip-path": `url(#${base}-c)` }, f.markup(x, y, iw, ih));
|
|
93
|
+
}
|
|
94
|
+
if (!o.simple) {
|
|
95
|
+
inner += el("rect", { class: "ky-pg-seam", x: num(x), y: num(y), width: num(iw), height: num(ih), "stroke-width": num(Math.max(Math.min(w, h) * 0.006, 0.08)) });
|
|
96
|
+
inner += el("rect", { class: "ky-pg-edge", x: num(-w / 2), y: num(-h / 2), width: num(w), height: num(h), "stroke-width": num(Math.max(Math.min(w, h) * 0.005, 0.06)) });
|
|
97
|
+
}
|
|
98
|
+
if (names && team.href !== undefined)
|
|
99
|
+
inner += pill(team, w, h, h / 2, o.simple);
|
|
100
|
+
return { markup: inner, defs, top };
|
|
101
|
+
}
|
|
102
|
+
/** A stage: the ring (gold, the team's colour or a colour of the caller's), a dark disc, and the crest in a circle on it. */
|
|
103
|
+
function stage(pl, p, o, names) {
|
|
104
|
+
const { team } = pl;
|
|
105
|
+
const R = pl.r ?? pl.w / 2;
|
|
106
|
+
const base = `${o.id}-pg-${pl.spot}`;
|
|
107
|
+
let defs = "";
|
|
108
|
+
let ringFill;
|
|
109
|
+
if (p.ring === "gold") {
|
|
110
|
+
defs += gradient(`${base}-g`, -R, -R, R, R, GOLD.map(([offset, colour]) => [offset, colour]));
|
|
111
|
+
ringFill = `url(#${base}-g)`;
|
|
112
|
+
}
|
|
113
|
+
else
|
|
114
|
+
ringFill = p.ring === "team" ? (team.color ?? "#c9a24a") : p.ring;
|
|
115
|
+
let inner = "";
|
|
116
|
+
inner += el("circle", { class: "ky-pg-shadow", cx: num(R * 0.03), cy: num(R * 0.06), r: num(R) });
|
|
117
|
+
inner += el("circle", { class: "ky-pg-ringband", cx: 0, cy: 0, r: num(R), fill: ringFill });
|
|
118
|
+
if (!o.simple)
|
|
119
|
+
inner += el("circle", { class: "ky-pg-groove", cx: 0, cy: 0, r: num(R * 0.925), "stroke-width": num(Math.max(R * 0.012, 0.06)) });
|
|
120
|
+
inner += el("circle", { class: "ky-pg-disc", cx: 0, cy: 0, r: num(R * 0.9) });
|
|
121
|
+
inner += roundMarkup({ id: base, cx: 0, cy: 0, r: R * 0.8, href: team.href, fit: team.fit, initials: team.abbr, color: team.color, ink: team.ink, ring: Math.max(R * 0.025, 0.08) });
|
|
122
|
+
if (!o.simple)
|
|
123
|
+
inner += el("circle", { class: "ky-pg-edge", cx: 0, cy: 0, r: num(R), "stroke-width": num(Math.max(R * 0.006, 0.05)) });
|
|
124
|
+
if (names)
|
|
125
|
+
inner += pill(team, 2 * R, 2 * R, R * 0.98, o.simple);
|
|
126
|
+
return { markup: inner, defs };
|
|
127
|
+
}
|
|
128
|
+
/** The motion classes of a picture: its entrance, and the way a carpet rolls out. */
|
|
129
|
+
const motion = (p, kind, tall) => (p.animate === "none" ? "" : ` ky-pg-${p.animate}${kind === "carpet" && tall ? " ky-pg-tall" : ""}`);
|
|
130
|
+
/** The pictures of a pageant: each team's carpet or stage, drawn in its place. Under the surface's lines (`lines: "over"`) or over them (`"under"`). */
|
|
131
|
+
export function picturesMarkup(layout, p, o) {
|
|
132
|
+
let markup = "";
|
|
133
|
+
let defs = "";
|
|
134
|
+
let tops = "";
|
|
135
|
+
for (const placed of layout.pictures) {
|
|
136
|
+
const { team } = placed;
|
|
137
|
+
// Only a team with no flag or logo has its name on its picture, unless the options ask for names.
|
|
138
|
+
const names = p.names ?? false;
|
|
139
|
+
const made = p.style === "stage" ? stage(placed, p, o, names) : carpet(placed, p, o, names);
|
|
140
|
+
defs += made.defs;
|
|
141
|
+
const classes = `ky-pg ky-pg-${p.style} ky-pg-${placed.spot}${motion(p, p.style, o.turned)}`;
|
|
142
|
+
markup += standing(placed.cx, placed.cy, o.turned, classes, made.markup, o, `pageant ${team.role}`, team.name, { "data-team": team.role, "data-state": team.state });
|
|
143
|
+
if (made.top !== undefined)
|
|
144
|
+
tops += standing(placed.cx, placed.cy, o.turned, `ky-pg ky-pg-words ky-pg-${placed.spot}${motion(p, p.style, o.turned)}`, made.top, o, undefined, undefined, { "data-team": team.role });
|
|
145
|
+
}
|
|
146
|
+
return { markup: `<g class="ky-pageant"${p.lines === "through" ? ' opacity=".9"' : ""}>${markup}</g>`, defs, names: tops };
|
|
147
|
+
}
|
|
148
|
+
/** The emblem: a competition's picture or a trophy on a disc with a ring in the centre circle, or as it is for a cut-out. */
|
|
149
|
+
export function emblemMarkup(layout, p, o) {
|
|
150
|
+
const place = layout.emblem;
|
|
151
|
+
const emblem = p.emblem;
|
|
152
|
+
if (place === undefined || emblem === undefined)
|
|
153
|
+
return { markup: "", defs: "" };
|
|
154
|
+
const R = place.r;
|
|
155
|
+
const base = `${o.id}-pg-emblem`;
|
|
156
|
+
let defs = "";
|
|
157
|
+
let inner;
|
|
158
|
+
if (emblem.shape === "plain") {
|
|
159
|
+
inner = el("ellipse", { class: "ky-pg-shadow", cx: 0, cy: num(R * 0.78), rx: num(R * 0.62), ry: num(R * 0.13) }) + el("image", { class: "ky-logo ky-pg-emblem-image", href: emblem.href, x: num(-R * 1.05), y: num(-R * 1.05), width: num(R * 2.1), height: num(R * 2.1), preserveAspectRatio: "xMidYMid meet" });
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
defs += gradient(`${base}-g`, -R, -R, R, R, GOLD.map(([offset, colour]) => [offset, colour]));
|
|
163
|
+
inner = el("circle", { class: "ky-pg-shadow", cx: num(R * 0.03), cy: num(R * 0.06), r: num(R) });
|
|
164
|
+
inner += el("circle", { class: "ky-pg-ringband", cx: 0, cy: 0, r: num(R), fill: `url(#${base}-g)` });
|
|
165
|
+
inner += el("circle", { class: "ky-pg-light", cx: 0, cy: 0, r: num(R * 0.9) });
|
|
166
|
+
inner += roundMarkup({ id: base, cx: 0, cy: 0, r: R * 0.82, href: emblem.href, fit: emblem.fit, ring: Math.max(R * 0.02, 0.06) });
|
|
167
|
+
if (!o.simple)
|
|
168
|
+
inner += el("circle", { class: "ky-pg-edge", cx: 0, cy: 0, r: num(R), "stroke-width": num(Math.max(R * 0.006, 0.05)) });
|
|
169
|
+
}
|
|
170
|
+
return { markup: standing(place.cx, place.cy, o.turned, `ky-pg ky-pg-emblem${p.animate === "none" ? "" : ` ky-pg-${p.animate}`}`, inner, o, "emblem", emblem.name), defs };
|
|
171
|
+
}
|