@tungstenstudio/dartboard-input 1.0.0-rc.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/LICENSE +15 -0
- package/README.md +294 -0
- package/dist/index.cjs +450 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +91 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +89 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.js +415 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
|
|
24
|
+
DEFAULT_RINGS: () => DEFAULT_RINGS,
|
|
25
|
+
DEFAULT_SEGMENTS: () => DEFAULT_SEGMENTS,
|
|
26
|
+
Dartboard: () => Dartboard,
|
|
27
|
+
MOBILE_OPTIONS: () => MOBILE_OPTIONS,
|
|
28
|
+
addRingToSegments: () => addRingToSegments,
|
|
29
|
+
asPercent: () => asPercent,
|
|
30
|
+
buildThrowDetail: () => buildThrowDetail,
|
|
31
|
+
parseBed: () => parseBed
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(index_exports);
|
|
34
|
+
|
|
35
|
+
// src/dartboard.ts
|
|
36
|
+
var import_d3_selection = require("d3-selection");
|
|
37
|
+
var import_d3_shape = require("d3-shape");
|
|
38
|
+
|
|
39
|
+
// src/constants.ts
|
|
40
|
+
var DEFAULT_OPTIONS = {
|
|
41
|
+
size: null,
|
|
42
|
+
missPercent: 10,
|
|
43
|
+
doublePercent: 10,
|
|
44
|
+
outerSinglePercent: 25,
|
|
45
|
+
triplePercent: 10,
|
|
46
|
+
innerSinglePercent: 30,
|
|
47
|
+
singleBullPercent: 8,
|
|
48
|
+
doubleBullPercent: 7
|
|
49
|
+
};
|
|
50
|
+
var DEFAULT_RINGS = {
|
|
51
|
+
MISS: { name: "miss", abbr: "M", multiplier: 0 },
|
|
52
|
+
DOUBLE: { name: "double", abbr: "D", multiplier: 2 },
|
|
53
|
+
OUTER_SINGLE: { name: "outerSingle", abbr: "S", multiplier: 1 },
|
|
54
|
+
TRIPLE: { name: "triple", abbr: "T", multiplier: 3 },
|
|
55
|
+
INNER_SINGLE: { name: "innerSingle", abbr: "S", multiplier: 1 },
|
|
56
|
+
SINGLE_BULL: { name: "singleBull", abbr: "B", multiplier: 1 },
|
|
57
|
+
DOUBLE_BULL: { name: "doubleBull", abbr: "DB", multiplier: 2 }
|
|
58
|
+
};
|
|
59
|
+
var MOBILE_OPTIONS = {
|
|
60
|
+
missPercent: 7,
|
|
61
|
+
doublePercent: 14,
|
|
62
|
+
outerSinglePercent: 21,
|
|
63
|
+
triplePercent: 14,
|
|
64
|
+
innerSinglePercent: 26,
|
|
65
|
+
singleBullPercent: 9,
|
|
66
|
+
doubleBullPercent: 9
|
|
67
|
+
};
|
|
68
|
+
var DEFAULT_SEGMENTS = [
|
|
69
|
+
{ segment: 20, position: 1, color: "Dark" },
|
|
70
|
+
{ segment: 1, position: 2, color: "Light" },
|
|
71
|
+
{ segment: 18, position: 3, color: "Dark" },
|
|
72
|
+
{ segment: 4, position: 4, color: "Light" },
|
|
73
|
+
{ segment: 13, position: 5, color: "Dark" },
|
|
74
|
+
{ segment: 6, position: 6, color: "Light" },
|
|
75
|
+
{ segment: 10, position: 7, color: "Dark" },
|
|
76
|
+
{ segment: 15, position: 8, color: "Light" },
|
|
77
|
+
{ segment: 2, position: 9, color: "Dark" },
|
|
78
|
+
{ segment: 17, position: 10, color: "Light" },
|
|
79
|
+
{ segment: 3, position: 11, color: "Dark" },
|
|
80
|
+
{ segment: 19, position: 12, color: "Light" },
|
|
81
|
+
{ segment: 7, position: 13, color: "Dark" },
|
|
82
|
+
{ segment: 16, position: 14, color: "Light" },
|
|
83
|
+
{ segment: 8, position: 15, color: "Dark" },
|
|
84
|
+
{ segment: 11, position: 16, color: "Light" },
|
|
85
|
+
{ segment: 14, position: 17, color: "Dark" },
|
|
86
|
+
{ segment: 9, position: 18, color: "Light" },
|
|
87
|
+
{ segment: 12, position: 19, color: "Dark" },
|
|
88
|
+
{ segment: 5, position: 20, color: "Light" }
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
// src/utils.ts
|
|
92
|
+
var SCORING_RINGS = [
|
|
93
|
+
"DOUBLE",
|
|
94
|
+
"TRIPLE",
|
|
95
|
+
"OUTER_SINGLE",
|
|
96
|
+
"INNER_SINGLE",
|
|
97
|
+
"SINGLE_BULL",
|
|
98
|
+
"DOUBLE_BULL"
|
|
99
|
+
];
|
|
100
|
+
function buildThrowDetail(bed) {
|
|
101
|
+
return {
|
|
102
|
+
bed: bed.ring.abbr + bed.segment,
|
|
103
|
+
ring: bed.ring.name,
|
|
104
|
+
score: bed.segment * bed.ring.multiplier
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function asPercent(n) {
|
|
108
|
+
return parseFloat((n / 100).toFixed(2));
|
|
109
|
+
}
|
|
110
|
+
function addRingToSegments(ring, segments) {
|
|
111
|
+
return segments.map((segment) => ({ ...segment, ring }));
|
|
112
|
+
}
|
|
113
|
+
function parseBed(bed, rings, segments) {
|
|
114
|
+
if (bed.toLowerCase() === "miss") {
|
|
115
|
+
if (!segments) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
'parseBed: segments are required to resolve the "miss" keyword'
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return segments.map((s) => ({ segment: s.segment, ring: "MISS" }));
|
|
121
|
+
}
|
|
122
|
+
const numOnly = bed.match(/^(\d+)$/);
|
|
123
|
+
if (numOnly) {
|
|
124
|
+
const segment2 = parseInt(numOnly[1], 10);
|
|
125
|
+
return SCORING_RINGS.filter((key) => key in rings).map((ring) => ({ segment: segment2, ring }));
|
|
126
|
+
}
|
|
127
|
+
const match = bed.match(/^([A-Za-z]+)(\d+)$/);
|
|
128
|
+
if (!match) {
|
|
129
|
+
throw new Error(`Invalid bed format: "${bed}"`);
|
|
130
|
+
}
|
|
131
|
+
const [, abbr, numStr] = match.map((s, i) => i === 1 ? s.toUpperCase() : s);
|
|
132
|
+
const segment = parseInt(numStr, 10);
|
|
133
|
+
const targets = [];
|
|
134
|
+
for (const [key, ring] of Object.entries(rings)) {
|
|
135
|
+
if (ring.abbr === abbr) {
|
|
136
|
+
targets.push({ segment, ring: key });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (targets.length === 0) {
|
|
140
|
+
throw new Error(`Unknown bed abbreviation: "${abbr}"`);
|
|
141
|
+
}
|
|
142
|
+
return targets;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/dartboard.ts
|
|
146
|
+
function buildAriaLabel(bed) {
|
|
147
|
+
const detail = buildThrowDetail(bed);
|
|
148
|
+
return `${detail.bed}, scores ${detail.score}`;
|
|
149
|
+
}
|
|
150
|
+
var Dartboard = class {
|
|
151
|
+
constructor(container, options = {}, segments = DEFAULT_SEGMENTS, rings = DEFAULT_RINGS) {
|
|
152
|
+
this.board = null;
|
|
153
|
+
this.sizes = null;
|
|
154
|
+
this.rendered = false;
|
|
155
|
+
this._disabled = false;
|
|
156
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
157
|
+
this.segments = segments;
|
|
158
|
+
this.rings = rings;
|
|
159
|
+
const percentSum = this.options.missPercent + this.options.doublePercent + this.options.outerSinglePercent + this.options.triplePercent + this.options.innerSinglePercent + this.options.singleBullPercent + this.options.doubleBullPercent;
|
|
160
|
+
if (percentSum !== 100) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Dartboard: ring percentages must sum to 100 (got ${percentSum})`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const boardContainer = typeof container === "string" ? document.querySelector(container) : container;
|
|
166
|
+
if (!boardContainer) {
|
|
167
|
+
throw new Error(`Dartboard: container not found`);
|
|
168
|
+
}
|
|
169
|
+
const width = this.options.size || Math.min(boardContainer.offsetHeight, boardContainer.offsetWidth);
|
|
170
|
+
const segmentWidth = 360 / segments.length;
|
|
171
|
+
const radius = width / 2;
|
|
172
|
+
const rotation = segmentWidth / -2;
|
|
173
|
+
const wrapper = (0, import_d3_selection.select)(boardContainer).append("div").classed("c-Dartboard", true);
|
|
174
|
+
const svg = wrapper.append("svg").attr("viewBox", `0 0 ${width} ${width}`).attr("role", "group").attr("aria-label", "Dartboard").append("g").attr(
|
|
175
|
+
"transform",
|
|
176
|
+
`translate(${radius}, ${radius}) rotate(${rotation})`
|
|
177
|
+
);
|
|
178
|
+
const pieFn = (0, import_d3_shape.pie)().sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).value(() => segmentWidth);
|
|
179
|
+
this.board = {
|
|
180
|
+
container: boardContainer,
|
|
181
|
+
wrapper,
|
|
182
|
+
width,
|
|
183
|
+
height: width,
|
|
184
|
+
radius,
|
|
185
|
+
rotation,
|
|
186
|
+
segmentWidth,
|
|
187
|
+
svg,
|
|
188
|
+
pie: pieFn
|
|
189
|
+
};
|
|
190
|
+
this.sizes = {
|
|
191
|
+
miss: radius * asPercent(this.options.missPercent),
|
|
192
|
+
double: radius * asPercent(this.options.doublePercent),
|
|
193
|
+
outerSingle: radius * asPercent(this.options.outerSinglePercent),
|
|
194
|
+
triple: radius * asPercent(this.options.triplePercent),
|
|
195
|
+
innerSingle: radius * asPercent(this.options.innerSinglePercent),
|
|
196
|
+
singleBull: radius * asPercent(this.options.singleBullPercent),
|
|
197
|
+
doubleBull: radius * asPercent(this.options.doubleBullPercent)
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
render() {
|
|
201
|
+
if (!this.board || !this.sizes) return this;
|
|
202
|
+
if (this.rendered) return this;
|
|
203
|
+
this.rendered = true;
|
|
204
|
+
const { board, sizes } = this;
|
|
205
|
+
let innerRadius = 0;
|
|
206
|
+
let outerRadius = innerRadius + sizes.doubleBull;
|
|
207
|
+
this.renderBeds(
|
|
208
|
+
board,
|
|
209
|
+
this.rings.DOUBLE_BULL,
|
|
210
|
+
[{ segment: 25, color: "Dark" }],
|
|
211
|
+
outerRadius,
|
|
212
|
+
innerRadius
|
|
213
|
+
);
|
|
214
|
+
innerRadius = outerRadius;
|
|
215
|
+
outerRadius = innerRadius + sizes.singleBull;
|
|
216
|
+
this.renderBeds(
|
|
217
|
+
board,
|
|
218
|
+
this.rings.SINGLE_BULL,
|
|
219
|
+
[{ segment: 25, color: "Light" }],
|
|
220
|
+
outerRadius,
|
|
221
|
+
innerRadius
|
|
222
|
+
);
|
|
223
|
+
innerRadius = outerRadius;
|
|
224
|
+
outerRadius = innerRadius + sizes.innerSingle;
|
|
225
|
+
this.renderBeds(
|
|
226
|
+
board,
|
|
227
|
+
this.rings.INNER_SINGLE,
|
|
228
|
+
this.segments,
|
|
229
|
+
outerRadius,
|
|
230
|
+
innerRadius
|
|
231
|
+
);
|
|
232
|
+
innerRadius = outerRadius;
|
|
233
|
+
outerRadius = innerRadius + sizes.triple;
|
|
234
|
+
this.renderBeds(
|
|
235
|
+
board,
|
|
236
|
+
this.rings.TRIPLE,
|
|
237
|
+
this.segments,
|
|
238
|
+
outerRadius,
|
|
239
|
+
innerRadius
|
|
240
|
+
);
|
|
241
|
+
innerRadius = outerRadius;
|
|
242
|
+
outerRadius = innerRadius + sizes.outerSingle;
|
|
243
|
+
this.renderBeds(
|
|
244
|
+
board,
|
|
245
|
+
this.rings.OUTER_SINGLE,
|
|
246
|
+
this.segments,
|
|
247
|
+
outerRadius,
|
|
248
|
+
innerRadius
|
|
249
|
+
);
|
|
250
|
+
innerRadius = outerRadius;
|
|
251
|
+
outerRadius = innerRadius + sizes.double;
|
|
252
|
+
this.renderBeds(
|
|
253
|
+
board,
|
|
254
|
+
this.rings.DOUBLE,
|
|
255
|
+
this.segments,
|
|
256
|
+
outerRadius,
|
|
257
|
+
innerRadius
|
|
258
|
+
);
|
|
259
|
+
innerRadius = board.radius - sizes.miss;
|
|
260
|
+
outerRadius = board.radius;
|
|
261
|
+
this.renderMissRing(
|
|
262
|
+
board,
|
|
263
|
+
this.rings.MISS,
|
|
264
|
+
this.segments,
|
|
265
|
+
outerRadius,
|
|
266
|
+
innerRadius
|
|
267
|
+
);
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
destroy() {
|
|
271
|
+
if (this.board) {
|
|
272
|
+
this.board.wrapper.selectAll(".c-Dartboard-bed").on("pointerup", null).on("pointerenter", null).on("pointerleave", null).on("keydown", null);
|
|
273
|
+
this.board.wrapper.remove();
|
|
274
|
+
this.board = null;
|
|
275
|
+
this.sizes = null;
|
|
276
|
+
this.rendered = false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
get disabled() {
|
|
280
|
+
return this._disabled;
|
|
281
|
+
}
|
|
282
|
+
disable() {
|
|
283
|
+
this._disabled = true;
|
|
284
|
+
if (this.board) {
|
|
285
|
+
this.board.wrapper.classed("is-disabled", true);
|
|
286
|
+
}
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
enable() {
|
|
290
|
+
this._disabled = false;
|
|
291
|
+
if (this.board) {
|
|
292
|
+
this.board.wrapper.classed("is-disabled", false);
|
|
293
|
+
}
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
throwAt(target) {
|
|
297
|
+
if (!this.board || this._disabled) return;
|
|
298
|
+
const targets = this.resolveTargets([target]);
|
|
299
|
+
if (targets.length === 0) return;
|
|
300
|
+
const first = targets[0];
|
|
301
|
+
if (!this.isValidTarget(first)) {
|
|
302
|
+
throw new Error(`Dartboard: invalid throw target \u2014 segment ${first.segment} does not exist`);
|
|
303
|
+
}
|
|
304
|
+
const ring = this.rings[first.ring];
|
|
305
|
+
const bed = { segment: first.segment, color: "Dark", ring };
|
|
306
|
+
const detail = buildThrowDetail(bed);
|
|
307
|
+
this.board.container.dispatchEvent(
|
|
308
|
+
new CustomEvent("throw", { detail })
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
highlight(targets, options = {}) {
|
|
312
|
+
if (!this.board) return;
|
|
313
|
+
const className = options.className || "is-highlighted";
|
|
314
|
+
for (const target of this.resolveTargets(targets)) {
|
|
315
|
+
const ring = this.rings[target.ring];
|
|
316
|
+
const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;
|
|
317
|
+
this.board.wrapper.selectAll(selector).classed(className, true);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
unhighlight(targets, options = {}) {
|
|
321
|
+
if (!this.board) return;
|
|
322
|
+
const className = options.className || "is-highlighted";
|
|
323
|
+
for (const target of this.resolveTargets(targets)) {
|
|
324
|
+
const ring = this.rings[target.ring];
|
|
325
|
+
const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;
|
|
326
|
+
this.board.wrapper.selectAll(selector).classed(className, false);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
reset(className = "is-highlighted") {
|
|
330
|
+
if (!this.board) return;
|
|
331
|
+
this.board.wrapper.selectAll(`.${className}`).classed(className, false);
|
|
332
|
+
}
|
|
333
|
+
isValidTarget(target) {
|
|
334
|
+
const isBull = target.ring === "DOUBLE_BULL" || target.ring === "SINGLE_BULL";
|
|
335
|
+
if (isBull) {
|
|
336
|
+
return target.segment === 25;
|
|
337
|
+
}
|
|
338
|
+
return this.segments.some((s) => s.segment === target.segment);
|
|
339
|
+
}
|
|
340
|
+
resolveTargets(inputs) {
|
|
341
|
+
return inputs.flatMap((input) => {
|
|
342
|
+
if (typeof input === "number") {
|
|
343
|
+
return parseBed(String(input), this.rings, this.segments);
|
|
344
|
+
}
|
|
345
|
+
if (typeof input === "string") {
|
|
346
|
+
return parseBed(input, this.rings, this.segments);
|
|
347
|
+
}
|
|
348
|
+
if (!input.ring) {
|
|
349
|
+
return parseBed(String(input.segment), this.rings, this.segments);
|
|
350
|
+
}
|
|
351
|
+
return [input];
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
dispatchThrow(bed) {
|
|
355
|
+
if (!this.board || this._disabled) return;
|
|
356
|
+
const detail = buildThrowDetail(bed);
|
|
357
|
+
this.board.container.dispatchEvent(
|
|
358
|
+
new CustomEvent("throw", { detail })
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
dispatchHover(bed, hovering) {
|
|
362
|
+
if (!this.board || this._disabled) return;
|
|
363
|
+
const throwDetail = buildThrowDetail(bed);
|
|
364
|
+
const detail = { ...throwDetail, hovering };
|
|
365
|
+
this.board.container.dispatchEvent(
|
|
366
|
+
new CustomEvent("hover", { detail })
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
renderBeds(board, ring, segments, outerRadius, innerRadius) {
|
|
370
|
+
const className = `c-Dartboard-${ring.name}`;
|
|
371
|
+
const arcFn = (0, import_d3_shape.arc)().outerRadius(outerRadius).innerRadius(innerRadius);
|
|
372
|
+
const beds = board.svg.append("g").classed(className, true).selectAll("arc").data(board.pie(addRingToSegments(ring, segments))).enter().append("g").attr(
|
|
373
|
+
"class",
|
|
374
|
+
(d) => `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} ${className}--${d.data.segment} is${d.data.color}`
|
|
375
|
+
).attr("role", "button").attr("tabindex", "0").attr(
|
|
376
|
+
"aria-label",
|
|
377
|
+
(d) => buildAriaLabel(d.data)
|
|
378
|
+
).on(
|
|
379
|
+
"pointerup",
|
|
380
|
+
(_event, d) => {
|
|
381
|
+
this.dispatchThrow(d.data);
|
|
382
|
+
}
|
|
383
|
+
).on(
|
|
384
|
+
"pointerenter",
|
|
385
|
+
(_event, d) => {
|
|
386
|
+
(0, import_d3_selection.select)(_event.currentTarget).classed("is-hovered", true);
|
|
387
|
+
this.dispatchHover(d.data, true);
|
|
388
|
+
}
|
|
389
|
+
).on(
|
|
390
|
+
"pointerleave",
|
|
391
|
+
(_event, d) => {
|
|
392
|
+
(0, import_d3_selection.select)(_event.currentTarget).classed("is-hovered", false);
|
|
393
|
+
this.dispatchHover(d.data, false);
|
|
394
|
+
}
|
|
395
|
+
).on(
|
|
396
|
+
"keydown",
|
|
397
|
+
(_event, d) => {
|
|
398
|
+
if (_event.key === "Enter" || _event.key === " ") {
|
|
399
|
+
_event.preventDefault();
|
|
400
|
+
this.dispatchThrow(d.data);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
beds.append("path").attr("d", arcFn);
|
|
405
|
+
}
|
|
406
|
+
renderMissRing(board, ring, segments, outerRadius, innerRadius) {
|
|
407
|
+
const missArc = (0, import_d3_shape.arc)().outerRadius(outerRadius).innerRadius(innerRadius);
|
|
408
|
+
const missBeds = board.svg.append("g").classed("c-Dartboard-miss", true).selectAll("arc").data(board.pie(addRingToSegments(ring, segments))).enter().append("g").attr(
|
|
409
|
+
"class",
|
|
410
|
+
(d) => `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} c-Dartboard-miss--${d.data.segment}`
|
|
411
|
+
).attr("role", "button").attr("tabindex", "0").attr(
|
|
412
|
+
"aria-label",
|
|
413
|
+
(d) => buildAriaLabel(d.data)
|
|
414
|
+
).on(
|
|
415
|
+
"pointerup",
|
|
416
|
+
(_event, d) => {
|
|
417
|
+
this.dispatchThrow(d.data);
|
|
418
|
+
}
|
|
419
|
+
).on(
|
|
420
|
+
"keydown",
|
|
421
|
+
(_event, d) => {
|
|
422
|
+
if (_event.key === "Enter" || _event.key === " ") {
|
|
423
|
+
_event.preventDefault();
|
|
424
|
+
this.dispatchThrow(d.data);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
);
|
|
428
|
+
missBeds.append("path").attr("d", missArc);
|
|
429
|
+
const determineRotation = (bedData) => -board.rotation + board.segmentWidth * ((bedData.position ?? 0) - 1);
|
|
430
|
+
const determineX = (d) => missArc.centroid(d)[0];
|
|
431
|
+
const determineY = (d) => missArc.centroid(d)[1];
|
|
432
|
+
missBeds.append("text").classed("c-Dartboard-missLabel", true).attr("x", (d) => determineX(d)).attr("y", (d) => determineY(d)).attr("dy", ".35em").attr(
|
|
433
|
+
"transform",
|
|
434
|
+
(d) => `rotate(${determineRotation(d.data)}, ${determineX(d)}, ${determineY(d)})`
|
|
435
|
+
).attr("text-anchor", "middle").text((d) => d.data.segment);
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
439
|
+
0 && (module.exports = {
|
|
440
|
+
DEFAULT_OPTIONS,
|
|
441
|
+
DEFAULT_RINGS,
|
|
442
|
+
DEFAULT_SEGMENTS,
|
|
443
|
+
Dartboard,
|
|
444
|
+
MOBILE_OPTIONS,
|
|
445
|
+
addRingToSegments,
|
|
446
|
+
asPercent,
|
|
447
|
+
buildThrowDetail,
|
|
448
|
+
parseBed
|
|
449
|
+
});
|
|
450
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dartboard.ts","../src/constants.ts","../src/utils.ts"],"sourcesContent":["import './dartboard.css';\nexport { Dartboard } from './dartboard';\nexport type {\n Ring,\n Rings,\n Segment,\n Bed,\n DartboardOptions,\n ThrowDetail,\n HoverDetail,\n BedTarget,\n BedInput,\n HighlightOptions,\n} from './types';\nexport { DEFAULT_OPTIONS, MOBILE_OPTIONS, DEFAULT_RINGS, DEFAULT_SEGMENTS } from './constants';\nexport { buildThrowDetail, asPercent, addRingToSegments, parseBed } from './utils';\n","import { select, type Selection } from 'd3-selection';\nimport { arc, pie, type PieArcDatum } from 'd3-shape';\nimport type {\n DartboardOptions,\n Rings,\n Ring,\n Segment,\n Bed,\n ThrowDetail,\n HoverDetail,\n BedTarget,\n BedInput,\n HighlightOptions,\n} from './types';\nimport { DEFAULT_OPTIONS, DEFAULT_RINGS, DEFAULT_SEGMENTS } from './constants';\nimport { buildThrowDetail, asPercent, addRingToSegments, parseBed } from './utils';\n\n// D3's selection generics are deeply nested and don't compose well across\n// chained calls. Using `any` for internal state avoids 100+ lines of type\n// gymnastics while keeping the public API fully typed.\n/* eslint-disable @typescript-eslint/no-explicit-any */\ninterface BoardState {\n container: HTMLElement;\n wrapper: Selection<any, any, any, any>;\n width: number;\n height: number;\n radius: number;\n rotation: number;\n segmentWidth: number;\n svg: Selection<any, any, any, any>;\n pie: ReturnType<typeof pie<Bed>>;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\ninterface SizeMap {\n miss: number;\n double: number;\n outerSingle: number;\n triple: number;\n innerSingle: number;\n singleBull: number;\n doubleBull: number;\n}\n\nfunction buildAriaLabel(bed: Bed): string {\n const detail = buildThrowDetail(bed);\n return `${detail.bed}, scores ${detail.score}`;\n}\n\nexport class Dartboard {\n private board: BoardState | null = null;\n private sizes: SizeMap | null = null;\n private rendered = false;\n private _disabled = false;\n private readonly options: DartboardOptions;\n readonly segments: Segment[];\n readonly rings: Rings;\n\n constructor(\n container: string | HTMLElement,\n options: Partial<DartboardOptions> = {},\n segments: Segment[] = DEFAULT_SEGMENTS,\n rings: Rings = DEFAULT_RINGS,\n ) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n this.segments = segments;\n this.rings = rings;\n\n const percentSum =\n this.options.missPercent +\n this.options.doublePercent +\n this.options.outerSinglePercent +\n this.options.triplePercent +\n this.options.innerSinglePercent +\n this.options.singleBullPercent +\n this.options.doubleBullPercent;\n\n if (percentSum !== 100) {\n throw new Error(\n `Dartboard: ring percentages must sum to 100 (got ${percentSum})`,\n );\n }\n\n const boardContainer =\n typeof container === 'string'\n ? document.querySelector<HTMLElement>(container)\n : container;\n\n if (!boardContainer) {\n throw new Error(`Dartboard: container not found`);\n }\n\n const width =\n this.options.size ||\n Math.min(boardContainer.offsetHeight, boardContainer.offsetWidth);\n const segmentWidth = 360 / segments.length;\n const radius = width / 2;\n const rotation = segmentWidth / -2;\n\n const wrapper = select(boardContainer)\n .append('div')\n .classed('c-Dartboard', true);\n\n const svg = wrapper\n .append('svg')\n .attr('viewBox', `0 0 ${width} ${width}`)\n .attr('role', 'group')\n .attr('aria-label', 'Dartboard')\n .append('g')\n .attr(\n 'transform',\n `translate(${radius}, ${radius}) rotate(${rotation})`,\n );\n\n const pieFn = pie<Bed>()\n .sort((a, b) => (a.position ?? 0) - (b.position ?? 0))\n .value(() => segmentWidth);\n\n this.board = {\n container: boardContainer,\n wrapper,\n width,\n height: width,\n radius,\n rotation,\n segmentWidth,\n svg,\n pie: pieFn,\n };\n\n this.sizes = {\n miss: radius * asPercent(this.options.missPercent),\n double: radius * asPercent(this.options.doublePercent),\n outerSingle: radius * asPercent(this.options.outerSinglePercent),\n triple: radius * asPercent(this.options.triplePercent),\n innerSingle: radius * asPercent(this.options.innerSinglePercent),\n singleBull: radius * asPercent(this.options.singleBullPercent),\n doubleBull: radius * asPercent(this.options.doubleBullPercent),\n };\n }\n\n render(): this {\n if (!this.board || !this.sizes) return this;\n if (this.rendered) return this;\n this.rendered = true;\n\n const { board, sizes } = this;\n\n let innerRadius = 0;\n let outerRadius = innerRadius + sizes.doubleBull;\n this.renderBeds(\n board,\n this.rings.DOUBLE_BULL,\n [{ segment: 25, color: 'Dark' }],\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.singleBull;\n this.renderBeds(\n board,\n this.rings.SINGLE_BULL,\n [{ segment: 25, color: 'Light' }],\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.innerSingle;\n this.renderBeds(\n board,\n this.rings.INNER_SINGLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.triple;\n this.renderBeds(\n board,\n this.rings.TRIPLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.outerSingle;\n this.renderBeds(\n board,\n this.rings.OUTER_SINGLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = outerRadius;\n outerRadius = innerRadius + sizes.double;\n this.renderBeds(\n board,\n this.rings.DOUBLE,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n innerRadius = board.radius - sizes.miss;\n outerRadius = board.radius;\n this.renderMissRing(\n board,\n this.rings.MISS,\n this.segments,\n outerRadius,\n innerRadius,\n );\n\n return this;\n }\n\n destroy(): void {\n if (this.board) {\n // Remove all D3 event listeners before removing from DOM\n this.board.wrapper.selectAll('.c-Dartboard-bed')\n .on('pointerup', null)\n .on('pointerenter', null)\n .on('pointerleave', null)\n .on('keydown', null);\n this.board.wrapper.remove();\n this.board = null;\n this.sizes = null;\n this.rendered = false;\n }\n }\n\n get disabled(): boolean {\n return this._disabled;\n }\n\n disable(): this {\n this._disabled = true;\n if (this.board) {\n this.board.wrapper.classed('is-disabled', true);\n }\n return this;\n }\n\n enable(): this {\n this._disabled = false;\n if (this.board) {\n this.board.wrapper.classed('is-disabled', false);\n }\n return this;\n }\n\n throwAt(target: BedInput): void {\n if (!this.board || this._disabled) return;\n\n const targets = this.resolveTargets([target]);\n if (targets.length === 0) return;\n const first = targets[0];\n\n if (!this.isValidTarget(first)) {\n throw new Error(`Dartboard: invalid throw target — segment ${first.segment} does not exist`);\n }\n\n const ring = this.rings[first.ring];\n const bed: Bed = { segment: first.segment, color: 'Dark', ring };\n const detail = buildThrowDetail(bed);\n\n this.board.container.dispatchEvent(\n new CustomEvent<ThrowDetail>('throw', { detail }),\n );\n }\n\n highlight(targets: BedInput[], options: HighlightOptions = {}): void {\n if (!this.board) return;\n const className = options.className || 'is-highlighted';\n\n for (const target of this.resolveTargets(targets)) {\n const ring = this.rings[target.ring];\n const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;\n this.board.wrapper.selectAll(selector).classed(className, true);\n }\n }\n\n unhighlight(targets: BedInput[], options: HighlightOptions = {}): void {\n if (!this.board) return;\n const className = options.className || 'is-highlighted';\n\n for (const target of this.resolveTargets(targets)) {\n const ring = this.rings[target.ring];\n const selector = `.c-Dartboard-${ring.name} .c-Dartboard-bed--${target.segment}`;\n this.board.wrapper.selectAll(selector).classed(className, false);\n }\n }\n\n reset(className = 'is-highlighted'): void {\n if (!this.board) return;\n this.board.wrapper.selectAll(`.${className}`).classed(className, false);\n }\n\n private isValidTarget(target: Required<BedTarget>): boolean {\n const isBull = target.ring === 'DOUBLE_BULL' || target.ring === 'SINGLE_BULL';\n if (isBull) {\n return target.segment === 25;\n }\n return this.segments.some((s) => s.segment === target.segment);\n }\n\n private resolveTargets(inputs: BedInput[]): Required<BedTarget>[] {\n return inputs.flatMap((input): Required<BedTarget>[] => {\n if (typeof input === 'number') {\n return parseBed(String(input), this.rings, this.segments) as Required<BedTarget>[];\n }\n if (typeof input === 'string') {\n return parseBed(input, this.rings, this.segments) as Required<BedTarget>[];\n }\n if (!input.ring) {\n return parseBed(String(input.segment), this.rings, this.segments) as Required<BedTarget>[];\n }\n return [input as Required<BedTarget>];\n });\n }\n\n private dispatchThrow(bed: Bed): void {\n if (!this.board || this._disabled) return;\n const detail = buildThrowDetail(bed);\n this.board.container.dispatchEvent(\n new CustomEvent<ThrowDetail>('throw', { detail }),\n );\n }\n\n private dispatchHover(bed: Bed, hovering: boolean): void {\n if (!this.board || this._disabled) return;\n const throwDetail = buildThrowDetail(bed);\n const detail: HoverDetail = { ...throwDetail, hovering };\n this.board.container.dispatchEvent(\n new CustomEvent<HoverDetail>('hover', { detail }),\n );\n }\n\n private renderBeds(\n board: BoardState,\n ring: Ring,\n segments: Segment[],\n outerRadius: number,\n innerRadius: number,\n ): void {\n const className = `c-Dartboard-${ring.name}`;\n const arcFn = arc<PieArcDatum<Bed>>()\n .outerRadius(outerRadius)\n .innerRadius(innerRadius);\n\n const beds = board.svg\n .append('g')\n .classed(className, true)\n .selectAll<SVGGElement, PieArcDatum<Bed>>('arc')\n .data(board.pie(addRingToSegments(ring, segments)))\n .enter()\n .append('g')\n .attr(\n 'class',\n (d: PieArcDatum<Bed>) =>\n `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} ${className}--${d.data.segment} is${d.data.color}`,\n )\n .attr('role', 'button')\n .attr('tabindex', '0')\n .attr('aria-label', (d: PieArcDatum<Bed>) =>\n buildAriaLabel(d.data),\n )\n .on(\n 'pointerup',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n this.dispatchThrow(d.data);\n },\n )\n .on(\n 'pointerenter',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n select(_event.currentTarget as Element).classed('is-hovered', true);\n this.dispatchHover(d.data, true);\n },\n )\n .on(\n 'pointerleave',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n select(_event.currentTarget as Element).classed('is-hovered', false);\n this.dispatchHover(d.data, false);\n },\n )\n .on(\n 'keydown',\n (_event: KeyboardEvent, d: PieArcDatum<Bed>) => {\n if (_event.key === 'Enter' || _event.key === ' ') {\n _event.preventDefault();\n this.dispatchThrow(d.data);\n }\n },\n );\n\n beds.append('path').attr('d', arcFn as never);\n }\n\n private renderMissRing(\n board: BoardState,\n ring: Ring,\n segments: Segment[],\n outerRadius: number,\n innerRadius: number,\n ): void {\n const missArc = arc<PieArcDatum<Bed>>()\n .outerRadius(outerRadius)\n .innerRadius(innerRadius);\n\n const missBeds = board.svg\n .append('g')\n .classed('c-Dartboard-miss', true)\n .selectAll<SVGGElement, PieArcDatum<Bed>>('arc')\n .data(board.pie(addRingToSegments(ring, segments)))\n .enter()\n .append('g')\n .attr(\n 'class',\n (d: PieArcDatum<Bed>) =>\n `c-Dartboard-bed c-Dartboard-bed--${d.data.segment} c-Dartboard-miss--${d.data.segment}`,\n )\n .attr('role', 'button')\n .attr('tabindex', '0')\n .attr('aria-label', (d: PieArcDatum<Bed>) =>\n buildAriaLabel(d.data),\n )\n .on(\n 'pointerup',\n (_event: PointerEvent, d: PieArcDatum<Bed>) => {\n this.dispatchThrow(d.data);\n },\n )\n .on(\n 'keydown',\n (_event: KeyboardEvent, d: PieArcDatum<Bed>) => {\n if (_event.key === 'Enter' || _event.key === ' ') {\n _event.preventDefault();\n this.dispatchThrow(d.data);\n }\n },\n );\n\n missBeds.append('path').attr('d', missArc as never);\n\n const determineRotation = (bedData: Bed) =>\n -board.rotation + board.segmentWidth * ((bedData.position ?? 0) - 1);\n\n const determineX = (d: PieArcDatum<Bed>) =>\n missArc.centroid(d)[0];\n\n const determineY = (d: PieArcDatum<Bed>) =>\n missArc.centroid(d)[1];\n\n missBeds\n .append('text')\n .classed('c-Dartboard-missLabel', true)\n .attr('x', (d: PieArcDatum<Bed>) => determineX(d))\n .attr('y', (d: PieArcDatum<Bed>) => determineY(d))\n .attr('dy', '.35em')\n .attr(\n 'transform',\n (d: PieArcDatum<Bed>) =>\n `rotate(${determineRotation(d.data)}, ${determineX(d)}, ${determineY(d)})`,\n )\n .attr('text-anchor', 'middle')\n .text((d: PieArcDatum<Bed>) => d.data.segment);\n }\n}\n","import type { DartboardOptions, Rings, Segment } from './types';\n\nexport const DEFAULT_OPTIONS: DartboardOptions = {\n size: null,\n missPercent: 10,\n doublePercent: 10,\n outerSinglePercent: 25,\n triplePercent: 10,\n innerSinglePercent: 30,\n singleBullPercent: 8,\n doubleBullPercent: 7,\n};\n\nexport const DEFAULT_RINGS: Rings = {\n MISS: { name: 'miss', abbr: 'M', multiplier: 0 },\n DOUBLE: { name: 'double', abbr: 'D', multiplier: 2 },\n OUTER_SINGLE: { name: 'outerSingle', abbr: 'S', multiplier: 1 },\n TRIPLE: { name: 'triple', abbr: 'T', multiplier: 3 },\n INNER_SINGLE: { name: 'innerSingle', abbr: 'S', multiplier: 1 },\n SINGLE_BULL: { name: 'singleBull', abbr: 'B', multiplier: 1 },\n DOUBLE_BULL: { name: 'doubleBull', abbr: 'DB', multiplier: 2 },\n};\n\nexport const MOBILE_OPTIONS: Partial<DartboardOptions> = {\n missPercent: 7,\n doublePercent: 14,\n outerSinglePercent: 21,\n triplePercent: 14,\n innerSinglePercent: 26,\n singleBullPercent: 9,\n doubleBullPercent: 9,\n};\n\nexport const DEFAULT_SEGMENTS: Segment[] = [\n { segment: 20, position: 1, color: 'Dark' },\n { segment: 1, position: 2, color: 'Light' },\n { segment: 18, position: 3, color: 'Dark' },\n { segment: 4, position: 4, color: 'Light' },\n { segment: 13, position: 5, color: 'Dark' },\n { segment: 6, position: 6, color: 'Light' },\n { segment: 10, position: 7, color: 'Dark' },\n { segment: 15, position: 8, color: 'Light' },\n { segment: 2, position: 9, color: 'Dark' },\n { segment: 17, position: 10, color: 'Light' },\n { segment: 3, position: 11, color: 'Dark' },\n { segment: 19, position: 12, color: 'Light' },\n { segment: 7, position: 13, color: 'Dark' },\n { segment: 16, position: 14, color: 'Light' },\n { segment: 8, position: 15, color: 'Dark' },\n { segment: 11, position: 16, color: 'Light' },\n { segment: 14, position: 17, color: 'Dark' },\n { segment: 9, position: 18, color: 'Light' },\n { segment: 12, position: 19, color: 'Dark' },\n { segment: 5, position: 20, color: 'Light' },\n];\n","import type { Ring, Rings, Segment, Bed, BedTarget, ThrowDetail } from './types';\n\nconst SCORING_RINGS: (keyof Rings)[] = [\n 'DOUBLE',\n 'TRIPLE',\n 'OUTER_SINGLE',\n 'INNER_SINGLE',\n 'SINGLE_BULL',\n 'DOUBLE_BULL',\n];\n\nexport function buildThrowDetail(bed: Bed): ThrowDetail {\n return {\n bed: bed.ring.abbr + bed.segment,\n ring: bed.ring.name,\n score: bed.segment * bed.ring.multiplier,\n };\n}\n\nexport function asPercent(n: number): number {\n return parseFloat((n / 100).toFixed(2));\n}\n\nexport function addRingToSegments(ring: Ring, segments: Segment[]): Bed[] {\n return segments.map((segment) => ({ ...segment, ring }));\n}\n\nexport function parseBed(\n bed: string,\n rings: Rings,\n segments?: Segment[],\n): BedTarget[] {\n // 'miss' keyword — target all segments in the miss ring\n if (bed.toLowerCase() === 'miss') {\n if (!segments) {\n throw new Error(\n 'parseBed: segments are required to resolve the \"miss\" keyword',\n );\n }\n return segments.map((s) => ({ segment: s.segment, ring: 'MISS' as keyof Rings }));\n }\n\n // Number-only string — target all scoring rings on that segment\n const numOnly = bed.match(/^(\\d+)$/);\n if (numOnly) {\n const segment = parseInt(numOnly[1], 10);\n return SCORING_RINGS\n .filter((key) => key in rings)\n .map((ring) => ({ segment, ring }));\n }\n\n const match = bed.match(/^([A-Za-z]+)(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid bed format: \"${bed}\"`);\n }\n\n const [, abbr, numStr] = match.map((s, i) => i === 1 ? s.toUpperCase() : s);\n const segment = parseInt(numStr, 10);\n\n const targets: BedTarget[] = [];\n for (const [key, ring] of Object.entries(rings)) {\n if (ring.abbr === abbr) {\n targets.push({ segment, ring: key as keyof Rings });\n }\n }\n\n if (targets.length === 0) {\n throw new Error(`Unknown bed abbreviation: \"${abbr}\"`);\n }\n\n return targets;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,0BAAuC;AACvC,sBAA2C;;;ACCpC,IAAM,kBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,mBAAmB;AACrB;AAEO,IAAM,gBAAuB;AAAA,EAClC,MAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,YAAY,EAAE;AAAA,EAC/C,QAAQ,EAAE,MAAM,UAAU,MAAM,KAAK,YAAY,EAAE;AAAA,EACnD,cAAc,EAAE,MAAM,eAAe,MAAM,KAAK,YAAY,EAAE;AAAA,EAC9D,QAAQ,EAAE,MAAM,UAAU,MAAM,KAAK,YAAY,EAAE;AAAA,EACnD,cAAc,EAAE,MAAM,eAAe,MAAM,KAAK,YAAY,EAAE;AAAA,EAC9D,aAAa,EAAE,MAAM,cAAc,MAAM,KAAK,YAAY,EAAE;AAAA,EAC5D,aAAa,EAAE,MAAM,cAAc,MAAM,MAAM,YAAY,EAAE;AAC/D;AAEO,IAAM,iBAA4C;AAAA,EACvD,aAAa;AAAA,EACb,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,mBAAmB;AACrB;AAEO,IAAM,mBAA8B;AAAA,EACzC,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,GAAG,OAAO,QAAQ;AAAA,EAC3C,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,OAAO;AAAA,EACzC,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,OAAO;AAAA,EAC1C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC5C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,OAAO;AAAA,EAC3C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC3C,EAAE,SAAS,IAAI,UAAU,IAAI,OAAO,OAAO;AAAA,EAC3C,EAAE,SAAS,GAAG,UAAU,IAAI,OAAO,QAAQ;AAC7C;;;ACpDA,IAAM,gBAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,iBAAiB,KAAuB;AACtD,SAAO;AAAA,IACL,KAAK,IAAI,KAAK,OAAO,IAAI;AAAA,IACzB,MAAM,IAAI,KAAK;AAAA,IACf,OAAO,IAAI,UAAU,IAAI,KAAK;AAAA,EAChC;AACF;AAEO,SAAS,UAAU,GAAmB;AAC3C,SAAO,YAAY,IAAI,KAAK,QAAQ,CAAC,CAAC;AACxC;AAEO,SAAS,kBAAkB,MAAY,UAA4B;AACxE,SAAO,SAAS,IAAI,CAAC,aAAa,EAAE,GAAG,SAAS,KAAK,EAAE;AACzD;AAEO,SAAS,SACd,KACA,OACA,UACa;AAEb,MAAI,IAAI,YAAY,MAAM,QAAQ;AAChC,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,SAAS,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,MAAM,OAAsB,EAAE;AAAA,EAClF;AAGA,QAAM,UAAU,IAAI,MAAM,SAAS;AACnC,MAAI,SAAS;AACX,UAAMA,WAAU,SAAS,QAAQ,CAAC,GAAG,EAAE;AACvC,WAAO,cACJ,OAAO,CAAC,QAAQ,OAAO,KAAK,EAC5B,IAAI,CAAC,UAAU,EAAE,SAAAA,UAAS,KAAK,EAAE;AAAA,EACtC;AAEA,QAAM,QAAQ,IAAI,MAAM,oBAAoB;AAC5C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,wBAAwB,GAAG,GAAG;AAAA,EAChD;AAEA,QAAM,CAAC,EAAE,MAAM,MAAM,IAAI,MAAM,IAAI,CAAC,GAAG,MAAM,MAAM,IAAI,EAAE,YAAY,IAAI,CAAC;AAC1E,QAAM,UAAU,SAAS,QAAQ,EAAE;AAEnC,QAAM,UAAuB,CAAC;AAC9B,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC/C,QAAI,KAAK,SAAS,MAAM;AACtB,cAAQ,KAAK,EAAE,SAAS,MAAM,IAAmB,CAAC;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,8BAA8B,IAAI,GAAG;AAAA,EACvD;AAEA,SAAO;AACT;;;AF3BA,SAAS,eAAe,KAAkB;AACxC,QAAM,SAAS,iBAAiB,GAAG;AACnC,SAAO,GAAG,OAAO,GAAG,YAAY,OAAO,KAAK;AAC9C;AAEO,IAAM,YAAN,MAAgB;AAAA,EASrB,YACE,WACA,UAAqC,CAAC,GACtC,WAAsB,kBACtB,QAAe,eACf;AAbF,SAAQ,QAA2B;AACnC,SAAQ,QAAwB;AAChC,SAAQ,WAAW;AACnB,SAAQ,YAAY;AAWlB,SAAK,UAAU,EAAE,GAAG,iBAAiB,GAAG,QAAQ;AAChD,SAAK,WAAW;AAChB,SAAK,QAAQ;AAEb,UAAM,aACJ,KAAK,QAAQ,cACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,qBACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,qBACb,KAAK,QAAQ,oBACb,KAAK,QAAQ;AAEf,QAAI,eAAe,KAAK;AACtB,YAAM,IAAI;AAAA,QACR,oDAAoD,UAAU;AAAA,MAChE;AAAA,IACF;AAEA,UAAM,iBACJ,OAAO,cAAc,WACjB,SAAS,cAA2B,SAAS,IAC7C;AAEN,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AAEA,UAAM,QACJ,KAAK,QAAQ,QACb,KAAK,IAAI,eAAe,cAAc,eAAe,WAAW;AAClE,UAAM,eAAe,MAAM,SAAS;AACpC,UAAM,SAAS,QAAQ;AACvB,UAAM,WAAW,eAAe;AAEhC,UAAM,cAAU,4BAAO,cAAc,EAClC,OAAO,KAAK,EACZ,QAAQ,eAAe,IAAI;AAE9B,UAAM,MAAM,QACT,OAAO,KAAK,EACZ,KAAK,WAAW,OAAO,KAAK,IAAI,KAAK,EAAE,EACvC,KAAK,QAAQ,OAAO,EACpB,KAAK,cAAc,WAAW,EAC9B,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,aAAa,MAAM,KAAK,MAAM,YAAY,QAAQ;AAAA,IACpD;AAEF,UAAM,YAAQ,qBAAS,EACpB,KAAK,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,EAAE,EACpD,MAAM,MAAM,YAAY;AAE3B,SAAK,QAAQ;AAAA,MACX,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IACP;AAEA,SAAK,QAAQ;AAAA,MACX,MAAM,SAAS,UAAU,KAAK,QAAQ,WAAW;AAAA,MACjD,QAAQ,SAAS,UAAU,KAAK,QAAQ,aAAa;AAAA,MACrD,aAAa,SAAS,UAAU,KAAK,QAAQ,kBAAkB;AAAA,MAC/D,QAAQ,SAAS,UAAU,KAAK,QAAQ,aAAa;AAAA,MACrD,aAAa,SAAS,UAAU,KAAK,QAAQ,kBAAkB;AAAA,MAC/D,YAAY,SAAS,UAAU,KAAK,QAAQ,iBAAiB;AAAA,MAC7D,YAAY,SAAS,UAAU,KAAK,QAAQ,iBAAiB;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,SAAe;AACb,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,MAAO,QAAO;AACvC,QAAI,KAAK,SAAU,QAAO;AAC1B,SAAK,WAAW;AAEhB,UAAM,EAAE,OAAO,MAAM,IAAI;AAEzB,QAAI,cAAc;AAClB,QAAI,cAAc,cAAc,MAAM;AACtC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,CAAC,EAAE,SAAS,IAAI,OAAO,OAAO,CAAC;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,CAAC,EAAE,SAAS,IAAI,OAAO,QAAQ,CAAC;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc;AACd,kBAAc,cAAc,MAAM;AAClC,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,kBAAc,MAAM,SAAS,MAAM;AACnC,kBAAc,MAAM;AACpB,SAAK;AAAA,MACH;AAAA,MACA,KAAK,MAAM;AAAA,MACX,KAAK;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,OAAO;AAEd,WAAK,MAAM,QAAQ,UAAU,kBAAkB,EAC5C,GAAG,aAAa,IAAI,EACpB,GAAG,gBAAgB,IAAI,EACvB,GAAG,gBAAgB,IAAI,EACvB,GAAG,WAAW,IAAI;AACrB,WAAK,MAAM,QAAQ,OAAO;AAC1B,WAAK,QAAQ;AACb,WAAK,QAAQ;AACb,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,YAAY;AACjB,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,QAAQ,QAAQ,eAAe,IAAI;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAe;AACb,SAAK,YAAY;AACjB,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,QAAQ,QAAQ,eAAe,KAAK;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,QAAwB;AAC9B,QAAI,CAAC,KAAK,SAAS,KAAK,UAAW;AAEnC,UAAM,UAAU,KAAK,eAAe,CAAC,MAAM,CAAC;AAC5C,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,QAAQ,QAAQ,CAAC;AAEvB,QAAI,CAAC,KAAK,cAAc,KAAK,GAAG;AAC9B,YAAM,IAAI,MAAM,kDAA6C,MAAM,OAAO,iBAAiB;AAAA,IAC7F;AAEA,UAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAClC,UAAM,MAAW,EAAE,SAAS,MAAM,SAAS,OAAO,QAAQ,KAAK;AAC/D,UAAM,SAAS,iBAAiB,GAAG;AAEnC,SAAK,MAAM,UAAU;AAAA,MACnB,IAAI,YAAyB,SAAS,EAAE,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,UAAU,SAAqB,UAA4B,CAAC,GAAS;AACnE,QAAI,CAAC,KAAK,MAAO;AACjB,UAAM,YAAY,QAAQ,aAAa;AAEvC,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,YAAM,OAAO,KAAK,MAAM,OAAO,IAAI;AACnC,YAAM,WAAW,gBAAgB,KAAK,IAAI,sBAAsB,OAAO,OAAO;AAC9E,WAAK,MAAM,QAAQ,UAAU,QAAQ,EAAE,QAAQ,WAAW,IAAI;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,YAAY,SAAqB,UAA4B,CAAC,GAAS;AACrE,QAAI,CAAC,KAAK,MAAO;AACjB,UAAM,YAAY,QAAQ,aAAa;AAEvC,eAAW,UAAU,KAAK,eAAe,OAAO,GAAG;AACjD,YAAM,OAAO,KAAK,MAAM,OAAO,IAAI;AACnC,YAAM,WAAW,gBAAgB,KAAK,IAAI,sBAAsB,OAAO,OAAO;AAC9E,WAAK,MAAM,QAAQ,UAAU,QAAQ,EAAE,QAAQ,WAAW,KAAK;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,kBAAwB;AACxC,QAAI,CAAC,KAAK,MAAO;AACjB,SAAK,MAAM,QAAQ,UAAU,IAAI,SAAS,EAAE,EAAE,QAAQ,WAAW,KAAK;AAAA,EACxE;AAAA,EAEQ,cAAc,QAAsC;AAC1D,UAAM,SAAS,OAAO,SAAS,iBAAiB,OAAO,SAAS;AAChE,QAAI,QAAQ;AACV,aAAO,OAAO,YAAY;AAAA,IAC5B;AACA,WAAO,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,OAAO;AAAA,EAC/D;AAAA,EAEQ,eAAe,QAA2C;AAChE,WAAO,OAAO,QAAQ,CAAC,UAAiC;AACtD,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO,SAAS,OAAO,KAAK,GAAG,KAAK,OAAO,KAAK,QAAQ;AAAA,MAC1D;AACA,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO,SAAS,OAAO,KAAK,OAAO,KAAK,QAAQ;AAAA,MAClD;AACA,UAAI,CAAC,MAAM,MAAM;AACf,eAAO,SAAS,OAAO,MAAM,OAAO,GAAG,KAAK,OAAO,KAAK,QAAQ;AAAA,MAClE;AACA,aAAO,CAAC,KAA4B;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEQ,cAAc,KAAgB;AACpC,QAAI,CAAC,KAAK,SAAS,KAAK,UAAW;AACnC,UAAM,SAAS,iBAAiB,GAAG;AACnC,SAAK,MAAM,UAAU;AAAA,MACnB,IAAI,YAAyB,SAAS,EAAE,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,cAAc,KAAU,UAAyB;AACvD,QAAI,CAAC,KAAK,SAAS,KAAK,UAAW;AACnC,UAAM,cAAc,iBAAiB,GAAG;AACxC,UAAM,SAAsB,EAAE,GAAG,aAAa,SAAS;AACvD,SAAK,MAAM,UAAU;AAAA,MACnB,IAAI,YAAyB,SAAS,EAAE,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAAA,EAEQ,WACN,OACA,MACA,UACA,aACA,aACM;AACN,UAAM,YAAY,eAAe,KAAK,IAAI;AAC1C,UAAM,YAAQ,qBAAsB,EACjC,YAAY,WAAW,EACvB,YAAY,WAAW;AAE1B,UAAM,OAAO,MAAM,IAChB,OAAO,GAAG,EACV,QAAQ,WAAW,IAAI,EACvB,UAAyC,KAAK,EAC9C,KAAK,MAAM,IAAI,kBAAkB,MAAM,QAAQ,CAAC,CAAC,EACjD,MAAM,EACN,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,CAAC,MACC,oCAAoC,EAAE,KAAK,OAAO,IAAI,SAAS,KAAK,EAAE,KAAK,OAAO,MAAM,EAAE,KAAK,KAAK;AAAA,IACxG,EACC,KAAK,QAAQ,QAAQ,EACrB,KAAK,YAAY,GAAG,EACpB;AAAA,MAAK;AAAA,MAAc,CAAC,MACnB,eAAe,EAAE,IAAI;AAAA,IACvB,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,aAAK,cAAc,EAAE,IAAI;AAAA,MAC3B;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,wCAAO,OAAO,aAAwB,EAAE,QAAQ,cAAc,IAAI;AAClE,aAAK,cAAc,EAAE,MAAM,IAAI;AAAA,MACjC;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,wCAAO,OAAO,aAAwB,EAAE,QAAQ,cAAc,KAAK;AACnE,aAAK,cAAc,EAAE,MAAM,KAAK;AAAA,MAClC;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAuB,MAAwB;AAC9C,YAAI,OAAO,QAAQ,WAAW,OAAO,QAAQ,KAAK;AAChD,iBAAO,eAAe;AACtB,eAAK,cAAc,EAAE,IAAI;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEF,SAAK,OAAO,MAAM,EAAE,KAAK,KAAK,KAAc;AAAA,EAC9C;AAAA,EAEQ,eACN,OACA,MACA,UACA,aACA,aACM;AACN,UAAM,cAAU,qBAAsB,EACnC,YAAY,WAAW,EACvB,YAAY,WAAW;AAE1B,UAAM,WAAW,MAAM,IACpB,OAAO,GAAG,EACV,QAAQ,oBAAoB,IAAI,EAChC,UAAyC,KAAK,EAC9C,KAAK,MAAM,IAAI,kBAAkB,MAAM,QAAQ,CAAC,CAAC,EACjD,MAAM,EACN,OAAO,GAAG,EACV;AAAA,MACC;AAAA,MACA,CAAC,MACC,oCAAoC,EAAE,KAAK,OAAO,sBAAsB,EAAE,KAAK,OAAO;AAAA,IAC1F,EACC,KAAK,QAAQ,QAAQ,EACrB,KAAK,YAAY,GAAG,EACpB;AAAA,MAAK;AAAA,MAAc,CAAC,MACnB,eAAe,EAAE,IAAI;AAAA,IACvB,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAsB,MAAwB;AAC7C,aAAK,cAAc,EAAE,IAAI;AAAA,MAC3B;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA,CAAC,QAAuB,MAAwB;AAC9C,YAAI,OAAO,QAAQ,WAAW,OAAO,QAAQ,KAAK;AAChD,iBAAO,eAAe;AACtB,eAAK,cAAc,EAAE,IAAI;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEF,aAAS,OAAO,MAAM,EAAE,KAAK,KAAK,OAAgB;AAElD,UAAM,oBAAoB,CAAC,YACzB,CAAC,MAAM,WAAW,MAAM,iBAAiB,QAAQ,YAAY,KAAK;AAEpE,UAAM,aAAa,CAAC,MAClB,QAAQ,SAAS,CAAC,EAAE,CAAC;AAEvB,UAAM,aAAa,CAAC,MAClB,QAAQ,SAAS,CAAC,EAAE,CAAC;AAEvB,aACG,OAAO,MAAM,EACb,QAAQ,yBAAyB,IAAI,EACrC,KAAK,KAAK,CAAC,MAAwB,WAAW,CAAC,CAAC,EAChD,KAAK,KAAK,CAAC,MAAwB,WAAW,CAAC,CAAC,EAChD,KAAK,MAAM,OAAO,EAClB;AAAA,MACC;AAAA,MACA,CAAC,MACC,UAAU,kBAAkB,EAAE,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC;AAAA,IAC3E,EACC,KAAK,eAAe,QAAQ,EAC5B,KAAK,CAAC,MAAwB,EAAE,KAAK,OAAO;AAAA,EACjD;AACF;","names":["segment"]}
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* src/dartboard.css */
|
|
2
|
+
.c-Dartboard {
|
|
3
|
+
--dartboard-dark: #1a1a1a;
|
|
4
|
+
--dartboard-light: #f5f5dc;
|
|
5
|
+
--dartboard-scoring-dark: #e32636;
|
|
6
|
+
--dartboard-scoring-light: #228b22;
|
|
7
|
+
--dartboard-miss: #000;
|
|
8
|
+
--dartboard-miss-label: #fff;
|
|
9
|
+
--dartboard-stroke: silver;
|
|
10
|
+
--dartboard-stroke-width: 2px;
|
|
11
|
+
--dartboard-highlight-color: #ffd700;
|
|
12
|
+
--dartboard-good: #228b22;
|
|
13
|
+
--dartboard-bad: #e32636;
|
|
14
|
+
--dartboard-neutral: #4a6fa5;
|
|
15
|
+
stroke: var(--dartboard-stroke);
|
|
16
|
+
stroke-width: var(--dartboard-stroke-width);
|
|
17
|
+
touch-action: none;
|
|
18
|
+
}
|
|
19
|
+
.c-Dartboard svg {
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: auto;
|
|
22
|
+
display: block;
|
|
23
|
+
}
|
|
24
|
+
.c-Dartboard-miss {
|
|
25
|
+
fill: var(--dartboard-miss);
|
|
26
|
+
}
|
|
27
|
+
.c-Dartboard-missLabel {
|
|
28
|
+
font-family: sans-serif;
|
|
29
|
+
fill: var(--dartboard-miss-label);
|
|
30
|
+
stroke-width: 0;
|
|
31
|
+
}
|
|
32
|
+
.c-Dartboard-bed.isDark {
|
|
33
|
+
fill: var(--dartboard-dark);
|
|
34
|
+
}
|
|
35
|
+
.c-Dartboard-bed.isLight {
|
|
36
|
+
fill: var(--dartboard-light);
|
|
37
|
+
}
|
|
38
|
+
.c-Dartboard-double .c-Dartboard-bed.isDark,
|
|
39
|
+
.c-Dartboard-triple .c-Dartboard-bed.isDark,
|
|
40
|
+
.c-Dartboard-doubleBull .c-Dartboard-bed.isDark,
|
|
41
|
+
.c-Dartboard-singleBull .c-Dartboard-bed.isDark {
|
|
42
|
+
fill: var(--dartboard-scoring-dark);
|
|
43
|
+
}
|
|
44
|
+
.c-Dartboard-double .c-Dartboard-bed.isLight,
|
|
45
|
+
.c-Dartboard-triple .c-Dartboard-bed.isLight,
|
|
46
|
+
.c-Dartboard-doubleBull .c-Dartboard-bed.isLight,
|
|
47
|
+
.c-Dartboard-singleBull .c-Dartboard-bed.isLight {
|
|
48
|
+
fill: var(--dartboard-scoring-light);
|
|
49
|
+
}
|
|
50
|
+
.c-Dartboard-bed.is-hovered,
|
|
51
|
+
.c-Dartboard-miss .c-Dartboard-bed:hover {
|
|
52
|
+
fill-opacity: 0.6;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
}
|
|
55
|
+
.c-Dartboard-bed.is-highlighted,
|
|
56
|
+
.c-Dartboard .c-Dartboard-bed.is-highlighted.isDark,
|
|
57
|
+
.c-Dartboard .c-Dartboard-bed.is-highlighted.isLight {
|
|
58
|
+
fill: var(--dartboard-highlight-color);
|
|
59
|
+
stroke: #fff;
|
|
60
|
+
stroke-width: 3px;
|
|
61
|
+
animation: dartboard-pulse 0.6s ease-in-out infinite alternate;
|
|
62
|
+
}
|
|
63
|
+
@keyframes dartboard-pulse {
|
|
64
|
+
from {
|
|
65
|
+
fill-opacity: 0.5;
|
|
66
|
+
}
|
|
67
|
+
to {
|
|
68
|
+
fill-opacity: 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
.c-Dartboard .c-Dartboard-bed.is-good.isDark,
|
|
72
|
+
.c-Dartboard .c-Dartboard-bed.is-good.isLight {
|
|
73
|
+
fill: var(--dartboard-good);
|
|
74
|
+
}
|
|
75
|
+
.c-Dartboard .c-Dartboard-bed.is-bad.isDark,
|
|
76
|
+
.c-Dartboard .c-Dartboard-bed.is-bad.isLight {
|
|
77
|
+
fill: var(--dartboard-bad);
|
|
78
|
+
}
|
|
79
|
+
.c-Dartboard .c-Dartboard-bed.is-neutral.isDark,
|
|
80
|
+
.c-Dartboard .c-Dartboard-bed.is-neutral.isLight {
|
|
81
|
+
fill: var(--dartboard-neutral);
|
|
82
|
+
}
|
|
83
|
+
.c-Dartboard-bed:focus-visible {
|
|
84
|
+
outline: 2px solid var(--dartboard-highlight-color);
|
|
85
|
+
outline-offset: -2px;
|
|
86
|
+
}
|
|
87
|
+
.c-Dartboard.is-disabled {
|
|
88
|
+
pointer-events: none;
|
|
89
|
+
opacity: 0.5;
|
|
90
|
+
}
|
|
91
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dartboard.css"],"sourcesContent":[".c-Dartboard {\n --dartboard-dark: #1a1a1a;\n --dartboard-light: #f5f5dc;\n --dartboard-scoring-dark: #e32636;\n --dartboard-scoring-light: #228b22;\n --dartboard-miss: #000;\n --dartboard-miss-label: #fff;\n --dartboard-stroke: silver;\n --dartboard-stroke-width: 2px;\n --dartboard-highlight-color: #ffd700;\n --dartboard-good: #228b22;\n --dartboard-bad: #e32636;\n --dartboard-neutral: #4a6fa5;\n\n stroke: var(--dartboard-stroke);\n stroke-width: var(--dartboard-stroke-width);\n touch-action: none;\n}\n\n.c-Dartboard svg {\n width: 100%;\n height: auto;\n display: block;\n}\n\n.c-Dartboard-miss {\n fill: var(--dartboard-miss);\n}\n\n.c-Dartboard-missLabel {\n font-family: sans-serif;\n fill: var(--dartboard-miss-label);\n stroke-width: 0;\n}\n\n.c-Dartboard-bed.isDark {\n fill: var(--dartboard-dark);\n}\n\n.c-Dartboard-bed.isLight {\n fill: var(--dartboard-light);\n}\n\n.c-Dartboard-double .c-Dartboard-bed.isDark,\n.c-Dartboard-triple .c-Dartboard-bed.isDark,\n.c-Dartboard-doubleBull .c-Dartboard-bed.isDark,\n.c-Dartboard-singleBull .c-Dartboard-bed.isDark {\n fill: var(--dartboard-scoring-dark);\n}\n\n.c-Dartboard-double .c-Dartboard-bed.isLight,\n.c-Dartboard-triple .c-Dartboard-bed.isLight,\n.c-Dartboard-doubleBull .c-Dartboard-bed.isLight,\n.c-Dartboard-singleBull .c-Dartboard-bed.isLight {\n fill: var(--dartboard-scoring-light);\n}\n\n.c-Dartboard-bed.is-hovered,\n.c-Dartboard-miss .c-Dartboard-bed:hover {\n fill-opacity: 0.6;\n cursor: pointer;\n}\n\n.c-Dartboard-bed.is-highlighted,\n.c-Dartboard .c-Dartboard-bed.is-highlighted.isDark,\n.c-Dartboard .c-Dartboard-bed.is-highlighted.isLight {\n fill: var(--dartboard-highlight-color);\n stroke: #fff;\n stroke-width: 3px;\n animation: dartboard-pulse 0.6s ease-in-out infinite alternate;\n}\n\n@keyframes dartboard-pulse {\n from {\n fill-opacity: 0.5;\n }\n to {\n fill-opacity: 1;\n }\n}\n\n.c-Dartboard .c-Dartboard-bed.is-good.isDark,\n.c-Dartboard .c-Dartboard-bed.is-good.isLight {\n fill: var(--dartboard-good);\n}\n\n.c-Dartboard .c-Dartboard-bed.is-bad.isDark,\n.c-Dartboard .c-Dartboard-bed.is-bad.isLight {\n fill: var(--dartboard-bad);\n}\n\n.c-Dartboard .c-Dartboard-bed.is-neutral.isDark,\n.c-Dartboard .c-Dartboard-bed.is-neutral.isLight {\n fill: var(--dartboard-neutral);\n}\n\n.c-Dartboard-bed:focus-visible {\n outline: 2px solid var(--dartboard-highlight-color);\n outline-offset: -2px;\n}\n\n.c-Dartboard.is-disabled {\n pointer-events: none;\n opacity: 0.5;\n}\n"],"mappings":";AAAA,CAAC;AACC,oBAAkB;AAClB,qBAAmB;AACnB,4BAA0B;AAC1B,6BAA2B;AAC3B,oBAAkB;AAClB,0BAAwB;AACxB,sBAAoB;AACpB,4BAA0B;AAC1B,+BAA6B;AAC7B,oBAAkB;AAClB,mBAAiB;AACjB,uBAAqB;AAErB,UAAQ,IAAI;AACZ,gBAAc,IAAI;AAClB,gBAAc;AAChB;AAEA,CAnBC,YAmBY;AACX,SAAO;AACP,UAAQ;AACR,WAAS;AACX;AAEA,CAAC;AACC,QAAM,IAAI;AACZ;AAEA,CAAC;AACC,eAAa;AACb,QAAM,IAAI;AACV,gBAAc;AAChB;AAEA,CAAC,eAAe,CAAC;AACf,QAAM,IAAI;AACZ;AAEA,CAJC,eAIe,CAAC;AACf,QAAM,IAAI;AACZ;AAEA,CAAC,mBAAmB,CARnB,eAQmC,CARnB;AASjB,CAAC,mBAAmB,CATnB,eASmC,CATnB;AAUjB,CAAC,uBAAuB,CAVvB,eAUuC,CAVvB;AAWjB,CAAC,uBAAuB,CAXvB,eAWuC,CAXvB;AAYf,QAAM,IAAI;AACZ;AAEA,CAPC,mBAOmB,CAfnB,eAemC,CAXnB;AAYjB,CAPC,mBAOmB,CAhBnB,eAgBmC,CAZnB;AAajB,CAPC,uBAOuB,CAjBvB,eAiBuC,CAbvB;AAcjB,CAPC,uBAOuB,CAlBvB,eAkBuC,CAdvB;AAef,QAAM,IAAI;AACZ;AAEA,CAtBC,eAsBe,CAAC;AACjB,CAjCC,iBAiCiB,CAvBjB,eAuBiC;AAChC,gBAAc;AACd,UAAQ;AACV;AAEA,CA5BC,eA4Be,CAAC;AACjB,CAhEC,YAgEY,CA7BZ,eA6B4B,CADZ,cAC2B,CA7B3B;AA8BjB,CAjEC,YAiEY,CA9BZ,eA8B4B,CAFZ,cAE2B,CA1B3B;AA2Bf,QAAM,IAAI;AACV,UAAQ;AACR,gBAAc;AACd,aAAW,gBAAgB,KAAK,YAAY,SAAS;AACvD;AAEA,WAHa;AAIX;AACE,kBAAc;AAChB;AACA;AACE,kBAAc;AAChB;AACF;AAEA,CAjFC,YAiFY,CA9CZ,eA8C4B,CAAC,OAAO,CA9CpB;AA+CjB,CAlFC,YAkFY,CA/CZ,eA+C4B,CADC,OACO,CA3CpB;AA4Cf,QAAM,IAAI;AACZ;AAEA,CAtFC,YAsFY,CAnDZ,eAmD4B,CAAC,MAAM,CAnDnB;AAoDjB,CAvFC,YAuFY,CApDZ,eAoD4B,CADC,MACM,CAhDnB;AAiDf,QAAM,IAAI;AACZ;AAEA,CA3FC,YA2FY,CAxDZ,eAwD4B,CAAC,UAAU,CAxDvB;AAyDjB,CA5FC,YA4FY,CAzDZ,eAyD4B,CADC,UACU,CArDvB;AAsDf,QAAM,IAAI;AACZ;AAEA,CA7DC,eA6De;AACd,WAAS,IAAI,MAAM,IAAI;AACvB,kBAAgB;AAClB;AAEA,CArGC,WAqGW,CAAC;AACX,kBAAgB;AAChB,WAAS;AACX;","names":[]}
|