@johnmorrisdotca/dougu-sports 0.7.2 → 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 +44 -0
- package/NOTICE.md +1 -1
- package/README.md +58 -28
- package/dist/emblems/ball/ball.baseball.js +2 -1
- package/dist/emblems/ball/ball.contrast.d.ts +4 -0
- package/dist/emblems/ball/ball.contrast.js +22 -0
- package/dist/emblems/ball/ball.core.d.ts +42 -0
- package/dist/emblems/ball/ball.core.js +34 -1
- package/dist/emblems/ball/ball.engine.d.ts +70 -4
- package/dist/emblems/ball/ball.engine.js +70 -20
- package/dist/emblems/ball/ball.family.seamed.d.ts +4 -0
- package/dist/emblems/ball/ball.family.seamed.js +42 -7
- package/dist/emblems/ball/ball.image.d.ts +8 -0
- package/dist/emblems/ball/ball.image.js +14 -5
- package/dist/emblems/ball/ball.index.js +2 -4
- package/dist/emblems/ball/ball.letters.d.ts +3 -0
- package/dist/emblems/ball/ball.letters.js +51 -0
- package/dist/emblems/ball/ball.print.d.ts +81 -0
- package/dist/emblems/ball/ball.print.js +268 -0
- package/dist/emblems/ball/ball.printable.d.ts +6 -0
- package/dist/emblems/ball/ball.printable.js +13 -0
- package/dist/emblems/ball/ball.region.d.ts +12 -0
- package/dist/emblems/ball/ball.region.js +94 -0
- package/dist/emblems/ball/ball.script.d.ts +15 -0
- package/dist/emblems/ball/ball.script.js +107 -0
- package/dist/emblems/ball/ball.soccer.js +7 -3
- package/dist/emblems/ball/ball.soccer.panels.d.ts +2 -0
- package/dist/emblems/ball/ball.soccer.panels.js +6 -3
- package/dist/emblems/ball/ball.soccer.size.d.ts +2 -0
- package/dist/emblems/ball/ball.soccer.size.js +8 -0
- package/dist/emblems/ball/ball.softball.js +2 -1
- package/dist/emblems/ball/ball.warp.d.ts +48 -0
- package/dist/emblems/ball/ball.warp.js +441 -0
- package/dist/emblems/emblem.core.d.ts +13 -0
- package/dist/emblems-entry.d.ts +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -5
- package/dist/turn-control.d.ts +24 -5
- package/dist/turn-control.js +67 -23
- package/dist/turn-full.d.ts +15 -0
- package/dist/turn-full.js +19 -0
- package/dist/turn-registry.d.ts +1 -0
- package/dist/turn-registry.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,50 @@ All notable changes to this project are written here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.0] - 2026-10-15
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Custom balls.** The baseball, the softball and the classic soccer balls (`ball:baseball`, `ball:softball`, `ball:soccer`, `ball:soccer-orange`, `ball:soccer-yellow` and `ball:soccer-colour`) take six options, drawn on the sphere so that they curve with it, are foreshortened toward the edge, go round the limb and turn with the ball (`renderEmblem`, `emblemFrame`, `ballFrame` and `bindTurn` take them):
|
|
14
|
+
- `paint`: a colour, or `{ body, second, split, angle, stitch }`. A solid ball takes the colour, and the stitches change to a thread that shows against it (red, cream, navy or near-black). Two colours make a two-tone ball, split along the figure-eight seam (each leather piece one colour, each stitch leg the thread that shows on its own side) or in halves. On a soccer ball `body` is the hexagons and `second` the pentagons.
|
|
15
|
+
- `decal`: a logo of your own as an SVG string, a `data:` image URI or `{ svg, href, size, turn }`. An SVG is flattened and wrapped exactly (fills cut at the limb, strokes thinning as they turn away); a PNG, JPEG, GIF or WebP is laid on in small affine triangles. Made safe with an allow-list; an address on the network is refused.
|
|
16
|
+
- `stamp`: bold condensed block lettering between small stars (`UNOFFICIAL` over `DIGITAL BASEBALL` by default, the ball's own word on each ball), your own lines, ink and an optional made-up signature line with a caption.
|
|
17
|
+
- `script`: an original cursive script (waypoints drawn for this package, a thick down stroke and a hairline up stroke, a to z and our own `Baseball` and `Soccer`), where a maker's mark sits; with a small circled letter under it, or your own mark.
|
|
18
|
+
- `mark`: a letter in a circle, or an SVG of your own drawn in its place (the slot for a mark this package must not carry).
|
|
19
|
+
- `spots`: where the logo and the lettering go. The logo has the middle and the lettering the far side by default.
|
|
20
|
+
- **`printed(ball)`** (main entry) and the types `BallPaint`, `BallDecal`, `BallStamp`, `BallScript`, `BallMark`, `BallSpots` and `Spot`. The balls' own modules carry no printing code and ignore the options; the registry, `renderEmblem` and the main entry's constants are the printed ones, and `printed(BALL_BASEBALL)` gives a ball taken from its own module the printing (about 19 kB gzipped, against 8.6 kB for the plain baseball).
|
|
21
|
+
- **`docs/custom-balls.md`** and its Japanese page, the gallery's note about the options, and a "Custom ball" section in the demo: colour, two-tone, stamp lines, script word, mark and a logo picked from a file (read in the browser into a data URI), with the call that draws it.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- The ball engine can fill the disc of a ball and a region of it, and a ball's draw hook takes its paint and print options. A plain soccer ball bundled alone is 7.3 kB gzipped (was 6.5), so the size test's limit for a ball is 7.6 kB.
|
|
26
|
+
|
|
27
|
+
## [0.8.0] - 2026-10-14
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **`bindTurn` takes an emblem object and is light.** `bindTurn(element, TROPHY_HOCKEY_CUP, options)` draws and turns the emblem it is given with its own `frame` and imports neither a drawing nor the registry, so a bundle of `bindTurn` and one cup is about 9.4 kB gzipped (the turning is about 2.5 kB of it), where it was about 81 kB. `test/size.test.ts` holds it to 10 kB, and the other emblems stay tree-shakeable.
|
|
32
|
+
- **`ready`** on the controller `bindTurn` returns: a promise that resolves when the emblem is drawn and bound (already, for an emblem object) and rejects for an id that names nothing.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **`bindTurn` of `./turn` loads the registry only for an id.** An id (`"trophy:tennis-cup"`) is read from the registry, which `bindTurn` now imports on demand (a dynamic import, a chunk of its own in a bundler) instead of at the top. The first id bound is drawn when `ready` resolves, not before; later ones at once. `bindTurn` of the main entry (`@johnmorrisdotca/dougu-sports`) has the registry already and draws an id at once, as before. New modules: `src/turn-registry.ts` (what is loaded) and `src/turn-full.ts` (the main entry's `bindTurn`).
|
|
37
|
+
|
|
38
|
+
## [0.7.3] - 2026-10-14
|
|
39
|
+
|
|
40
|
+
The repository's own tooling is TypeScript. No change to the package: the same files are published, and the pictures are byte for byte the same.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- **The scripts, the browser tests, the test helpers and the demo's source are `.ts`.** `scripts/*.ts` (build, gallery, package check, README examples, release notes, contact sheets, the pictures script, the demo's server and page maker), `e2e/*.demo.ts`, `playwright.config.ts` and `test/pieces-gallery.test.ts` were `.mjs` or `.js`. They run with Node's own type stripping, with no `tsx` and no build step, so `package.json`'s scripts call the `.ts` files directly. The shared family files stay as they are, byte for byte: `scripts/family-template.mjs` and `scripts/family-readme.mjs` (plain JavaScript, with the types of the template written by hand in `scripts/family-template.d.mts`) and `scripts/family-backgrounds.ts`.
|
|
45
|
+
- **`pnpm typecheck` checks all of it.** `tsconfig.check.json` covers `src` and `test`, the new `tsconfig.tools.json` covers `scripts`, `e2e` and the Playwright config (with the browser's types, since the tests and the pictures script run code in the page), and the new `tsconfig.demo.json` covers `demo`. The syntax is the erasable kind only (`erasableSyntaxOnly` was already on), with `import type` and `.ts` extensions.
|
|
46
|
+
- **The demo's scripts are `demo/*.ts`, built with esbuild.** A browser cannot run TypeScript, so `scripts/page.ts` builds each one into `demo.js`, `compose.js` and `gallery.js` for the dev server (on each request) and for `pnpm site`. A script imports the package from `../src/index.ts`, so that it is type-checked against the real source; the build changes that one import to `./dist/index.js`, the built package, as before. The page is the same.
|
|
47
|
+
- **Node.** Working on the repository needs Node 22.18 or later (where type stripping is on by default); CI already runs 22 and 24. `engines` stays `>=22`, because the published package is plain JavaScript and needs no more. `CONTRIBUTING.md` says so.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- **The belts note counted the two-colour pairs wrong.** `docs/japanese-sports.md` and `docs/japanese-sports.ja.md` said the IJF names "these four pairs" under a table of five. The IJF's page names four (white-yellow, yellow-orange, orange-green, green-blue); blue-brown is drawn for completeness and no source found names it. Both pages now say that.
|
|
52
|
+
|
|
9
53
|
## [0.7.2] - 2026-10-14
|
|
10
54
|
|
|
11
55
|
The docs are one language to a page. No change to the pictures; the only change to the package is one English description.
|
package/NOTICE.md
CHANGED
|
@@ -72,4 +72,4 @@ Facts only: a dimension or a mass is a fact, not a work. The NHL's puck rule was
|
|
|
72
72
|
| What | Made from | Terms |
|
|
73
73
|
| --- | --- | --- |
|
|
74
74
|
| The demo's page | Written for this package, with the family stylesheet `demo/family.css` | MIT |
|
|
75
|
-
| The README's pictures (`docs/images`) | Taken by `scripts/screenshots.
|
|
75
|
+
| The README's pictures (`docs/images`) | Taken by `scripts/screenshots.ts` from the demo, which draws the package's own emblems | MIT |
|
package/README.md
CHANGED
|
@@ -85,6 +85,7 @@ Put the string in a page (`element.innerHTML = svg`), write it to a file, or sen
|
|
|
85
85
|
- **Size, tint, accent and theme** as options: a tint recolours the main part (a medal's metal, a crest's colour, a ball's patches), an accent the second colour (a ribbon, a crest's band, the pennants), a theme sets the ink for light, dark or either.
|
|
86
86
|
- **Turning**: `emblemFrame` and `ballFrame` return the emblem at an angle, in plain SVG: every emblem turns, a ball rolls, a cup keeps its outline and moves its light, and everything flat (gear, a bat, a crown, a sport's icon) flips like a coin; `bindTurn` lets a drag, the arrow keys or an auto-turn do the turning in a page; see [docs/turning.md](./docs/turning.md).
|
|
87
87
|
- **Engraving**: text cut into a medal, a plaque, the belt, a ring, a banner, a pennant and the plinth of a cup, from `label`, `year` and `rank` or one `engrave` string, in the ink that reads at 4.5 to 1 on the metal, and it turns with the emblem; see [Engrave an emblem](#engrave-an-emblem).
|
|
88
|
+
- **Custom balls**: a baseball, a softball and the classic soccer balls take `paint` (a solid colour, or two: along the seam or in halves, with stitches that still show), `decal` (your own SVG or image as a logo, wrapped onto the sphere so that it turns with the ball), `stamp` (condensed bold text between small stars, with an optional made-up signature), `script` (an original cursive word) and `mark` (a letter in a circle, or an SVG of your own); see [docs/custom-balls.md](./docs/custom-balls.md). The package carries no logo of anyone's: a logo or a mark is the one you pass.
|
|
88
89
|
- **Labels in two languages**: the `<title>` is English or Japanese (`locale`), your own words (`title: "…"`), or left out for an emblem that sits beside text that says the same (`title: false`).
|
|
89
90
|
- **As an image, a sprite, a podium or a case**: `emblemDataUri` for an `<img>`, a CSS background or a canvas, `emblemSprite` to draw one emblem fifty times cheaply, `sportEquipment` for what a sport is played with, and `podium` and `awardCase` for results and trophy shelves; see [docs/compose.md](./docs/compose.md).
|
|
90
91
|
- **One module per item**, so a bundler takes only what is imported; see [Use it in your project](#use-it-in-your-project).
|
|
@@ -137,7 +138,7 @@ The alias is a name in your `package.json` only: the same package, the same code
|
|
|
137
138
|
| --- | --- |
|
|
138
139
|
| `@johnmorrisdotca/dougu-sports` | The full registry: every emblem by id, the functions, and each emblem as a constant |
|
|
139
140
|
| `@johnmorrisdotca/dougu-sports/emblems` | `renderEmblem`, the ids and the types, with no single drawing imported by name |
|
|
140
|
-
| `@johnmorrisdotca/dougu-sports/turn` | `emblemFrame`, `ballFrame` and `bindTurn` |
|
|
141
|
+
| `@johnmorrisdotca/dougu-sports/turn` | `emblemFrame`, `ballFrame` and `bindTurn`; `bindTurn` with an emblem object takes nothing else with it |
|
|
141
142
|
| `@johnmorrisdotca/dougu-sports/<group>/<name>` | One emblem, alone: `trophy/hockey-cup`, `medal/gold`, `crest/shield`, `sport/nhl`, `award/crown`, `ball/soccer`, `pennant/championship`, `gear/<name>` |
|
|
142
143
|
|
|
143
144
|
### One emblem and nothing else
|
|
@@ -149,7 +150,7 @@ console.log(TROPHY_HOCKEY_CUP.id); // trophy:hockey-cup
|
|
|
149
150
|
console.log(TROPHY_HOCKEY_CUP.svg({ size: 24 }).includes('width="24"')); // true
|
|
150
151
|
```
|
|
151
152
|
|
|
152
|
-
A bundler that imports this module takes the cup and the renderer for a body of revolution, and no other emblem: the package says `"sideEffects": false` and each constant is marked pure. `test/size.test.ts` bundles one item with esbuild and holds it to a limit for its kind (a ball 6
|
|
153
|
+
A bundler that imports this module takes the cup and the renderer for a body of revolution, and no other emblem: the package says `"sideEffects": false` and each constant is marked pure. `test/size.test.ts` bundles one item with esbuild and holds it to a limit for its kind (a ball 7.6 kB, a medal or a crest 4.6 kB, a cup 7.1 kB gzipped, most of that the renderer); `pnpm test:package` does the same from the packed tarball.
|
|
153
154
|
|
|
154
155
|
### In a page
|
|
155
156
|
|
|
@@ -379,12 +380,13 @@ Both are one SVG string in the page's text colour, with a title and a descriptio
|
|
|
379
380
|
|
|
380
381
|
```js no-run
|
|
381
382
|
import { bindTurn } from "@johnmorrisdotca/dougu-sports/turn";
|
|
383
|
+
import { TROPHY_TENNIS_CUP } from "@johnmorrisdotca/dougu-sports/trophy/tennis-cup";
|
|
382
384
|
|
|
383
|
-
const turner = bindTurn(document.getElementById("cup"),
|
|
385
|
+
const turner = bindTurn(document.getElementById("cup"), TROPHY_TENNIS_CUP, { size: 160, speed: 36 });
|
|
384
386
|
document.getElementById("spin").onclick = () => turner.togglePlay();
|
|
385
387
|
```
|
|
386
388
|
|
|
387
|
-
A drag turns it, the arrow keys turn it, Space starts and stops an auto-turn, and nothing moves until you ask;
|
|
389
|
+
A drag turns it, the arrow keys turn it, Space starts and stops an auto-turn, and nothing moves until you ask. Pass the emblem itself and the page carries the turning and that one emblem and nothing else (a cup and the turning are about 9 kB gzipped); pass an id, `"trophy:tennis-cup"`, and the registry is loaded when it is needed. See [docs/turning.md](./docs/turning.md).
|
|
388
390
|
|
|
389
391
|
### In React, Vue and the rest
|
|
390
392
|
|
|
@@ -434,7 +436,7 @@ The thirty-eight sports the ball, gear and sport emblems are made for are `SPORT
|
|
|
434
436
|
| `sportIcon(sport, options?)` | The pictogram of a sport, by the names of `SPORT_NAMES`; an unknown sport is an error |
|
|
435
437
|
| `lineup(ids, options?)` | Several balls side by side, at their true relative sizes (or all as large as the largest) |
|
|
436
438
|
| `emblemFrame(ref, options?)` | An emblem turned by `yaw` and `pitch` degrees (and `roll` for a ball) |
|
|
437
|
-
| `bindTurn(element, ref, options?)` | Draws an emblem into an element and lets a drag, the arrow keys, Space or a clock turn it; returns a controller with `angles`, `playing`, `turnable`, `setAngles`, `update`, `play`, `pause`, `togglePlay` and `destroy` |
|
|
439
|
+
| `bindTurn(element, ref, options?)` | Draws an emblem (the emblem itself, or its id) into an element and lets a drag, the arrow keys, Space or a clock turn it; returns a controller with `angles`, `playing`, `turnable`, `ready`, `setAngles`, `update`, `play`, `pause`, `togglePlay` and `destroy` |
|
|
438
440
|
| `emblemDataUri(ref, options?)` | An emblem as a `data:image/svg+xml;utf8,…` address for an `<img>`, a CSS background or a canvas, with the ink made a colour (`color`, or the theme's) |
|
|
439
441
|
| `emblemSprite(ids, options?)` | A hidden sheet of `<symbol>`s with unique ids, and `use(id, { size, class, title })` for the markup of each use |
|
|
440
442
|
| `sportEquipment(sport)` | The ball, gear, trophy and medal of a sport, as ids of the registry |
|
|
@@ -550,39 +552,67 @@ Every emblem is drawn for this package, and nothing is copied from another proje
|
|
|
550
552
|
### The family
|
|
551
553
|
|
|
552
554
|
<!-- family:start (made by scripts/family-readme.mjs from scripts/family-template.mjs; change those, not this) -->
|
|
553
|
-
Dougu Sports is one of
|
|
554
|
-
[github.com/johnmorrisdotca](https://github.com/johnmorrisdotca). The code of every one is MIT.
|
|
555
|
+
Dougu Sports is one of thirty-two packages, each made for the same site, each at
|
|
556
|
+
[github.com/johnmorrisdotca](https://github.com/johnmorrisdotca) or [github.com/spxis](https://github.com/spxis). The code of every one is MIT.
|
|
555
557
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
- [
|
|
559
|
-
- [
|
|
560
|
-
- [Tane](https://github.com/johnmorrisdotca/tane) (種): seeded random numbers and daily seeds, the same in every browser and on every server. [Demo](https://johnmorrisdotca.github.io/tane/).
|
|
558
|
+
**Games — board**
|
|
559
|
+
|
|
560
|
+
- [Domino](https://github.com/johnmorrisdotca/domino) (ドミノ): dominoes and Mexican Train. [Demo](https://johnmorrisdotca.github.io/domino/).
|
|
561
|
+
- [Gunjin](https://github.com/johnmorrisdotca/gunjin) (軍人): five hidden-rank strategy games with pass-the-device play. [Demo](https://johnmorrisdotca.github.io/gunjin/).
|
|
561
562
|
- [Narabe](https://github.com/johnmorrisdotca/narabe) (並べ): one rules engine for abstract board games, from gomoku and Reversi to Go and checkers. [Demo](https://johnmorrisdotca.github.io/narabe/).
|
|
563
|
+
- [Sugoroku](https://github.com/johnmorrisdotca/sugoroku) (双六): backgammon and its variants, with the doubling cube and match play. [Demo](https://johnmorrisdotca.github.io/sugoroku/).
|
|
562
564
|
- [Tenka](https://github.com/johnmorrisdotca/tenka) (天下): world conquest for two to six, on a map of the real world. [Demo](https://johnmorrisdotca.github.io/tenka/).
|
|
563
|
-
|
|
564
|
-
|
|
565
|
+
|
|
566
|
+
**Games — cards & tiles**
|
|
567
|
+
|
|
568
|
+
- [Hitotsu](https://github.com/johnmorrisdotca/hitotsu) (一つ): a colour-card shedding game for two to eight, with the house rules people play. [Demo](https://johnmorrisdotca.github.io/hitotsu/).
|
|
565
569
|
- [Jarajara](https://github.com/johnmorrisdotca/jarajara) (ジャラジャラ): mahjong tiles drawn as SVG, stacked layouts, and the matching solitaire Awase. [Demo](https://johnmorrisdotca.github.io/jarajara/).
|
|
566
|
-
- [
|
|
567
|
-
- [
|
|
568
|
-
|
|
569
|
-
|
|
570
|
+
- [Kumimoji](https://github.com/johnmorrisdotca/kumimoji) (組み文字): a crossword tile race, in English and Japanese kana. [Demo](https://johnmorrisdotca.github.io/kumimoji/).
|
|
571
|
+
- [Toranpu](https://github.com/johnmorrisdotca/toranpu) (トランプ): a deck of playing cards, card games with computer players, and solitaires. [Demo](https://johnmorrisdotca.github.io/toranpu/).
|
|
572
|
+
|
|
573
|
+
**Games — puzzles**
|
|
574
|
+
|
|
575
|
+
- [Houseki](https://github.com/johnmorrisdotca/houseki) (宝石): gem and stone matching puzzles: falling triplets, stone collapse, colour chains and gem swap. [Demo](https://johnmorrisdotca.github.io/houseki/).
|
|
576
|
+
- [Jirai](https://github.com/johnmorrisdotca/jirai) (地雷): minesweeper on shaped grids with verified no-guess boards. [Demo](https://johnmorrisdotca.github.io/jirai/).
|
|
577
|
+
- [Karakuri](https://github.com/johnmorrisdotca/karakuri) (からくり): eight hyper-casual puzzle games, some of them physics: draw a shield, pull pins, cut ropes, slide blocks, pour tubes. [Demo](https://johnmorrisdotca.github.io/karakuri/).
|
|
570
578
|
- [Kazu](https://github.com/johnmorrisdotca/kazu) (数): grid number puzzles: Sudoku and its variants, Futoshiki and Skyscrapers. [Demo](https://johnmorrisdotca.github.io/kazu/).
|
|
579
|
+
- [Kyuubu](https://github.com/johnmorrisdotca/kyuubu) (キューブ): a turning cube for the browser, 2×2 to 7×7, with record solves to replay. [Demo](https://johnmorrisdotca.github.io/kyuubu/).
|
|
571
580
|
- [Meikyuu](https://github.com/johnmorrisdotca/meikyuu) (迷宮): mazes on squares, hexagons, triangles and circles, made from a seed and drawn through with a finger or the mouse. [Demo](https://johnmorrisdotca.github.io/meikyuu/).
|
|
581
|
+
- [Suido](https://github.com/johnmorrisdotca/suido) (水道): a pipe puzzle: turn the pieces until the water reaches every drain. [Demo](https://johnmorrisdotca.github.io/suido/).
|
|
582
|
+
- [Tobiishi](https://github.com/johnmorrisdotca/tobiishi) (飛び石): peg solitaire with nine boards and seeded solvable challenges. [Demo](https://johnmorrisdotca.github.io/tobiishi/).
|
|
583
|
+
- [Tsunagi](https://github.com/johnmorrisdotca/tsunagi) (繋ぎ): a line-joining logic puzzle whose every level has exactly one answer. [Demo](https://johnmorrisdotca.github.io/tsunagi/).
|
|
584
|
+
|
|
585
|
+
**Games — dice & random**
|
|
586
|
+
|
|
587
|
+
- [Korokoro](https://github.com/johnmorrisdotca/korokoro) (コロコロ): dice, with notation, exact odds, real sounds and the dice of many games. [Demo](https://johnmorrisdotca.github.io/korokoro/).
|
|
588
|
+
- [Tane](https://github.com/johnmorrisdotca/tane) (種): seeded random numbers and daily seeds, the same in every browser and on every server. [Demo](https://johnmorrisdotca.github.io/tane/).
|
|
589
|
+
|
|
590
|
+
**Language**
|
|
591
|
+
|
|
592
|
+
- [Bushu](https://github.com/johnmorrisdotca/bushu) (部首): find a kanji by the parts it is made of. [Demo](https://johnmorrisdotca.github.io/bushu/).
|
|
572
593
|
- [Hikidashi](https://github.com/johnmorrisdotca/hikidashi) (引き出し): a drawer of small Japanese text tools: era dates, kanji numerals, readings and sentence difficulty. [Demo](https://johnmorrisdotca.github.io/hikidashi/).
|
|
594
|
+
- [Kotoba](https://github.com/johnmorrisdotca/kotoba) (言葉): word lists and word-game rules in English, French, German and Japanese. [Demo](https://johnmorrisdotca.github.io/kotoba/).
|
|
595
|
+
|
|
596
|
+
**Geography & data**
|
|
597
|
+
|
|
598
|
+
- [address-plus](https://github.com/johnmorrisdotca/address-plus) (アドレスプラス): parse and format addresses in the United States, Canada, Japan, Australia, France, Germany and the United Kingdom. [Demo](https://johnmorrisdotca.github.io/address-plus/).
|
|
573
599
|
- [Chizu](https://github.com/johnmorrisdotca/chizu) (地図): maps of the world and of countries' regions, in English and Japanese, with a quiz and callouts. [Demo](https://johnmorrisdotca.github.io/chizu/).
|
|
574
|
-
- [
|
|
575
|
-
- [
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
- [Houseki](https://github.com/johnmorrisdotca/houseki) (宝石): gem and stone matching puzzles: falling triplets, stone collapse, colour chains and gem swap. [Demo](https://johnmorrisdotca.github.io/houseki/).
|
|
580
|
-
- [Kyogijo Stadiums](https://github.com/johnmorrisdotca/kyogijo-stadiums) (競技場): sports fields, rinks, courts and ballparks drawn to scale as SVG, with each team and the score on them. [Demo](https://johnmorrisdotca.github.io/kyogijo-stadiums/).
|
|
581
|
-
- [Taisen Brackets](https://github.com/johnmorrisdotca/taisen-brackets) (対戦): a sport-agnostic tournament bracket, drawn as SVG, from a list of ties. [Demo](https://johnmorrisdotca.github.io/taisen-brackets/).
|
|
600
|
+
- [Hata](https://github.com/johnmorrisdotca/hata) (旗): country and regional flags as SVG, at their true proportions and keyed by ISO code. [Demo](https://johnmorrisdotca.github.io/hata/).
|
|
601
|
+
- [Kuni](https://github.com/johnmorrisdotca/kuni) (国): countries and their regions, with ISO codes and names in English and Japanese. [Demo](https://johnmorrisdotca.github.io/kuni/).
|
|
602
|
+
|
|
603
|
+
**Sports**
|
|
604
|
+
|
|
582
605
|
- [Dougu Sports](https://github.com/johnmorrisdotca/dougu-sports) (道具): sports emblems as SVG: trophies, medals, crests, and the ball and gear of every sport, with optional 3D turning. [Demo](https://johnmorrisdotca.github.io/dougu-sports/).
|
|
606
|
+
- [Kyogijo Stadiums](https://github.com/johnmorrisdotca/kyogijo-stadiums) (競技場): sports fields, rinks, courts and ballparks drawn to scale as SVG, with each team and the score on them. [Demo](https://johnmorrisdotca.github.io/kyogijo-stadiums/).
|
|
583
607
|
- [Senshu Jerseys](https://github.com/johnmorrisdotca/senshu-jerseys) (選手): sports jerseys, sweaters, kits, caps, helmets and retired-number banners as SVG, front and back, with optional 2.5D turning. [Demo](https://johnmorrisdotca.github.io/senshu-jerseys/).
|
|
608
|
+
- [Taisen Brackets](https://github.com/johnmorrisdotca/taisen-brackets) (対戦): a sport-agnostic tournament bracket, drawn as SVG, from a list of ties. [Demo](https://johnmorrisdotca.github.io/taisen-brackets/).
|
|
609
|
+
|
|
610
|
+
**Developer tools**
|
|
611
|
+
|
|
612
|
+
- [REST in Pieces](https://github.com/spxis/rest-in-pieces) (レスト・イン・ピーシーズ): seeded test data and REST APIs for frontend development, with latency and error drills. [Demo](https://spxis.github.io/rest-in-pieces/).
|
|
613
|
+
|
|
584
614
|
|
|
585
|
-
**This package is Dougu Sports.** The demos of all
|
|
615
|
+
**This package is Dougu Sports.** The demos of all thirty-two share one header and footer, so each links the rest.
|
|
586
616
|
<!-- family:end -->
|
|
587
617
|
|
|
588
618
|
## Development
|
|
@@ -604,7 +634,7 @@ Bug reports and ideas go in the [issues](https://github.com/johnmorrisdotca/doug
|
|
|
604
634
|
|
|
605
635
|
## Changes
|
|
606
636
|
|
|
607
|
-
See [CHANGELOG.md](./CHANGELOG.md). 0.7.2 makes every docs page single-language (a page in Japanese beside each page that had Japanese words in it, and a test that holds them apart), with no change to the pictures; 0.7.1 puts real countries (Canada, Japan) in the crest and puck examples in place of made-up teams, with no change to the code; 0.7.0 gives the national volleyballs layouts that tell them apart (Japan a crimson band, Poland white above and red below, the USA a navy field), strengthens the 2010-style grooved soccer ball, and adds six pictures of how the judo belt is tied, `gear:obi-step-1` to `gear:obi-step-6` (269 emblems: [docs/obi-steps.md](./docs/obi-steps.md)); 0.6.0 gives the judo suit and the karate suit their sleeves (a judogi has no short ones: they reach the wrist) and adds the judogi seen from behind with the IJF-style back number, a family name and a country code on a patch, with a `backnumber` option (269 emblems: [docs/judogi-back.md](./docs/judogi-back.md)); 0.5.1 redraws the judo suit, the belt and the football pictograms and adds the blue and folded suits and the belts of every grade (261 emblems: [docs/japanese-sports.md](./docs/japanese-sports.md)); 0.5.0 adds fifty balls: vintage leather soccer balls, era-style and shop-wall soccer balls, baseballs of other threads and volleyballs in national colours, with a `colors` option (244 emblems: [docs/vintage-balls.md](./docs/vintage-balls.md)); 0.4.0 adds eight printed pucks and a `face` option (194 emblems: [docs/pucks.md](./docs/pucks.md)); 0.3.0 adds nineteen soccer balls (26, 18, 14, 12 and 6 panels, winter orange and high-visibility yellow, futsal and beach soccer: 186 emblems); 0.2.1 draws every ball and implement to the rulebook's proportions; 0.2.0 is 167 emblems, every one drawn here, with the Japanese sports, engraving, a turn for every emblem and the compose helpers; 0.1.0 brought the first full set of 148; 0.0.1 was the first preview.
|
|
637
|
+
See [CHANGELOG.md](./CHANGELOG.md). 0.9.0 lets the baseball, the softball and the classic soccer balls be painted and printed: solid and two-tone colours, a logo of your own wrapped onto the ball, stamped text, an original cursive word and a small mark, all turning with the ball ([docs/custom-balls.md](./docs/custom-balls.md)); 0.8.0 makes `bindTurn` light: it takes an emblem object and then needs no registry, so a turnable cup is about 9.4 kB gzipped instead of about 81 kB, and an id loads the registry on demand; 0.7.3 turns the build, docs and picture scripts, the browser tests and the demo's source from JavaScript into TypeScript, with no change to the package; 0.7.2 makes every docs page single-language (a page in Japanese beside each page that had Japanese words in it, and a test that holds them apart), with no change to the pictures; 0.7.1 puts real countries (Canada, Japan) in the crest and puck examples in place of made-up teams, with no change to the code; 0.7.0 gives the national volleyballs layouts that tell them apart (Japan a crimson band, Poland white above and red below, the USA a navy field), strengthens the 2010-style grooved soccer ball, and adds six pictures of how the judo belt is tied, `gear:obi-step-1` to `gear:obi-step-6` (269 emblems: [docs/obi-steps.md](./docs/obi-steps.md)); 0.6.0 gives the judo suit and the karate suit their sleeves (a judogi has no short ones: they reach the wrist) and adds the judogi seen from behind with the IJF-style back number, a family name and a country code on a patch, with a `backnumber` option (269 emblems: [docs/judogi-back.md](./docs/judogi-back.md)); 0.5.1 redraws the judo suit, the belt and the football pictograms and adds the blue and folded suits and the belts of every grade (261 emblems: [docs/japanese-sports.md](./docs/japanese-sports.md)); 0.5.0 adds fifty balls: vintage leather soccer balls, era-style and shop-wall soccer balls, baseballs of other threads and volleyballs in national colours, with a `colors` option (244 emblems: [docs/vintage-balls.md](./docs/vintage-balls.md)); 0.4.0 adds eight printed pucks and a `face` option (194 emblems: [docs/pucks.md](./docs/pucks.md)); 0.3.0 adds nineteen soccer balls (26, 18, 14, 12 and 6 panels, winter orange and high-visibility yellow, futsal and beach soccer: 186 emblems); 0.2.1 draws every ball and implement to the rulebook's proportions; 0.2.0 is 167 emblems, every one drawn here, with the Japanese sports, engraving, a turn for every emblem and the compose helpers; 0.1.0 brought the first full set of 148; 0.0.1 was the first preview.
|
|
608
638
|
|
|
609
639
|
## Credits
|
|
610
640
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Baseball: a white leather ball with 108 red double stitches in V's along the figure-eight seam.
|
|
2
|
-
import { seamedBall } from "./ball.family.seamed.js";
|
|
2
|
+
import { SEAMED_HOME, seamedBall } from "./ball.family.seamed.js";
|
|
3
3
|
export const BALL_BASEBALL = /* @__PURE__ */ seamedBall({
|
|
4
4
|
id: "ball:baseball",
|
|
5
5
|
en: "Baseball",
|
|
@@ -9,6 +9,7 @@ export const BALL_BASEBALL = /* @__PURE__ */ seamedBall({
|
|
|
9
9
|
b: 0.4,
|
|
10
10
|
view: { yaw: 18, pitch: 28, roll: -10 },
|
|
11
11
|
mat: { gloss: 0.3, shade: "#4a3a2a", grain: { f: 1.4, a: 0.12 } },
|
|
12
|
+
home: SEAMED_HOME("baseball"),
|
|
12
13
|
groove: "#8a7a62",
|
|
13
14
|
stitch: { colour: "#c4262e", count: 108, half: 0.075, width: 0.85, lean: 0.032 },
|
|
14
15
|
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The contrast of two colours, 1 to 21. */
|
|
2
|
+
export declare function contrast(a: string, b: string): number;
|
|
3
|
+
/** The stitch colour for a ball: the wanted one if it is a colour, else the ball's own thread, cream, navy or near-black, whichever shows on every colour the ball is. */
|
|
4
|
+
export declare function stitchFor(grounds: readonly string[], wanted: string | undefined, fallback: string): string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Contrast of colours, for choosing a thread or an ink that shows on the ball. Imports only the core's colour reader.
|
|
2
|
+
import { hexOf, readColour } from "./ball.core.js";
|
|
3
|
+
const luminance = (hex) => {
|
|
4
|
+
const rgb = readColour(hex) ?? [128, 128, 128];
|
|
5
|
+
const f = (c) => {
|
|
6
|
+
const v = c / 255;
|
|
7
|
+
return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
8
|
+
};
|
|
9
|
+
return 0.2126 * f(rgb[0]) + 0.7152 * f(rgb[1]) + 0.0722 * f(rgb[2]);
|
|
10
|
+
};
|
|
11
|
+
/** The contrast of two colours, 1 to 21. */
|
|
12
|
+
export function contrast(a, b) {
|
|
13
|
+
const x = luminance(a), y = luminance(b);
|
|
14
|
+
return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
|
|
15
|
+
}
|
|
16
|
+
/** The stitch colour for a ball: the wanted one if it is a colour, else the ball's own thread, cream, navy or near-black, whichever shows on every colour the ball is. */
|
|
17
|
+
export function stitchFor(grounds, wanted, fallback) {
|
|
18
|
+
const w = wanted === undefined ? undefined : readColour(wanted);
|
|
19
|
+
if (w !== undefined)
|
|
20
|
+
return hexOf(w);
|
|
21
|
+
return [fallback, "#f4f0e6", "#1b2a5c", "#101418"].find((c) => grounds.every((g) => contrast(c, g) >= 2.2)) ?? fallback;
|
|
22
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { FlagRenderer, PuckFace } from "./ball.face.ts";
|
|
2
|
+
import type { Surface } from "./ball.engine.ts";
|
|
3
|
+
import type { BallDecal, BallMark, BallPaint, BallScript, BallSpots, BallStamp } from "./ball.print.ts";
|
|
2
4
|
/** `metal` (also written `colour`): full colour, with shading. `line`: one outline in `currentColor`. */
|
|
3
5
|
export type PieceStyle = "metal" | "colour" | "color" | "line";
|
|
4
6
|
/** `inherit` (the default): the page's text colour. `auto`: dark ink on a light device and pale ink on a dark one. `light` and `dark` force one. */
|
|
@@ -27,7 +29,23 @@ export interface PieceOptions {
|
|
|
27
29
|
flags?: FlagRenderer;
|
|
28
30
|
/** A judogi seen from behind: the back number on it (see `Backnumber`). The back views of the judogi (`gear:judogi-back`, `gear:judogi-blue-back`) take it; anything else ignores it. */
|
|
29
31
|
backnumber?: Backnumber;
|
|
32
|
+
/** A baseball, a softball and the classic soccer balls: the colour of the ball, as one colour or two (see `BallPaint`). Any other ball takes the body colour as a tint. */
|
|
33
|
+
paint?: string | BallPaint;
|
|
34
|
+
/** A baseball, a softball and the classic soccer balls: a logo printed on the side of the ball, wrapped to the sphere (see `BallDecal`). An SVG string, a `data:` image URI or an object. */
|
|
35
|
+
decal?: string | BallDecal;
|
|
36
|
+
/** The same balls: stamped text like a ball's stamp, `true` for the default (see `BallStamp`). */
|
|
37
|
+
stamp?: boolean | string | readonly string[] | BallStamp;
|
|
38
|
+
/** The same balls: a cursive script word where a maker's mark sits, `true` for the ball's own word, or your text (see `BallScript`). */
|
|
39
|
+
script?: boolean | string | BallScript;
|
|
40
|
+
/** The same balls: a small mark under the script, `true` for the circled letter, an SVG string of your own, or an object (see `BallMark`). */
|
|
41
|
+
mark?: boolean | string | BallMark;
|
|
42
|
+
/** The same balls: where on the ball the logo and the lettering go (see `BallSpots`). */
|
|
43
|
+
spots?: BallSpots;
|
|
44
|
+
/** @internal The function that draws the print of a ball (`printLayers`). `renderEmblem`, the registry and `printed()` set it; a ball taken from its own module has none and ignores `decal`, `stamp`, `script` and `mark`. */
|
|
45
|
+
printer?: PrintRenderer;
|
|
30
46
|
}
|
|
47
|
+
/** What draws the print of a ball on its surface: the options, the ball's own word, and the colours the print lies on. */
|
|
48
|
+
export type PrintRenderer = (s: Surface, p: PrintOptions | undefined, word: string, grounds: readonly string[]) => string;
|
|
31
49
|
/**
|
|
32
50
|
* The back number sewn on the back of a judogi (IJF Sport and Organisation Rules, C1.8): the competitor's family name and the three letters of the National Olympic Committee, on a white patch under a coloured band.
|
|
33
51
|
* Only `gear:judogi-back` and `gear:judogi-blue-back` take it; anything else ignores it.
|
|
@@ -112,7 +130,31 @@ export interface ResolvedOptions {
|
|
|
112
130
|
flags: FlagRenderer | undefined;
|
|
113
131
|
/** A string that tells two faces apart, for the ids of a drawing. */
|
|
114
132
|
faceKey: string;
|
|
133
|
+
/** The colours of a printed or painted ball, read and made safe; undefined when none was asked for. */
|
|
134
|
+
paint: ResolvedPaint | undefined;
|
|
135
|
+
/** What a ball is printed with, as the caller gave it (made safe where it is drawn, by `resolvePrint`); undefined when nothing was asked for. */
|
|
136
|
+
print: PrintOptions | undefined;
|
|
137
|
+
/** What draws the print, when the caller has it (see `PieceOptions.printer`). */
|
|
138
|
+
printer: PrintRenderer | undefined;
|
|
115
139
|
}
|
|
140
|
+
/** The colours of a painted ball, as hex colours. */
|
|
141
|
+
export interface ResolvedPaint {
|
|
142
|
+
body: string | undefined;
|
|
143
|
+
second: string | undefined;
|
|
144
|
+
split: "seam" | "half";
|
|
145
|
+
angle: number;
|
|
146
|
+
stitch: string | undefined;
|
|
147
|
+
}
|
|
148
|
+
/** The printing options of a ball, as given. */
|
|
149
|
+
export interface PrintOptions {
|
|
150
|
+
decal?: PieceOptions["decal"];
|
|
151
|
+
stamp?: PieceOptions["stamp"];
|
|
152
|
+
script?: PieceOptions["script"];
|
|
153
|
+
mark?: PieceOptions["mark"];
|
|
154
|
+
spots?: PieceOptions["spots"];
|
|
155
|
+
}
|
|
156
|
+
/** True when a ball is asked to carry a logo, lettering or a mark. */
|
|
157
|
+
export declare const hasPrint: (p: PrintOptions | undefined) => boolean;
|
|
116
158
|
export declare function resolveOptions(o: PieceOptions | undefined): ResolvedOptions;
|
|
117
159
|
/** The ink of a drawing when a theme sets it, and the page it is made to read on. */
|
|
118
160
|
export declare const PIECE_INK: {
|
|
@@ -42,6 +42,39 @@ export function hashOf(text) {
|
|
|
42
42
|
h = Math.imul(h ^ text.charCodeAt(i), 16777619);
|
|
43
43
|
return (h >>> 0).toString(36);
|
|
44
44
|
}
|
|
45
|
+
/** True when a ball is asked to carry a logo, lettering or a mark. */
|
|
46
|
+
export const hasPrint = (p) => p !== undefined && ((p.decal !== undefined && p.decal !== false) || [p.stamp, p.script, p.mark].some((v) => v !== undefined && v !== false));
|
|
47
|
+
function paintOf(value) {
|
|
48
|
+
const o = typeof value === "string" ? { body: value } : typeof value === "object" && value !== null ? value : undefined;
|
|
49
|
+
if (o === undefined)
|
|
50
|
+
return undefined;
|
|
51
|
+
const pick = (v) => {
|
|
52
|
+
const rgb = typeof v === "string" ? readColour(v) : undefined;
|
|
53
|
+
return rgb === undefined ? undefined : hexOf(rgb);
|
|
54
|
+
};
|
|
55
|
+
const body = pick(o.body), second = pick(o.second), stitch = pick(o.stitch);
|
|
56
|
+
if (body === undefined && second === undefined && stitch === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
const angle = typeof o.angle === "number" && Number.isFinite(o.angle) ? Math.max(-360, Math.min(360, o.angle)) : 0;
|
|
59
|
+
return { body, second, split: o.split === "half" ? "half" : "seam", angle, stitch };
|
|
60
|
+
}
|
|
61
|
+
/** The printing options that were given, copied (a hostile object is never held), or undefined when there are none. */
|
|
62
|
+
function printOf(o) {
|
|
63
|
+
if (o === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
const p = {};
|
|
66
|
+
if (o.decal !== undefined)
|
|
67
|
+
p.decal = o.decal;
|
|
68
|
+
if (o.stamp !== undefined)
|
|
69
|
+
p.stamp = o.stamp;
|
|
70
|
+
if (o.script !== undefined)
|
|
71
|
+
p.script = o.script;
|
|
72
|
+
if (o.mark !== undefined)
|
|
73
|
+
p.mark = o.mark;
|
|
74
|
+
if (o.spots !== undefined)
|
|
75
|
+
p.spots = o.spots;
|
|
76
|
+
return Object.keys(p).length === 0 ? undefined : p;
|
|
77
|
+
}
|
|
45
78
|
/** What tells one face from another: its plain data (a renderer is a function, and only its name goes in). */
|
|
46
79
|
function faceKeyOf(face) {
|
|
47
80
|
if (typeof face !== "object" || face === null)
|
|
@@ -68,7 +101,7 @@ export function resolveOptions(o) {
|
|
|
68
101
|
const theme = o?.theme === "auto" || o?.theme === "light" || o?.theme === "dark" ? o.theme : "inherit";
|
|
69
102
|
const tint = readColour(o?.tint);
|
|
70
103
|
const accent = readColour(o?.accent);
|
|
71
|
-
return { style: o?.style === "line" ? "line" : "colour", size, theme, tint: tint === undefined ? undefined : hexOf(tint), accent: accent === undefined ? undefined : hexOf(accent), colors: coloursOf(o?.colors), grain: typeof o?.grain === "boolean" ? o.grain : undefined, face: typeof o?.face === "object" && o.face !== null ? o.face : undefined, flags: typeof o?.flags === "function" ? o.flags : undefined, faceKey: faceKeyOf(o?.face) + (typeof o?.flags === "function" ? `|fn:${o.flags.name}` : "") };
|
|
104
|
+
return { style: o?.style === "line" ? "line" : "colour", size, theme, tint: tint === undefined ? undefined : hexOf(tint), accent: accent === undefined ? undefined : hexOf(accent), colors: coloursOf(o?.colors), grain: typeof o?.grain === "boolean" ? o.grain : undefined, face: typeof o?.face === "object" && o.face !== null ? o.face : undefined, flags: typeof o?.flags === "function" ? o.flags : undefined, faceKey: faceKeyOf(o?.face) + (typeof o?.flags === "function" ? `|fn:${o.flags.name}` : ""), paint: paintOf(o?.paint), print: printOf(o), printer: typeof o?.printer === "function" ? o.printer : undefined };
|
|
72
105
|
}
|
|
73
106
|
/** The ink of a drawing when a theme sets it, and the page it is made to read on. */
|
|
74
107
|
export const PIECE_INK = { light: "#20262d", dark: "#eef1f3" };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Piece, type PieceSize, type ResolvedOptions } from "./ball.core.ts";
|
|
2
|
-
import { type V3 } from "./ball.math.ts";
|
|
1
|
+
import { type Piece, type PieceSize, type PrintOptions, type PrintRenderer, type ResolvedOptions, type ResolvedPaint } from "./ball.core.ts";
|
|
2
|
+
import { type M3, type V3 } from "./ball.math.ts";
|
|
3
3
|
/** How a ball takes the light. */
|
|
4
4
|
export interface Material {
|
|
5
5
|
/** The colour of the shadowed side; by default the base colour made darker. */
|
|
@@ -32,12 +32,14 @@ export interface Surface {
|
|
|
32
32
|
ink?: boolean;
|
|
33
33
|
opacity?: number;
|
|
34
34
|
n?: number;
|
|
35
|
+
rule?: "evenodd";
|
|
35
36
|
}): string;
|
|
36
37
|
/** Several closed polygons of one fill, drawn as one path (a smaller document than a path for each). */
|
|
37
38
|
panels(rings: ReadonlyArray<readonly V3[]>, fill: string, o?: {
|
|
38
39
|
ink?: boolean;
|
|
39
40
|
opacity?: number;
|
|
40
41
|
n?: number;
|
|
42
|
+
rule?: "evenodd";
|
|
41
43
|
}): string;
|
|
42
44
|
/** A curve on the surface: only what faces you. `closed` joins its ends; `deco` marks a line that is not part of the ball's form (a highlight), which the line style leaves out. */
|
|
43
45
|
stroke(pts: readonly V3[], colour: string, width: number, o?: StrokeOptions): string;
|
|
@@ -59,8 +61,16 @@ export interface Surface {
|
|
|
59
61
|
facing(u: V3): number;
|
|
60
62
|
/** A point of space, in units of the ball's radius from its centre (not on the surface): its screen position and depth (positive is toward you). */
|
|
61
63
|
space(p: V3): [number, number, number];
|
|
64
|
+
/** The whole disc of the ball filled with a colour (a sphere's silhouette). */
|
|
65
|
+
fill(colour: string): string;
|
|
66
|
+
/** The ball's view, for a module that draws what the engine does not (`ball.region.ts`). Opaque to everything else. */
|
|
67
|
+
readonly view: Geometry;
|
|
68
|
+
/** Where a ball's printing sits: the middle of its label area in the ball's own frame, and the right-hand and upward directions there. Only a ball that is printed has one. */
|
|
69
|
+
readonly home: HomeFrame | undefined;
|
|
62
70
|
}
|
|
63
71
|
export interface StrokeOptions {
|
|
72
|
+
/** Digits kept after the point in the path (1 by default; lettering asks for 2). */
|
|
73
|
+
digits?: number;
|
|
64
74
|
closed?: boolean;
|
|
65
75
|
ink?: boolean;
|
|
66
76
|
deco?: boolean;
|
|
@@ -88,8 +98,23 @@ export interface BallSpec {
|
|
|
88
98
|
/** The colour the whole ball is filled with before its panels are laid on, where it is not `base` (a soccer ball is white, its pentagons are `base`). */
|
|
89
99
|
ground?: string;
|
|
90
100
|
mat: Material;
|
|
91
|
-
/** Lays the panels and seams. `base` is the main colour, or the tint; `accent` is the second colour or undefined. */
|
|
92
|
-
draw: (s: Surface, base: string, accent: string | undefined, colors?: readonly [string, string, string]) => string;
|
|
101
|
+
/** Lays the panels and seams. `base` is the main colour, or the tint; `accent` is the second colour or undefined. `custom` is what a caller asked to paint and print (a ball that takes it reads it; the rest ignore it). */
|
|
102
|
+
draw: (s: Surface, base: string, accent: string | undefined, colors?: readonly [string, string, string], custom?: Custom) => string;
|
|
103
|
+
/**
|
|
104
|
+
* Where a ball carries a logo and lettering: the middle of the label area (`c`) and the way up there (`up`), as directions in the ball's own frame, how far it reaches from the middle (`reach`, radians),
|
|
105
|
+
* the view that shows it (`view`, used instead of `view` when the caller prints something) and the ball's own word for the script and the stamp (`word`).
|
|
106
|
+
*/
|
|
107
|
+
home?: {
|
|
108
|
+
c: V3;
|
|
109
|
+
up: V3;
|
|
110
|
+
reach: number;
|
|
111
|
+
view: {
|
|
112
|
+
yaw: number;
|
|
113
|
+
pitch: number;
|
|
114
|
+
roll: number;
|
|
115
|
+
};
|
|
116
|
+
word: string;
|
|
117
|
+
};
|
|
93
118
|
/** Where the ball's centre is in the 100 by 100 box (50, 50 by default): a hammer's head sits in a corner to leave room for the wire. */
|
|
94
119
|
centre?: readonly [number, number];
|
|
95
120
|
/** Where the ball is in space, in units of its radius from the middle of the whole (0, 0, 0 by default), turned with it: a hammer's head is at one end of the hammer, which turns about its middle. */
|
|
@@ -102,6 +127,47 @@ export interface BallSpec {
|
|
|
102
127
|
front: string;
|
|
103
128
|
};
|
|
104
129
|
}
|
|
130
|
+
/** The label area of a printed ball: its middle, and the right-hand and upward directions there, and how far it reaches. */
|
|
131
|
+
export interface HomeFrame {
|
|
132
|
+
c: V3;
|
|
133
|
+
ex: V3;
|
|
134
|
+
up: V3;
|
|
135
|
+
reach: number;
|
|
136
|
+
}
|
|
137
|
+
/** What a caller asked a ball to be painted and printed with. */
|
|
138
|
+
export interface Custom {
|
|
139
|
+
paint: ResolvedPaint | undefined;
|
|
140
|
+
print: PrintOptions | undefined;
|
|
141
|
+
/** Draws the print, when the caller has it; without it a ball draws no print. */
|
|
142
|
+
printer: PrintRenderer | undefined;
|
|
143
|
+
}
|
|
144
|
+
export declare const EPS = 0.000001;
|
|
145
|
+
export interface Geometry {
|
|
146
|
+
/** The centre of the ball on the screen, and the middle of the whole (where a point of `space` is measured from). */
|
|
147
|
+
cx: number;
|
|
148
|
+
cy: number;
|
|
149
|
+
ox: number;
|
|
150
|
+
oy: number;
|
|
151
|
+
axes: V3;
|
|
152
|
+
rot: M3;
|
|
153
|
+
k: number;
|
|
154
|
+
/** The unit sphere's point is visible when its dot with `w` is above 0. */
|
|
155
|
+
w: V3;
|
|
156
|
+
wl: number;
|
|
157
|
+
/** The third row of the rotation: the direction of the eye in the ball's own frame. */
|
|
158
|
+
rz: V3;
|
|
159
|
+
/** The exponent of a pointed ball's profile, or undefined for an ellipsoid. */
|
|
160
|
+
point: number | undefined;
|
|
161
|
+
}
|
|
162
|
+
/** How squarely a point of the sphere faces the eye, before it is scaled: above 0 is the side you see. For an ellipsoid it is the dot of the point with `w`; for a pointed ball the surface's normal is worked out. */
|
|
163
|
+
export declare const visOf: (g: Geometry, u: V3) => number;
|
|
164
|
+
export declare const project: (g: Geometry, u: V3) => [number, number];
|
|
165
|
+
export interface Run {
|
|
166
|
+
pts: Array<[number, number, number]>;
|
|
167
|
+
}
|
|
168
|
+
/** The parts of a curve that face you, each as screen points with their facing. The curve is cut exactly at the limb. */
|
|
169
|
+
export declare function visibleRuns(g: Geometry, pts: readonly V3[], closed: boolean): Run[];
|
|
170
|
+
export declare const pathOf: (pts: Array<[number, number, number]>, digits?: number) => string;
|
|
105
171
|
/** Draws a ball: the document for a spec, the options and a turn in radians. */
|
|
106
172
|
export declare function drawBall(title: string, key: string, spec: BallSpec, opts: ResolvedOptions, turn: {
|
|
107
173
|
yaw: number;
|