@johnmorrisdotca/dougu-sports 0.3.0 → 0.3.2

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 CHANGED
@@ -6,6 +6,22 @@ All notable changes to this project are written here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.3.2] - 2026-10-14
10
+
11
+ The README pictures fill their frames: balls first, then trophies, then gear, each a full grid.
12
+
13
+ ### Changed
14
+
15
+ - **README pictures are full grids.** The opening picture is now thirty-six balls and pucks in four full rows of nine, followed by one of trophies, medals and crests and one of gear (each light and dark), then a turn strip of four rows of seven and a phone shot of twelve emblems. No row is ragged and there is no empty band. They are webp (made in the browser by `pnpm screenshots`, about 60 to 400 kB each) instead of png.
16
+
17
+ ## [0.3.1] - 2026-10-14
18
+
19
+ Nothing is cut off when an emblem turns: every cup and the pieces that were clipped at rest now draw inside their box at every angle.
20
+
21
+ ### Fixed
22
+
23
+ - **Tall and wide things were cut off by their own box as they turned, and a few were cut off at rest.** Every emblem is drawn in a fixed square box sized for the still drawing, and a turn grows the outline past it: tilted toward the eye by 60 degrees, the rim and the foot of all 16 cups (and the handles of the sumo cup, up to 17.6 of 64 units, a quarter of the picture) went out of the box. Each cup now has a `turnBox`, measured from its drawing over every yaw and tilt, and `emblemFrame`, `bindTurn` and `renderEmblem(id, { turnBox: true })` draw in it, so a turn is one size from the first frame to the last and the resting view of `bindTurn` is the same size too (the cup is drawn up to 30 percent smaller in its square while it can turn). A still drawing keeps its box and its size. Eleven pieces of flat art whose stroke ran past the 64 by 64 box at rest (the swim goggles, three skates, the diving board, the referee's fan, the running track and three pictograms, by up to 3.3 units) have a box that holds them. Balls, medals, crests and the other flat art needed nothing. `test/turnbox.test.ts` measures the ink of every emblem, still and turned, against its box. A frame at no turn is now the still in the box of the turn (`renderEmblem(id, { turnBox: true })`), which is the still itself for everything but those cups.
24
+
9
25
  ## [0.3.0] - 2026-10-14
10
26
 
11
27
  Nineteen more soccer balls (26, 18, 14, 12 and 6 panels, winter orange and high-visibility yellow, futsal and beach soccer), 186 emblems in all.
@@ -100,7 +116,10 @@ First preview: the name, the API and two sample emblems. The full set of trophie
100
116
  - Tests for the drawing, the ids, the turns and the bundle size of one item; a package check that installs the packed tarball and bundles one item from it.
101
117
  - The demo (a playground with a turn slider, and a gallery page), `docs/layout.md`, `docs/turning.md`, `docs/gallery.md`, the family header and footer, the CI, Pages and Release workflows, and `LICENSES/` and `NOTICE.md` ready for third-party art.
102
118
 
103
- [Unreleased]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.2.1...HEAD
119
+ [Unreleased]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.3.2...HEAD
120
+ [0.3.2]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.3.1...v0.3.2
121
+ [0.3.1]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.3.0...v0.3.1
122
+ [0.3.0]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.2.1...v0.3.0
104
123
  [0.2.1]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.2.0...v0.2.1
105
124
  [0.2.0]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.1.0...v0.2.0
106
125
  [0.1.0]: https://github.com/johnmorrisdotca/dougu-sports/compare/v0.0.1...v0.1.0
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <h1 align="center">Dougu Sports <sub>道具</sub></h1>
2
2
 
3
3
  <p align="center"><strong>Sports emblems as SVG strings, with optional 3D turning.</strong><br>
4
- Trophies, medals, crests, the icon of every sport, and the ball and gear of the sports, each one a function that returns SVG: in polished metal, in one line, or in flat colour, light and dark, any size, any tint. Turn one about its axis and it is another string. Each emblem is its own module, so a page that wants one trophy takes one trophy. MIT, with no dependencies.</p>
4
+ The ball and the gear of every sport, trophies, medals, crests and the icon of every sport, each one a function that returns SVG: in polished metal, in one line, or in flat colour, light and dark, any size, any tint. Turn one about its axis and it is another string. Each emblem is its own module, so a page that wants one trophy takes one trophy. MIT, with no dependencies.</p>
5
5
 
6
6
  <p align="center">
7
7
  <a href="https://github.com/johnmorrisdotca/dougu-sports/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/johnmorrisdotca/dougu-sports/actions/workflows/ci.yml/badge.svg"></a>
@@ -15,18 +15,32 @@ Trophies, medals, crests, the icon of every sport, and the ball and gear of the
15
15
 
16
16
  <p align="center">
17
17
  <picture>
18
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/hero-desk-dark.png">
19
- <img alt="Ten trophies drawn in metal, each a generic form that stands for a league's cup: a tall banded silver cup, a ring of gold pennants round a baseball, a football on a three-sided stand, a basketball over a net, a wide two-handled bowl on a tall base, a globe held up by spiral figures, a gilt dish, a lidded cup with a pineapple, a terracotta urn and a gilded lidded cup. Below them gold, silver and bronze medals, crests, a rosette, a wreath and a belt, and one cup in the three styles." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/hero-desk-light.png" width="760">
18
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/balls-desk-dark.webp">
19
+ <img alt="Thirty-six balls and pucks drawn in 3D, in four rows of nine: soccer balls of several constructions and colours, then basketball, the 3x3 ball, baseball, softball, a football, a rugby ball, an Australian football and two volleyballs, then tennis, padel, pickleball with its holes, squash with its two dots, racquetball, golf, red and pink cricket and water polo, then sepak takraw, a shuttlecock, a puck, a curling stone, lacrosse, handball, table tennis, a sliotar and a roundnet ball." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/balls-desk-light.webp" width="760">
20
+ </picture>
21
+ </p>
22
+
23
+ <p align="center">
24
+ <picture>
25
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/hero-desk-dark.webp">
26
+ <img alt="Trophies, medals and crests, in four rows of nine: nine famous cups, then a gilded cup, a phoenix-handle cup, a soccer ball trophy, a wreath, a rosette, a belt, a banner, a ring and a plaque, then three medals, three place badges and three crests, and last three cups each in metal, line and colour." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/hero-desk-light.webp" width="760">
27
+ </picture>
28
+ </p>
29
+
30
+ <p align="center">
31
+ <picture>
32
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/gear-desk-dark.webp">
33
+ <img alt="Thirty-six pieces of gear in four rows of nine: hockey stick and skate, a goalie mask, field hockey, lacrosse and hurling sticks, a cricket bat and wicket, a baseball bat and glove, a football helmet and goalposts, a basketball hoop, a volleyball net, rackets and paddles, a curling broom, skates, swim goggles, starting blocks, a baton, a javelin, a hurdle, and the kendo, sumo, judo, kyudo and karate gear of Japan." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/gear-desk-light.webp" width="760">
20
34
  </picture>
21
35
  </p>
22
36
 
23
37
  <table align="center">
24
38
  <tr>
25
39
  <td align="center" valign="top">
26
- <img alt="A two-handled cup, a banded cup, a medal and a soccer ball each turned through five angles: the cups keep their outline and move their light and handles, the medal flips like a coin to show its plain back, and the ball rolls." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/turn-desk-light.png" width="470"><br><em>Turned: a ball rolls, a medal flips</em>
40
+ <img alt="A two-handled cup, a medal, a soccer ball and a championship banner each turned through seven angles: the cup keeps its outline and moves its light and handles, the medal and the banner flip like a coin to show their plain backs, and the ball rolls." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/turn-desk-light.webp" width="470"><br><em>Turned: a ball rolls, a medal flips</em>
27
41
  </td>
28
42
  <td align="center" valign="top">
29
- <img alt="The same emblems on a phone, light." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/phone-light.png" width="200"><br><em>On a phone</em>
43
+ <img alt="Cups, a medal, balls and gear on a phone, three to a row." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/phone-light.webp" width="200"><br><em>On a phone</em>
30
44
  </td>
31
45
  </tr>
32
46
  </table>
@@ -59,6 +73,7 @@ Put the string in a page (`element.innerHTML = svg`), write it to a file, or sen
59
73
 
60
74
  ## Features
61
75
 
76
+ - **Equipment first (道具 is the word for it)**: 66 balls and implements drawn in 3D, from the 32-panel soccer ball to the 26, 18, 14, 12 and 6 panel constructions, futsal, beach soccer and the pucks and stones, each with its official size, and 42 pieces of gear (sticks, rackets, helmets, skates, nets, and the Japanese budo kit) drawn to match; see [docs/gallery.md](./docs/gallery.md).
62
77
  - **Three styles** for every emblem: `metal` (polished metal: a gradient, a highlight and a soft rim of reflected light, edged in a darker tone of its own metal, with no heavy outline), `line` (one clean outline in the page's text colour, made to read at 14 pixels) and `color` (flat fills); see [Theming](#theming).
63
78
  - **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.
64
79
  - **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).
@@ -78,8 +93,8 @@ Put the string in a page (`element.innerHTML = svg`), write it to a file, or sen
78
93
 
79
94
  <table>
80
95
  <tr>
81
- <td align="center" valign="top"><img alt="Ten trophies, medals and crests, and one cup in the three styles." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/hero-desk-light.png" width="360"><br><em>Trophies, medals and crests, and one cup in three styles</em></td>
82
- <td align="center" valign="top"><img alt="Cups, a medal and a ball turned through five angles." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/turn-desk-light.png" width="360"><br><em>Turned through five angles</em></td>
96
+ <td align="center" valign="top"><img alt="Balls and pucks in four rows of nine." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/balls-desk-light.webp" width="360"><br><em>Balls and pucks, trophies, medals and gear</em></td>
97
+ <td align="center" valign="top"><img alt="A cup, a medal, a ball and a banner turned through seven angles." src="https://raw.githubusercontent.com/johnmorrisdotca/dougu-sports/main/docs/images/turn-desk-light.webp" width="360"><br><em>Turned through seven angles</em></td>
83
98
  </tr>
84
99
  </table>
85
100
 
@@ -217,7 +232,7 @@ console.log(renderEmblem("medal:gold").includes(" color=")); // false
217
232
  import { ballFrame, emblemFrame } from "@johnmorrisdotca/dougu-sports/turn";
218
233
  import { renderEmblem } from "@johnmorrisdotca/dougu-sports/emblems";
219
234
 
220
- console.log(emblemFrame("trophy:hockey-cup", { yaw: 0 }) === renderEmblem("trophy:hockey-cup")); // true
235
+ console.log(emblemFrame("trophy:hockey-cup", { yaw: 0 }) === renderEmblem("trophy:hockey-cup", { turnBox: true })); // true
221
236
  console.log(emblemFrame("trophy:tennis-cup", { yaw: 90 }) === renderEmblem("trophy:tennis-cup")); // false
222
237
  console.log(ballFrame("ball:soccer", { yaw: 90 }) === ballFrame("ball:soccer", { yaw: 450 })); // true
223
238
  ```
@@ -44,6 +44,12 @@ export interface EmblemOptions {
44
44
  numberColor?: string;
45
45
  /** Which side of a pennant is drawn at rest: `"front"` (the default) or `"back"`. */
46
46
  view?: "front" | "back";
47
+ /**
48
+ * The box the drawing is made in. A turning emblem has two: the box of its still drawing, and a box that holds every turn of it (a cup tilted toward the eye shows its rim and its foot beyond the still drawing's
49
+ * edges). `true` draws in the box of the turn, so that a still drawing and the frames of its turn are one size; `false` draws a turned frame in the box of the still. By default a still drawing (`svg`) is in its own
50
+ * box and every turned frame (`frame`) is in the box of the turn, so nothing is cut off while it turns and the size does not change from one angle to the next.
51
+ */
52
+ turnBox?: boolean;
47
53
  }
48
54
  /** A turn, in degrees from the resting view (0 and 0 is the still drawing): `yaw` about the vertical axis, `pitch` the tilt toward the eye. */
49
55
  export interface FrameOptions extends EmblemOptions {
@@ -49,6 +49,14 @@ export interface LatheModel {
49
49
  tones?: Readonly<Record<string, string>>;
50
50
  /** The elevation of the eye in degrees at rest: how much of the top of a rim shows. */
51
51
  tilt?: number;
52
+ /** The view box of the still drawing, `x y width height`; "0 0 64 64" unless the still reaches past it (the stroke of a rim at the top edge). */
53
+ box?: string;
54
+ /**
55
+ * The view box of every turned frame. A turn tilts the body toward the eye by up to 60 degrees and away by 40: the rim and the foot swing up and down by the sine of the elevation times their radius, past the
56
+ * 64 by 64 box of the still drawing, and the handles, balls and poles swing out to their full reach. It is the box that holds the drawing at every yaw and pitch, so the drawing does not change size as it turns.
57
+ * `test/turnbox.test.ts` measures every frame against it, and `scripts/turn-boxes.mjs` prints the box a model needs.
58
+ */
59
+ turnBox?: string;
52
60
  solids: readonly Solid[];
53
61
  handles?: readonly Handle[];
54
62
  balls?: readonly Ball[];
@@ -414,13 +414,17 @@ const PENTAGONS = [
414
414
  ];
415
415
  /** A lathe emblem: the object with its names and its model, the still drawing and the turned one. */
416
416
  export function defineLathe(id, en, ja, source, model) {
417
- const frame = (o) => {
417
+ const rest = model.box ?? "0 0 64 64";
418
+ const turn = model.turnBox ?? rest;
419
+ // A still drawing is in its own box and a turned frame in the box of the turn, unless the options say otherwise; the box is the same for every angle.
420
+ const make = (o, turned) => {
418
421
  const r = resolve(o);
419
422
  const yaw = typeof o?.yaw === "number" && Number.isFinite(o.yaw) ? o.yaw % 360 : 0;
420
423
  const pitch = typeof o?.pitch === "number" && Number.isFinite(o.pitch) ? Math.max(-40, Math.min(60, o.pitch)) : 0;
421
424
  const d = draw(model, r, o, yaw, pitch);
422
- return wrap({ title: en, size: r.size, style: r.style, theme: r.theme, defs: d.defs, body: d.body, edge: d.edge, width: r.style === "line" ? 2.3 : 0.6 });
425
+ const box = (o?.turnBox ?? turned) ? turn : rest;
426
+ return wrap({ title: en, size: r.size, style: r.style, theme: r.theme, defs: d.defs, body: d.body, box, edge: d.edge, width: r.style === "line" ? 2.3 : 0.6 });
423
427
  };
424
- const still = labelled(en, ja, (o) => frame(o));
425
- return { id, en, ja, source, kind: "lathe", model, svg: still, frame: labelled(en, ja, frame) };
428
+ const still = labelled(en, ja, (o) => make(o, false));
429
+ return { id, en, ja, source, kind: "lathe", model, svg: still, frame: labelled(en, ja, (o) => make(o, true)) };
426
430
  }
@@ -1,6 +1,7 @@
1
1
  // Ice skates drawn by us, all facing right: a hockey skate, a figure skate and a speed skate.
2
2
  import { capsule, drawn, rect, seg } from "./gear.core.js";
3
3
  export const GEAR_HOCKEY_SKATE = /* @__PURE__ */ drawn("gear:hockey-skate", "Hockey skate", "アイスホッケースケート", {
4
+ box: "-0.9 -0.9 65.8 65.8",
4
5
  main: "#232a36",
5
6
  accent: "#d4202c",
6
7
  parts: [
@@ -14,6 +15,7 @@ export const GEAR_HOCKEY_SKATE = /* @__PURE__ */ drawn("gear:hockey-skate", "Hoc
14
15
  ],
15
16
  });
16
17
  export const GEAR_FIGURE_SKATE = /* @__PURE__ */ drawn("gear:figure-skate", "Figure skate", "フィギュアスケート靴", {
18
+ box: "-1.4 -1.4 66.8 66.8",
17
19
  main: "#f6f2ea",
18
20
  accent: "#c8a26a",
19
21
  parts: [
@@ -26,6 +28,7 @@ export const GEAR_FIGURE_SKATE = /* @__PURE__ */ drawn("gear:figure-skate", "Fig
26
28
  ],
27
29
  });
28
30
  export const GEAR_SPEED_SKATE = /* @__PURE__ */ drawn("gear:speed-skate", "Speed skate", "スピードスケート靴", {
31
+ box: "-1.2 -1.2 66.4 66.4",
29
32
  main: "#2a5fb0",
30
33
  accent: "#1d1f24",
31
34
  parts: [
@@ -1,6 +1,7 @@
1
1
  // Sumo gear, drawn for this package: the referee's war fan with its tassel, and the wrestler's belt with its stiff hanging cords.
2
2
  import { capsule, circle, drawn, seg } from "./gear.core.js";
3
3
  export const GEAR_GUNBAI = /* @__PURE__ */ drawn("gear:gunbai", "Referee's war fan", "軍配", {
4
+ box: "-0.4 0 64.7 64.7",
4
5
  main: "#4a2428",
5
6
  accent: "#f0dca6",
6
7
  parts: [
@@ -1,6 +1,7 @@
1
1
  // Swimming and diving gear drawn by us: a diving board over water, and a pair of goggles.
2
2
  import { capsule, drawn, ellipse, rect } from "./gear.core.js";
3
3
  export const GEAR_DIVING_BOARD = /* @__PURE__ */ drawn("gear:diving-board", "Diving board", "飛び込み板", {
4
+ box: "-1.4 -0.8 66.8 66.8",
4
5
  main: "#4b84b8",
5
6
  accent: "#8a949f",
6
7
  parts: [
@@ -11,6 +12,7 @@ export const GEAR_DIVING_BOARD = /* @__PURE__ */ drawn("gear:diving-board", "Div
11
12
  ],
12
13
  });
13
14
  export const GEAR_SWIM_GOGGLES = /* @__PURE__ */ drawn("gear:swim-goggles", "Swim goggles", "水泳のゴーグル", {
15
+ box: "-2.1 -2.1 68.2 68.2",
14
16
  main: "#2a7fd0",
15
17
  accent: "#1d1f24",
16
18
  parts: [
@@ -4,6 +4,7 @@ import { defineIcon } from "../emblem.shapes.js";
4
4
  const wave = (y) => `M3 ${y}q7-6 14 0t14 0 14 0 14 0`;
5
5
  /** Raised legs. */
6
6
  export const SPORT_ARTISTICSWIMMING = /* @__PURE__ */ defineIcon("sport:artisticswimming", "Raised legs", "水面に上げた脚", "ours", {
7
+ box: "-0.3 0 64.6 64.6",
7
8
  metal: "flat",
8
9
  ink: true,
9
10
  front: [
@@ -2,6 +2,7 @@
2
2
  import { defineIcon } from "../emblem.shapes.js";
3
3
  /** Running track. */
4
4
  export const SPORT_ATHLETICS = /* @__PURE__ */ defineIcon("sport:athletics", "Running track", "陸上競技のトラック", "ours", {
5
+ box: "-3.7 -3.7 71.4 71.4",
5
6
  metal: "flat",
6
7
  ink: true,
7
8
  front: [
@@ -4,6 +4,7 @@ import { circlePath as circ, defineIcon } from "../emblem.shapes.js";
4
4
  const wave = (y) => `M3 ${y}q7-6 14 0t14 0 14 0 14 0`;
5
5
  /** Diver. */
6
6
  export const SPORT_DIVING = /* @__PURE__ */ defineIcon("sport:diving", "Diver", "飛込の選手", "ours", {
7
+ box: "-0.3 0 64.6 64.6",
7
8
  metal: "flat",
8
9
  ink: true,
9
10
  front: [
@@ -2,6 +2,7 @@
2
2
  import { circlePath as circ, defineIcon } from "../emblem.shapes.js";
3
3
  /** Racquetball racket and ball. */
4
4
  export const SPORT_RACQUETBALL = /* @__PURE__ */ defineIcon("sport:racquetball", "Racquetball racket", "ラケットボールのラケット", "ours", {
5
+ box: "-0.3 0 64.6 64.6",
5
6
  metal: "flat",
6
7
  ink: true,
7
8
  front: [
@@ -3,6 +3,7 @@
3
3
  import { defineIcon } from "../emblem.shapes.js";
4
4
  /** Sumo. */
5
5
  export const SPORT_SUMO = /* @__PURE__ */ defineIcon("sport:sumo", "Sumo", "相撲", "ours", {
6
+ box: "-0.7 0 65.3 65.3",
6
7
  metal: "flat",
7
8
  ink: true,
8
9
  front: [
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A ring of about thirty gold pennants standing round a silver baseball on a round base. */
4
4
  export const TROPHY_BASEBALL = /* @__PURE__ */ defineLathe("trophy:baseball", "Baseball trophy", "野球のトロフィー", "ours", {
5
5
  metal: "silver",
6
+ turnBox: "-9.3 -7.3 82.6 82.6",
6
7
  tones: { gilt: "#d9a620", pole: "#aab2bc", accent: "#e0b030" },
7
8
  solids: [
8
9
  {
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A gold ball resting over a net and rim, on a tapered column and base. */
4
4
  export const TROPHY_BASKETBALL = /* @__PURE__ */ defineLathe("trophy:basketball", "Basketball trophy", "バスケットボールのトロフィー", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-5 0 74 74",
6
7
  solids: [
7
8
  {
8
9
  p: [
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A round bowl on a short foot. */
4
4
  export const TROPHY_BOWL = /* @__PURE__ */ defineLathe("trophy:bowl", "Bowl", "ボウル", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-6.7 -9.2 77.4 77.4",
6
7
  solids: [{ open: true, p: [[16, 25, 1], [19, 24.8], [30, 15], [38, 7, 1], [38, 4.6, 1], [46, 3.6, 1], [46, 9, 1], [49, 9, 1], [49, 13.4, 1], [54, 13.4, 1]], decor: [["ring", 21]] }],
7
8
  plate: { y0: 49.2, y1: 53.8 },
8
9
  });
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A wide silver bowl with two handles on a tall tiered base. */
4
4
  export const TROPHY_CANADIAN_BOWL = /* @__PURE__ */ defineLathe("trophy:canadian-bowl", "Wide two-handled bowl", "取っ手が二つの広いボウル", "ours", {
5
5
  metal: "silver",
6
+ turnBox: "-10.7 -9.6 85.3 85.3",
6
7
  tones: { dark: "#2b2f36" },
7
8
  solids: [
8
9
  {
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A small terracotta urn. */
4
4
  export const TROPHY_CRICKET_URN = /* @__PURE__ */ defineLathe("trophy:cricket-urn", "Urn", "取っ手付きの壺", "ours", {
5
5
  metal: "flat",
6
+ turnBox: "-2.2 0 68.4 68.4",
6
7
  color: "#a8442f",
7
8
  tones: { wood: "#b98a4f" },
8
9
  solids: [
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A silver football standing on end, tilted as if ready for a kick, on a tapered three-sided stand. */
4
4
  export const TROPHY_FOOTBALL = /* @__PURE__ */ defineLathe("trophy:football", "Football trophy", "アメフトのトロフィー", "ours", {
5
5
  metal: "silver",
6
+ turnBox: "-5.1 0 74.1 74.1",
6
7
  solids: [
7
8
  { sides: 3, p: [[28.6, 3.4, 1], [49, 10.2, 1], [49, 12.8, 1], [53.4, 12.8, 1], [53.4, 15, 1], [58.4, 15, 1]] },
8
9
  ],
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A globe in a stand. */
4
4
  export const TROPHY_GLOBE = /* @__PURE__ */ defineLathe("trophy:globe", "Globe on a stand", "台座の上の地球儀", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-5.5 0 74.9 74.9",
6
7
  solids: [{ p: [[34, 3.4, 1], [48, 3.4, 1], [48, 8, 1], [51, 8, 1], [51, 13, 1], [55, 13, 1], [55, 15.2, 1], [59, 15.2, 1]] }],
7
8
  balls: [{ kind: "globe", cy: 21, r: 15 }],
8
9
  plate: { y0: 55.2, y1: 58.8 },
@@ -4,6 +4,8 @@ import { defineLathe } from "../emblem.lathe.js";
4
4
  /** A tall silver cup: a small bowl on a collar over a tall tiered barrel of widening bands. */
5
5
  export const TROPHY_HOCKEY_CUP = /* @__PURE__ */ defineLathe("trophy:hockey-cup", "Banded silver cup", "段付きの銀カップ", "ours", {
6
6
  metal: "silver",
7
+ box: "-0.4 -0.8 64.8 64.8",
8
+ turnBox: "-8.8 -9.2 81.6 81.6",
7
9
  tones: { dark: "#2b2f36" },
8
10
  solids: [
9
11
  {
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A cup with a domed lid and a knob. */
4
4
  export const TROPHY_LIDDED_CUP = /* @__PURE__ */ defineLathe("trophy:lidded-cup", "Cup with a lid", "ふた付きカップ", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-1.2 0 66.4 66.4",
6
7
  solids: [
7
8
  {
8
9
  p: [
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A gilded two-handled cup with a lid. */
4
4
  export const TROPHY_RUGBY_CUP = /* @__PURE__ */ defineLathe("trophy:rugby-cup", "Gilded cup with a lid", "ふた付きの金色のカップ", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-6 -8.8 76.1 76.1",
6
7
  tones: { dark: "#3a2a22" },
7
8
  solids: [
8
9
  {
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A broad dish on a low foot, with a banded rim. */
4
4
  export const TROPHY_SALVER = /* @__PURE__ */ defineLathe("trophy:salver", "Salver", "足付きの丸盆", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-4.5 -8.4 72.9 72.9",
6
7
  tilt: 24,
7
8
  solids: [{ open: true, p: [[22, 30, 1], [24.4, 30, 1], [29, 22, 1], [34, 8, 1], [34, 4.8, 1], [42, 3.8, 1], [42, 9.4, 1], [46, 10.4, 1], [48, 12.6, 1], [51, 12.6, 1]], decor: [["disc", 26.4, "main"]] }],
8
9
  plate: { y0: 48.2, y1: 50.8 },
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A soccer ball held up on a tapering stand. */
4
4
  export const TROPHY_SOCCER_BALL = /* @__PURE__ */ defineLathe("trophy:soccer-ball", "Soccer ball trophy", "サッカーのトロフィー", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-5.4 0 74.7 74.7",
6
7
  solids: [{ p: [[27, 4.4, 1], [38, 3.4], [47, 5.4, 1], [47, 8, 1], [51, 8, 1], [51, 12.4, 1], [55, 12.4, 1], [55, 15, 1], [59, 15, 1]] }],
7
8
  balls: [{ kind: "soccer", cy: 16, r: 11.4 }],
8
9
  plate: { y0: 55.2, y1: 58.8 },
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** Gold spiral figures rising to hold up a globe, with green bands at the base. */
4
4
  export const TROPHY_SOCCER_GLOBE = /* @__PURE__ */ defineLathe("trophy:soccer-globe", "Globe on a column", "柱の上の地球儀", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-3.8 -0.4 71.6 71.6",
6
7
  tones: { green: "#1f8a5b" },
7
8
  solids: [
8
9
  {
@@ -6,6 +6,7 @@ const side = (a) => ({ a, w: 2.4, tone: "gilt", pts: [[8.4, 27], [14, 25], [18.4
6
6
  /** A tall silver cup with phoenix-crested handles on a tall stand. */
7
7
  export const TROPHY_SUMO_CUP = /* @__PURE__ */ defineLathe("trophy:sumo-cup", "Phoenix-handle cup", "鳳凰飾りの銀杯", "ours", {
8
8
  metal: "silver",
9
+ turnBox: "-12.9 -17.9 89.9 89.9",
9
10
  tones: { dark: "#2b2f36", gilt: "#d9a620" },
10
11
  solids: [
11
12
  {
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A two-handled cup with a lid and a small pineapple finial. */
4
4
  export const TROPHY_TENNIS_CUP = /* @__PURE__ */ defineLathe("trophy:tennis-cup", "Pineapple cup", "パイナップル飾りのカップ", "ours", {
5
5
  metal: "gold",
6
+ turnBox: "-3.6 -4.2 71.2 71.2",
6
7
  tones: { dark: "#2b2f36" },
7
8
  solids: [
8
9
  {
@@ -3,6 +3,7 @@ import { defineLathe } from "../emblem.lathe.js";
3
3
  /** A silver salver with a gilt pattern. */
4
4
  export const TROPHY_TENNIS_PLATE = /* @__PURE__ */ defineLathe("trophy:tennis-plate", "Plate on a pedestal", "台付きの大皿", "ours", {
5
5
  metal: "silver",
6
+ turnBox: "-5.9 -8.9 75.9 75.9",
6
7
  tilt: 36,
7
8
  tones: { gilt: "#d9a620", plain: "#9aa3ad" },
8
9
  solids: [
@@ -94,7 +94,8 @@ export function bindTurn(container, ref, options = {}) {
94
94
  renderId = undefined;
95
95
  }
96
96
  const at = angles.yaw === 0 && angles.pitch === 0 && angles.roll === 0;
97
- container.innerHTML = !turnable || at ? renderEmblem(current, frame) : emblemFrame(current, { ...frame, ...angles });
97
+ // The resting view of an emblem that turns is drawn in the box of the turn too, so that the element is the same size at every angle and a drag does not make the emblem jump or zoom at its first step.
98
+ container.innerHTML = !turnable ? renderEmblem(current, frame) : at ? renderEmblem(current, { turnBox: true, ...frame }) : emblemFrame(current, { ...frame, ...angles });
98
99
  };
99
100
  /** One drawing for any number of changes within a frame. */
100
101
  const schedule = () => {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.3.0";
1
+ export declare const VERSION = "0.3.2";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.3.0";
1
+ export const VERSION = "0.3.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johnmorrisdotca/dougu-sports",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Dougu Sports 道具, sports emblems as SVG strings: trophies, medals, crests, sport icons, and the ball and gear of every sport, in metal, line or flat colour, with optional 3D turning. Light and dark, accessible, tree-shakeable. Zero dependencies.",
5
5
  "keywords": [
6
6
  "sports",