badgecraft 0.3.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.
Files changed (73) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +406 -0
  4. package/cli/index.mjs +143 -0
  5. package/cli/render.d.ts +20 -0
  6. package/cli/render.mjs +87 -0
  7. package/cli/studio.mjs +98 -0
  8. package/dist/badge-B-g_9WFj.d.ts +79 -0
  9. package/dist/badge-CCjUxNIG.d.cts +79 -0
  10. package/dist/chunk-3OMN635U.js +44 -0
  11. package/dist/chunk-3OMN635U.js.map +1 -0
  12. package/dist/chunk-BRT5S5PF.cjs +3418 -0
  13. package/dist/chunk-BRT5S5PF.cjs.map +1 -0
  14. package/dist/chunk-EBDSIGZR.cjs +48 -0
  15. package/dist/chunk-EBDSIGZR.cjs.map +1 -0
  16. package/dist/chunk-RRYBMB25.js +3410 -0
  17. package/dist/chunk-RRYBMB25.js.map +1 -0
  18. package/dist/cli-browser.js +526 -0
  19. package/dist/element.cjs +176 -0
  20. package/dist/element.cjs.map +1 -0
  21. package/dist/element.d.cts +31 -0
  22. package/dist/element.d.ts +31 -0
  23. package/dist/element.js +174 -0
  24. package/dist/element.js.map +1 -0
  25. package/dist/index.cjs +47 -0
  26. package/dist/index.cjs.map +1 -0
  27. package/dist/index.d.cts +58 -0
  28. package/dist/index.d.ts +58 -0
  29. package/dist/index.js +17 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/react.cjs +60 -0
  32. package/dist/react.cjs.map +1 -0
  33. package/dist/react.d.cts +29 -0
  34. package/dist/react.d.ts +29 -0
  35. package/dist/react.js +55 -0
  36. package/dist/react.js.map +1 -0
  37. package/dist/studio/assets/badge-9Zq6e9Ht.js +524 -0
  38. package/dist/studio/assets/base-ItCYnbux.css +1 -0
  39. package/dist/studio/assets/base-LFa9cTPp.js +1 -0
  40. package/dist/studio/assets/element-CCTxyf61.js +1 -0
  41. package/dist/studio/assets/index-BVuSTaz-.css +1 -0
  42. package/dist/studio/assets/index-CTTcx2pV.js +28 -0
  43. package/dist/studio/assets/option-keys-CKi71y0n.js +1 -0
  44. package/dist/studio/assets/react-Cq5Erey2.js +9 -0
  45. package/dist/studio/assets/react-DyJFYpWJ.js +1 -0
  46. package/dist/studio/assets/studio-C6plMNOe.css +1 -0
  47. package/dist/studio/assets/studio-DBcSY6tV.js +1 -0
  48. package/dist/studio/assets/style-C2sJ2Xy3.css +1 -0
  49. package/dist/studio/assets/vue-BpGwr3iF.js +1 -0
  50. package/dist/studio/element.html +31 -0
  51. package/dist/studio/env/studio.hdr +5 -0
  52. package/dist/studio/index.html +24 -0
  53. package/dist/studio/logos/apple.svg +1 -0
  54. package/dist/studio/logos/atlassian.svg +1 -0
  55. package/dist/studio/logos/google.svg +1 -0
  56. package/dist/studio/logos/meta.svg +1 -0
  57. package/dist/studio/react.html +16 -0
  58. package/dist/studio/studio.html +27 -0
  59. package/dist/studio/vue.html +15 -0
  60. package/dist/types-CHM3-ZZV.d.cts +204 -0
  61. package/dist/types-CHM3-ZZV.d.ts +204 -0
  62. package/dist/vue.cjs +93 -0
  63. package/dist/vue.cjs.map +1 -0
  64. package/dist/vue.d.cts +115 -0
  65. package/dist/vue.d.ts +115 -0
  66. package/dist/vue.js +87 -0
  67. package/dist/vue.js.map +1 -0
  68. package/docs/cli.md +146 -0
  69. package/docs/gallery.jpg +0 -0
  70. package/docs/performance.md +151 -0
  71. package/docs/render-quality.md +220 -0
  72. package/docs/studio.jpg +0 -0
  73. package/package.json +163 -0
@@ -0,0 +1,176 @@
1
+ 'use strict';
2
+
3
+ var chunkBRT5S5PF_cjs = require('./chunk-BRT5S5PF.cjs');
4
+
5
+ // src/element/index.ts
6
+ var text = (v) => v;
7
+ var number = (v) => v.trim() === "" ? void 0 : Number(v);
8
+ var numberOrAuto = (v) => v === "auto" ? "auto" : number(v);
9
+ var boolean = (v) => v !== "false" && v !== "0";
10
+ var json = (v) => {
11
+ try {
12
+ return JSON.parse(v);
13
+ } catch {
14
+ return void 0;
15
+ }
16
+ };
17
+ var nameOrJson = (v) => v.trim().startsWith("{") ? json(v) : v;
18
+ var attributes = {
19
+ src: ["svg", text],
20
+ mode: ["mode", text],
21
+ metal: ["metal", nameOrJson],
22
+ enamel: ["enamel", nameOrJson],
23
+ base: ["base", nameOrJson],
24
+ accent: ["accent", nameOrJson],
25
+ color: ["color", text],
26
+ frame: ["frame", nameOrJson],
27
+ rim: ["rim", number],
28
+ outline: ["outline", numberOrAuto],
29
+ "fill-holes": ["fillHoles", boolean],
30
+ relief: ["relief", json],
31
+ environment: ["environment", nameOrJson],
32
+ "environment-rotation": ["environmentRotation", number],
33
+ exposure: ["exposure", number],
34
+ "tone-mapping": ["toneMapping", text],
35
+ interaction: ["interaction", text],
36
+ "tilt-max": ["tiltMax", number],
37
+ pose: ["pose", json],
38
+ idle: ["idle", text],
39
+ locked: ["locked", boolean],
40
+ "locked-color": ["lockedColor", text],
41
+ shadow: ["shadow", number],
42
+ quality: ["quality", numberOrAuto],
43
+ padding: ["padding", number]
44
+ };
45
+ function createElementClass() {
46
+ return class BadgecraftElementImpl extends HTMLElement {
47
+ constructor() {
48
+ super();
49
+ this.badge = null;
50
+ this.extra = {};
51
+ this.generatedLabel = null;
52
+ this.ready = new Promise((resolve, reject) => {
53
+ this.readyResolve = resolve;
54
+ this.readyReject = reject;
55
+ });
56
+ const root = this.attachShadow({ mode: "open" });
57
+ const style = document.createElement("style");
58
+ style.textContent = ":host{display:inline-block;position:relative;width:160px;height:160px}:host([hidden]){display:none}div{width:100%;height:100%}";
59
+ this.container = document.createElement("div");
60
+ this.container.setAttribute("part", "badge");
61
+ root.append(style, this.container);
62
+ this.mutations = new MutationObserver(() => this.sync());
63
+ this.ready.catch(() => {
64
+ });
65
+ }
66
+ static get observedAttributes() {
67
+ return [...Object.keys(attributes), "alt"];
68
+ }
69
+ get options() {
70
+ return this.extra;
71
+ }
72
+ set options(value) {
73
+ this.extra = { ...value };
74
+ this.sync();
75
+ }
76
+ connectedCallback() {
77
+ if (Object.prototype.hasOwnProperty.call(this, "options")) {
78
+ const value = this.options;
79
+ delete this.options;
80
+ this.extra = { ...value };
81
+ }
82
+ if (!this.hasAttribute("role")) this.setAttribute("role", "img");
83
+ this.mutations.observe(this, { childList: true, subtree: true, characterData: true, attributes: true });
84
+ if (!this.badge) {
85
+ const options = this.collect();
86
+ if (options) this.badge = new chunkBRT5S5PF_cjs.Badgecraft(this.container, options);
87
+ }
88
+ }
89
+ disconnectedCallback() {
90
+ this.mutations.disconnect();
91
+ queueMicrotask(() => {
92
+ if (!this.isConnected && this.badge) {
93
+ this.badge.destroy();
94
+ this.badge = null;
95
+ }
96
+ });
97
+ }
98
+ attributeChangedCallback() {
99
+ this.sync();
100
+ }
101
+ spin(turns) {
102
+ this.badge?.spin(turns);
103
+ }
104
+ glint() {
105
+ this.badge?.glint();
106
+ }
107
+ toDataURL(type, quality) {
108
+ return this.badge?.toDataURL(type, quality) ?? "";
109
+ }
110
+ toBlob(type, quality) {
111
+ return this.badge?.toBlob(type, quality) ?? Promise.resolve(null);
112
+ }
113
+ sync() {
114
+ if (!this.isConnected) return;
115
+ const options = this.collect();
116
+ if (!options) {
117
+ this.badge?.destroy();
118
+ this.badge = null;
119
+ return;
120
+ }
121
+ if (this.badge) this.badge.setOptions(options);
122
+ else this.badge = new chunkBRT5S5PF_cjs.Badgecraft(this.container, options);
123
+ }
124
+ collect() {
125
+ const label = this.getAttribute("alt");
126
+ const current = this.getAttribute("aria-label");
127
+ if (current === null || current === this.generatedLabel) {
128
+ if (label !== current) {
129
+ if (label === null) this.removeAttribute("aria-label");
130
+ else this.setAttribute("aria-label", label);
131
+ }
132
+ this.generatedLabel = label;
133
+ }
134
+ const out = {};
135
+ for (const [attr, [key, parse]] of Object.entries(attributes)) {
136
+ const value = this.getAttribute(attr);
137
+ if (value !== null) {
138
+ const parsed = parse(value);
139
+ if (parsed !== void 0 && !(typeof parsed === "number" && Number.isNaN(parsed))) out[key] = parsed;
140
+ }
141
+ }
142
+ Object.assign(out, this.extra);
143
+ if (out.svg === void 0) {
144
+ const inline = this.querySelector("svg");
145
+ const template = this.querySelector("template");
146
+ if (inline) out.svg = new XMLSerializer().serializeToString(inline);
147
+ else if (template) out.svg = template.innerHTML.trim();
148
+ }
149
+ if (out.svg === void 0) return null;
150
+ out.onReady = () => {
151
+ this.readyResolve();
152
+ this.dispatchEvent(new CustomEvent("ready"));
153
+ this.extra.onReady?.();
154
+ };
155
+ out.onError = (error) => {
156
+ this.readyReject(error);
157
+ this.dispatchEvent(new CustomEvent("error", { detail: error }));
158
+ this.extra.onError?.(error);
159
+ };
160
+ return out;
161
+ }
162
+ };
163
+ }
164
+ function defineBadgecraft(tagName = "badge-craft") {
165
+ if (typeof customElements === "undefined") return void 0;
166
+ const existing = customElements.get(tagName);
167
+ if (existing) return existing;
168
+ const ctor = createElementClass();
169
+ customElements.define(tagName, ctor);
170
+ return ctor;
171
+ }
172
+ defineBadgecraft();
173
+
174
+ exports.defineBadgecraft = defineBadgecraft;
175
+ //# sourceMappingURL=element.cjs.map
176
+ //# sourceMappingURL=element.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/element/index.ts"],"names":["Badgecraft"],"mappings":"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","file":"element.cjs","sourcesContent":["/**\n * `<badge-craft>` custom element. Works in plain HTML and any framework.\n *\n * ```html\n * <script type=\"module\">import 'badgecraft/element'</script>\n * <badge-craft src=\"/award.svg\" metal=\"gold\" frame=\"hexagon\"></badge-craft>\n * <badge-craft metal=\"silver\"><svg viewBox=\"0 0 24 24\">…</svg></badge-craft>\n * ```\n */\n\nimport { Badgecraft as Badge } from '../badge'\nimport type { BadgeOptions } from '../types'\n\nexport type * from '../types'\n\ntype Parser = (value: string) => unknown\n\nconst text: Parser = (v) => v\nconst number: Parser = (v) => (v.trim() === '' ? undefined : Number(v))\nconst numberOrAuto: Parser = (v) => (v === 'auto' ? 'auto' : number(v))\nconst boolean: Parser = (v) => v !== 'false' && v !== '0'\nconst json: Parser = (v) => {\n try {\n return JSON.parse(v)\n } catch {\n return undefined\n }\n}\n/** Preset name or inline JSON object. */\nconst nameOrJson: Parser = (v) => (v.trim().startsWith('{') ? json(v) : v)\n\nconst attributes: Record<string, [keyof BadgeOptions, Parser]> = {\n src: ['svg', text],\n mode: ['mode', text],\n metal: ['metal', nameOrJson],\n enamel: ['enamel', nameOrJson],\n base: ['base', nameOrJson],\n accent: ['accent', nameOrJson],\n color: ['color', text],\n frame: ['frame', nameOrJson],\n rim: ['rim', number],\n outline: ['outline', numberOrAuto],\n 'fill-holes': ['fillHoles', boolean],\n relief: ['relief', json],\n environment: ['environment', nameOrJson],\n 'environment-rotation': ['environmentRotation', number],\n exposure: ['exposure', number],\n 'tone-mapping': ['toneMapping', text],\n interaction: ['interaction', text],\n 'tilt-max': ['tiltMax', number],\n pose: ['pose', json],\n idle: ['idle', text],\n locked: ['locked', boolean],\n 'locked-color': ['lockedColor', text],\n shadow: ['shadow', number],\n quality: ['quality', numberOrAuto],\n padding: ['padding', number],\n}\n\nexport interface BadgecraftElement extends HTMLElement {\n /** Options set from JavaScript; merged over attributes. */\n options: Partial<BadgeOptions>\n spin(turns?: number): void\n glint(): void\n toDataURL(type?: string, quality?: number): string\n toBlob(type?: string, quality?: number): Promise<Blob | null>\n readonly ready: Promise<void>\n}\n\nfunction createElementClass(): CustomElementConstructor {\n return class BadgecraftElementImpl extends HTMLElement implements BadgecraftElement {\n static get observedAttributes() {\n return [...Object.keys(attributes), 'alt']\n }\n\n private badge: Badge | null = null\n private container: HTMLDivElement\n private extra: Partial<BadgeOptions> = {}\n private generatedLabel: string | null = null\n private mutations: MutationObserver\n private readyResolve!: () => void\n private readyReject!: (error: Error) => void\n readonly ready: Promise<void> = new Promise((resolve, reject) => {\n this.readyResolve = resolve\n this.readyReject = reject\n })\n\n constructor() {\n super()\n const root = this.attachShadow({ mode: 'open' })\n const style = document.createElement('style')\n style.textContent =\n ':host{display:inline-block;position:relative;width:160px;height:160px}:host([hidden]){display:none}div{width:100%;height:100%}'\n this.container = document.createElement('div')\n this.container.setAttribute('part', 'badge')\n root.append(style, this.container)\n // Inline <svg> children are the artwork; re-bake when they change.\n this.mutations = new MutationObserver(() => this.sync())\n this.ready.catch(() => {})\n }\n\n get options(): Partial<BadgeOptions> {\n return this.extra\n }\n\n set options(value: Partial<BadgeOptions>) {\n this.extra = { ...value }\n this.sync()\n }\n\n connectedCallback(): void {\n // `el.options = …` assigned before the element was upgraded is an own property\n // shadowing the setter; re-apply it through the setter.\n if (Object.prototype.hasOwnProperty.call(this, 'options')) {\n const value = (this as { options?: Partial<BadgeOptions> }).options\n delete (this as { options?: unknown }).options\n this.extra = { ...value }\n }\n if (!this.hasAttribute('role')) this.setAttribute('role', 'img')\n this.mutations.observe(this, { childList: true, subtree: true, characterData: true, attributes: true })\n if (!this.badge) {\n const options = this.collect()\n if (options) this.badge = new Badge(this.container, options)\n }\n }\n\n disconnectedCallback(): void {\n this.mutations.disconnect()\n // Defer so moving the element within the DOM doesn't rebuild it.\n queueMicrotask(() => {\n if (!this.isConnected && this.badge) {\n this.badge.destroy()\n this.badge = null\n }\n })\n }\n\n attributeChangedCallback(): void {\n this.sync()\n }\n\n spin(turns?: number): void {\n this.badge?.spin(turns)\n }\n\n glint(): void {\n this.badge?.glint()\n }\n\n toDataURL(type?: string, quality?: number): string {\n return this.badge?.toDataURL(type, quality) ?? ''\n }\n\n toBlob(type?: string, quality?: number): Promise<Blob | null> {\n return this.badge?.toBlob(type, quality) ?? Promise.resolve(null)\n }\n\n private sync(): void {\n if (!this.isConnected) return\n const options = this.collect()\n if (!options) {\n this.badge?.destroy()\n this.badge = null\n return\n }\n if (this.badge) this.badge.setOptions(options)\n else this.badge = new Badge(this.container, options)\n }\n\n private collect(): BadgeOptions | null {\n const label = this.getAttribute('alt')\n const current = this.getAttribute('aria-label')\n if (current === null || current === this.generatedLabel) {\n if (label !== current) {\n if (label === null) this.removeAttribute('aria-label')\n else this.setAttribute('aria-label', label)\n }\n this.generatedLabel = label\n }\n const out: Record<string, unknown> = {}\n for (const [attr, [key, parse]] of Object.entries(attributes)) {\n const value = this.getAttribute(attr)\n if (value !== null) {\n const parsed = parse(value)\n if (parsed !== undefined && !(typeof parsed === 'number' && Number.isNaN(parsed))) out[key] = parsed\n }\n }\n Object.assign(out, this.extra)\n if (out.svg === undefined) {\n const inline = this.querySelector('svg')\n const template = this.querySelector('template')\n // XML serialisation: outerHTML would emit HTML entities (e.g. &nbsp;) that XML can't parse.\n if (inline) out.svg = new XMLSerializer().serializeToString(inline)\n else if (template) out.svg = template.innerHTML.trim()\n }\n if (out.svg === undefined) return null\n out.onReady = () => {\n this.readyResolve()\n this.dispatchEvent(new CustomEvent('ready'))\n ;(this.extra.onReady as (() => void) | undefined)?.()\n }\n out.onError = (error: Error) => {\n this.readyReject(error)\n this.dispatchEvent(new CustomEvent('error', { detail: error }))\n ;(this.extra.onError as ((e: Error) => void) | undefined)?.(error)\n }\n return out as unknown as BadgeOptions\n }\n }\n}\n\n/** Register the custom element (idempotent). Returns the constructor. */\nexport function defineBadgecraft(tagName = 'badge-craft'): CustomElementConstructor | undefined {\n if (typeof customElements === 'undefined') return undefined\n const existing = customElements.get(tagName)\n if (existing) return existing\n const ctor = createElementClass()\n customElements.define(tagName, ctor)\n return ctor\n}\n\ndefineBadgecraft()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'badge-craft': BadgecraftElement\n }\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import { B as BadgeOptions } from './types-CHM3-ZZV.cjs';
2
+ export { a as BadgeMode, b as BadgecraftHandle, c as BrushDirection, E as EnvironmentInput, d as EnvironmentLight, e as EnvironmentPreset, F as FrameOptions, f as FrameShape, I as IdleAnimation, g as ImageEnvironment, h as Interaction, M as Material, i as MaterialInput, j as MaterialPreset, k as MaterialSlot, P as ProceduralEnvironment, l as ProfileShape, R as ReliefOptions, m as ReliefRole, T as ToneMapping } from './types-CHM3-ZZV.cjs';
3
+
4
+ /**
5
+ * `<badge-craft>` custom element. Works in plain HTML and any framework.
6
+ *
7
+ * ```html
8
+ * <script type="module">import 'badgecraft/element'</script>
9
+ * <badge-craft src="/award.svg" metal="gold" frame="hexagon"></badge-craft>
10
+ * <badge-craft metal="silver"><svg viewBox="0 0 24 24">…</svg></badge-craft>
11
+ * ```
12
+ */
13
+
14
+ interface BadgecraftElement extends HTMLElement {
15
+ /** Options set from JavaScript; merged over attributes. */
16
+ options: Partial<BadgeOptions>;
17
+ spin(turns?: number): void;
18
+ glint(): void;
19
+ toDataURL(type?: string, quality?: number): string;
20
+ toBlob(type?: string, quality?: number): Promise<Blob | null>;
21
+ readonly ready: Promise<void>;
22
+ }
23
+ /** Register the custom element (idempotent). Returns the constructor. */
24
+ declare function defineBadgecraft(tagName?: string): CustomElementConstructor | undefined;
25
+ declare global {
26
+ interface HTMLElementTagNameMap {
27
+ 'badge-craft': BadgecraftElement;
28
+ }
29
+ }
30
+
31
+ export { BadgeOptions, type BadgecraftElement, defineBadgecraft };
@@ -0,0 +1,31 @@
1
+ import { B as BadgeOptions } from './types-CHM3-ZZV.js';
2
+ export { a as BadgeMode, b as BadgecraftHandle, c as BrushDirection, E as EnvironmentInput, d as EnvironmentLight, e as EnvironmentPreset, F as FrameOptions, f as FrameShape, I as IdleAnimation, g as ImageEnvironment, h as Interaction, M as Material, i as MaterialInput, j as MaterialPreset, k as MaterialSlot, P as ProceduralEnvironment, l as ProfileShape, R as ReliefOptions, m as ReliefRole, T as ToneMapping } from './types-CHM3-ZZV.js';
3
+
4
+ /**
5
+ * `<badge-craft>` custom element. Works in plain HTML and any framework.
6
+ *
7
+ * ```html
8
+ * <script type="module">import 'badgecraft/element'</script>
9
+ * <badge-craft src="/award.svg" metal="gold" frame="hexagon"></badge-craft>
10
+ * <badge-craft metal="silver"><svg viewBox="0 0 24 24">…</svg></badge-craft>
11
+ * ```
12
+ */
13
+
14
+ interface BadgecraftElement extends HTMLElement {
15
+ /** Options set from JavaScript; merged over attributes. */
16
+ options: Partial<BadgeOptions>;
17
+ spin(turns?: number): void;
18
+ glint(): void;
19
+ toDataURL(type?: string, quality?: number): string;
20
+ toBlob(type?: string, quality?: number): Promise<Blob | null>;
21
+ readonly ready: Promise<void>;
22
+ }
23
+ /** Register the custom element (idempotent). Returns the constructor. */
24
+ declare function defineBadgecraft(tagName?: string): CustomElementConstructor | undefined;
25
+ declare global {
26
+ interface HTMLElementTagNameMap {
27
+ 'badge-craft': BadgecraftElement;
28
+ }
29
+ }
30
+
31
+ export { BadgeOptions, type BadgecraftElement, defineBadgecraft };
@@ -0,0 +1,174 @@
1
+ import { Badgecraft } from './chunk-RRYBMB25.js';
2
+
3
+ // src/element/index.ts
4
+ var text = (v) => v;
5
+ var number = (v) => v.trim() === "" ? void 0 : Number(v);
6
+ var numberOrAuto = (v) => v === "auto" ? "auto" : number(v);
7
+ var boolean = (v) => v !== "false" && v !== "0";
8
+ var json = (v) => {
9
+ try {
10
+ return JSON.parse(v);
11
+ } catch {
12
+ return void 0;
13
+ }
14
+ };
15
+ var nameOrJson = (v) => v.trim().startsWith("{") ? json(v) : v;
16
+ var attributes = {
17
+ src: ["svg", text],
18
+ mode: ["mode", text],
19
+ metal: ["metal", nameOrJson],
20
+ enamel: ["enamel", nameOrJson],
21
+ base: ["base", nameOrJson],
22
+ accent: ["accent", nameOrJson],
23
+ color: ["color", text],
24
+ frame: ["frame", nameOrJson],
25
+ rim: ["rim", number],
26
+ outline: ["outline", numberOrAuto],
27
+ "fill-holes": ["fillHoles", boolean],
28
+ relief: ["relief", json],
29
+ environment: ["environment", nameOrJson],
30
+ "environment-rotation": ["environmentRotation", number],
31
+ exposure: ["exposure", number],
32
+ "tone-mapping": ["toneMapping", text],
33
+ interaction: ["interaction", text],
34
+ "tilt-max": ["tiltMax", number],
35
+ pose: ["pose", json],
36
+ idle: ["idle", text],
37
+ locked: ["locked", boolean],
38
+ "locked-color": ["lockedColor", text],
39
+ shadow: ["shadow", number],
40
+ quality: ["quality", numberOrAuto],
41
+ padding: ["padding", number]
42
+ };
43
+ function createElementClass() {
44
+ return class BadgecraftElementImpl extends HTMLElement {
45
+ constructor() {
46
+ super();
47
+ this.badge = null;
48
+ this.extra = {};
49
+ this.generatedLabel = null;
50
+ this.ready = new Promise((resolve, reject) => {
51
+ this.readyResolve = resolve;
52
+ this.readyReject = reject;
53
+ });
54
+ const root = this.attachShadow({ mode: "open" });
55
+ const style = document.createElement("style");
56
+ style.textContent = ":host{display:inline-block;position:relative;width:160px;height:160px}:host([hidden]){display:none}div{width:100%;height:100%}";
57
+ this.container = document.createElement("div");
58
+ this.container.setAttribute("part", "badge");
59
+ root.append(style, this.container);
60
+ this.mutations = new MutationObserver(() => this.sync());
61
+ this.ready.catch(() => {
62
+ });
63
+ }
64
+ static get observedAttributes() {
65
+ return [...Object.keys(attributes), "alt"];
66
+ }
67
+ get options() {
68
+ return this.extra;
69
+ }
70
+ set options(value) {
71
+ this.extra = { ...value };
72
+ this.sync();
73
+ }
74
+ connectedCallback() {
75
+ if (Object.prototype.hasOwnProperty.call(this, "options")) {
76
+ const value = this.options;
77
+ delete this.options;
78
+ this.extra = { ...value };
79
+ }
80
+ if (!this.hasAttribute("role")) this.setAttribute("role", "img");
81
+ this.mutations.observe(this, { childList: true, subtree: true, characterData: true, attributes: true });
82
+ if (!this.badge) {
83
+ const options = this.collect();
84
+ if (options) this.badge = new Badgecraft(this.container, options);
85
+ }
86
+ }
87
+ disconnectedCallback() {
88
+ this.mutations.disconnect();
89
+ queueMicrotask(() => {
90
+ if (!this.isConnected && this.badge) {
91
+ this.badge.destroy();
92
+ this.badge = null;
93
+ }
94
+ });
95
+ }
96
+ attributeChangedCallback() {
97
+ this.sync();
98
+ }
99
+ spin(turns) {
100
+ this.badge?.spin(turns);
101
+ }
102
+ glint() {
103
+ this.badge?.glint();
104
+ }
105
+ toDataURL(type, quality) {
106
+ return this.badge?.toDataURL(type, quality) ?? "";
107
+ }
108
+ toBlob(type, quality) {
109
+ return this.badge?.toBlob(type, quality) ?? Promise.resolve(null);
110
+ }
111
+ sync() {
112
+ if (!this.isConnected) return;
113
+ const options = this.collect();
114
+ if (!options) {
115
+ this.badge?.destroy();
116
+ this.badge = null;
117
+ return;
118
+ }
119
+ if (this.badge) this.badge.setOptions(options);
120
+ else this.badge = new Badgecraft(this.container, options);
121
+ }
122
+ collect() {
123
+ const label = this.getAttribute("alt");
124
+ const current = this.getAttribute("aria-label");
125
+ if (current === null || current === this.generatedLabel) {
126
+ if (label !== current) {
127
+ if (label === null) this.removeAttribute("aria-label");
128
+ else this.setAttribute("aria-label", label);
129
+ }
130
+ this.generatedLabel = label;
131
+ }
132
+ const out = {};
133
+ for (const [attr, [key, parse]] of Object.entries(attributes)) {
134
+ const value = this.getAttribute(attr);
135
+ if (value !== null) {
136
+ const parsed = parse(value);
137
+ if (parsed !== void 0 && !(typeof parsed === "number" && Number.isNaN(parsed))) out[key] = parsed;
138
+ }
139
+ }
140
+ Object.assign(out, this.extra);
141
+ if (out.svg === void 0) {
142
+ const inline = this.querySelector("svg");
143
+ const template = this.querySelector("template");
144
+ if (inline) out.svg = new XMLSerializer().serializeToString(inline);
145
+ else if (template) out.svg = template.innerHTML.trim();
146
+ }
147
+ if (out.svg === void 0) return null;
148
+ out.onReady = () => {
149
+ this.readyResolve();
150
+ this.dispatchEvent(new CustomEvent("ready"));
151
+ this.extra.onReady?.();
152
+ };
153
+ out.onError = (error) => {
154
+ this.readyReject(error);
155
+ this.dispatchEvent(new CustomEvent("error", { detail: error }));
156
+ this.extra.onError?.(error);
157
+ };
158
+ return out;
159
+ }
160
+ };
161
+ }
162
+ function defineBadgecraft(tagName = "badge-craft") {
163
+ if (typeof customElements === "undefined") return void 0;
164
+ const existing = customElements.get(tagName);
165
+ if (existing) return existing;
166
+ const ctor = createElementClass();
167
+ customElements.define(tagName, ctor);
168
+ return ctor;
169
+ }
170
+ defineBadgecraft();
171
+
172
+ export { defineBadgecraft };
173
+ //# sourceMappingURL=element.js.map
174
+ //# sourceMappingURL=element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/element/index.ts"],"names":[],"mappings":"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","file":"element.js","sourcesContent":["/**\n * `<badge-craft>` custom element. Works in plain HTML and any framework.\n *\n * ```html\n * <script type=\"module\">import 'badgecraft/element'</script>\n * <badge-craft src=\"/award.svg\" metal=\"gold\" frame=\"hexagon\"></badge-craft>\n * <badge-craft metal=\"silver\"><svg viewBox=\"0 0 24 24\">…</svg></badge-craft>\n * ```\n */\n\nimport { Badgecraft as Badge } from '../badge'\nimport type { BadgeOptions } from '../types'\n\nexport type * from '../types'\n\ntype Parser = (value: string) => unknown\n\nconst text: Parser = (v) => v\nconst number: Parser = (v) => (v.trim() === '' ? undefined : Number(v))\nconst numberOrAuto: Parser = (v) => (v === 'auto' ? 'auto' : number(v))\nconst boolean: Parser = (v) => v !== 'false' && v !== '0'\nconst json: Parser = (v) => {\n try {\n return JSON.parse(v)\n } catch {\n return undefined\n }\n}\n/** Preset name or inline JSON object. */\nconst nameOrJson: Parser = (v) => (v.trim().startsWith('{') ? json(v) : v)\n\nconst attributes: Record<string, [keyof BadgeOptions, Parser]> = {\n src: ['svg', text],\n mode: ['mode', text],\n metal: ['metal', nameOrJson],\n enamel: ['enamel', nameOrJson],\n base: ['base', nameOrJson],\n accent: ['accent', nameOrJson],\n color: ['color', text],\n frame: ['frame', nameOrJson],\n rim: ['rim', number],\n outline: ['outline', numberOrAuto],\n 'fill-holes': ['fillHoles', boolean],\n relief: ['relief', json],\n environment: ['environment', nameOrJson],\n 'environment-rotation': ['environmentRotation', number],\n exposure: ['exposure', number],\n 'tone-mapping': ['toneMapping', text],\n interaction: ['interaction', text],\n 'tilt-max': ['tiltMax', number],\n pose: ['pose', json],\n idle: ['idle', text],\n locked: ['locked', boolean],\n 'locked-color': ['lockedColor', text],\n shadow: ['shadow', number],\n quality: ['quality', numberOrAuto],\n padding: ['padding', number],\n}\n\nexport interface BadgecraftElement extends HTMLElement {\n /** Options set from JavaScript; merged over attributes. */\n options: Partial<BadgeOptions>\n spin(turns?: number): void\n glint(): void\n toDataURL(type?: string, quality?: number): string\n toBlob(type?: string, quality?: number): Promise<Blob | null>\n readonly ready: Promise<void>\n}\n\nfunction createElementClass(): CustomElementConstructor {\n return class BadgecraftElementImpl extends HTMLElement implements BadgecraftElement {\n static get observedAttributes() {\n return [...Object.keys(attributes), 'alt']\n }\n\n private badge: Badge | null = null\n private container: HTMLDivElement\n private extra: Partial<BadgeOptions> = {}\n private generatedLabel: string | null = null\n private mutations: MutationObserver\n private readyResolve!: () => void\n private readyReject!: (error: Error) => void\n readonly ready: Promise<void> = new Promise((resolve, reject) => {\n this.readyResolve = resolve\n this.readyReject = reject\n })\n\n constructor() {\n super()\n const root = this.attachShadow({ mode: 'open' })\n const style = document.createElement('style')\n style.textContent =\n ':host{display:inline-block;position:relative;width:160px;height:160px}:host([hidden]){display:none}div{width:100%;height:100%}'\n this.container = document.createElement('div')\n this.container.setAttribute('part', 'badge')\n root.append(style, this.container)\n // Inline <svg> children are the artwork; re-bake when they change.\n this.mutations = new MutationObserver(() => this.sync())\n this.ready.catch(() => {})\n }\n\n get options(): Partial<BadgeOptions> {\n return this.extra\n }\n\n set options(value: Partial<BadgeOptions>) {\n this.extra = { ...value }\n this.sync()\n }\n\n connectedCallback(): void {\n // `el.options = …` assigned before the element was upgraded is an own property\n // shadowing the setter; re-apply it through the setter.\n if (Object.prototype.hasOwnProperty.call(this, 'options')) {\n const value = (this as { options?: Partial<BadgeOptions> }).options\n delete (this as { options?: unknown }).options\n this.extra = { ...value }\n }\n if (!this.hasAttribute('role')) this.setAttribute('role', 'img')\n this.mutations.observe(this, { childList: true, subtree: true, characterData: true, attributes: true })\n if (!this.badge) {\n const options = this.collect()\n if (options) this.badge = new Badge(this.container, options)\n }\n }\n\n disconnectedCallback(): void {\n this.mutations.disconnect()\n // Defer so moving the element within the DOM doesn't rebuild it.\n queueMicrotask(() => {\n if (!this.isConnected && this.badge) {\n this.badge.destroy()\n this.badge = null\n }\n })\n }\n\n attributeChangedCallback(): void {\n this.sync()\n }\n\n spin(turns?: number): void {\n this.badge?.spin(turns)\n }\n\n glint(): void {\n this.badge?.glint()\n }\n\n toDataURL(type?: string, quality?: number): string {\n return this.badge?.toDataURL(type, quality) ?? ''\n }\n\n toBlob(type?: string, quality?: number): Promise<Blob | null> {\n return this.badge?.toBlob(type, quality) ?? Promise.resolve(null)\n }\n\n private sync(): void {\n if (!this.isConnected) return\n const options = this.collect()\n if (!options) {\n this.badge?.destroy()\n this.badge = null\n return\n }\n if (this.badge) this.badge.setOptions(options)\n else this.badge = new Badge(this.container, options)\n }\n\n private collect(): BadgeOptions | null {\n const label = this.getAttribute('alt')\n const current = this.getAttribute('aria-label')\n if (current === null || current === this.generatedLabel) {\n if (label !== current) {\n if (label === null) this.removeAttribute('aria-label')\n else this.setAttribute('aria-label', label)\n }\n this.generatedLabel = label\n }\n const out: Record<string, unknown> = {}\n for (const [attr, [key, parse]] of Object.entries(attributes)) {\n const value = this.getAttribute(attr)\n if (value !== null) {\n const parsed = parse(value)\n if (parsed !== undefined && !(typeof parsed === 'number' && Number.isNaN(parsed))) out[key] = parsed\n }\n }\n Object.assign(out, this.extra)\n if (out.svg === undefined) {\n const inline = this.querySelector('svg')\n const template = this.querySelector('template')\n // XML serialisation: outerHTML would emit HTML entities (e.g. &nbsp;) that XML can't parse.\n if (inline) out.svg = new XMLSerializer().serializeToString(inline)\n else if (template) out.svg = template.innerHTML.trim()\n }\n if (out.svg === undefined) return null\n out.onReady = () => {\n this.readyResolve()\n this.dispatchEvent(new CustomEvent('ready'))\n ;(this.extra.onReady as (() => void) | undefined)?.()\n }\n out.onError = (error: Error) => {\n this.readyReject(error)\n this.dispatchEvent(new CustomEvent('error', { detail: error }))\n ;(this.extra.onError as ((e: Error) => void) | undefined)?.(error)\n }\n return out as unknown as BadgeOptions\n }\n }\n}\n\n/** Register the custom element (idempotent). Returns the constructor. */\nexport function defineBadgecraft(tagName = 'badge-craft'): CustomElementConstructor | undefined {\n if (typeof customElements === 'undefined') return undefined\n const existing = customElements.get(tagName)\n if (existing) return existing\n const ctor = createElementClass()\n customElements.define(tagName, ctor)\n return ctor\n}\n\ndefineBadgecraft()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'badge-craft': BadgecraftElement\n }\n}\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var chunkBRT5S5PF_cjs = require('./chunk-BRT5S5PF.cjs');
4
+
5
+ // src/index.ts
6
+ function isSupported() {
7
+ if (typeof document === "undefined") return false;
8
+ try {
9
+ const gl = document.createElement("canvas").getContext("webgl2");
10
+ gl?.getExtension("WEBGL_lose_context")?.loseContext();
11
+ return !!gl;
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ Object.defineProperty(exports, "Badgecraft", {
18
+ enumerable: true,
19
+ get: function () { return chunkBRT5S5PF_cjs.Badgecraft; }
20
+ });
21
+ Object.defineProperty(exports, "createBadge", {
22
+ enumerable: true,
23
+ get: function () { return chunkBRT5S5PF_cjs.createBadge; }
24
+ });
25
+ Object.defineProperty(exports, "defaults", {
26
+ enumerable: true,
27
+ get: function () { return chunkBRT5S5PF_cjs.defaults; }
28
+ });
29
+ Object.defineProperty(exports, "environments", {
30
+ enumerable: true,
31
+ get: function () { return chunkBRT5S5PF_cjs.environments; }
32
+ });
33
+ Object.defineProperty(exports, "framePaths", {
34
+ enumerable: true,
35
+ get: function () { return chunkBRT5S5PF_cjs.framePaths; }
36
+ });
37
+ Object.defineProperty(exports, "materials", {
38
+ enumerable: true,
39
+ get: function () { return chunkBRT5S5PF_cjs.materials; }
40
+ });
41
+ Object.defineProperty(exports, "resolveMaterial", {
42
+ enumerable: true,
43
+ get: function () { return chunkBRT5S5PF_cjs.resolveMaterial; }
44
+ });
45
+ exports.isSupported = isSupported;
46
+ //# sourceMappingURL=index.cjs.map
47
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAQO,SAAS,WAAA,GAAuB;AACrC,EAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,KAAA;AAC5C,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA,CAAE,WAAW,QAAQ,CAAA;AAC/D,IAAA,EAAA,EAAI,YAAA,CAAa,oBAAoB,CAAA,EAAG,WAAA,EAAY;AACpD,IAAA,OAAO,CAAC,CAAC,EAAA;AAAA,EACX,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"index.cjs","sourcesContent":["export { Badgecraft, createBadge } from './badge'\nexport { materials, resolveMaterial } from './materials'\nexport { environments } from './environment'\nexport { framePaths } from './svg/frames'\nexport { defaults } from './options'\nexport type * from './types'\n\n/** True when the browser can render badges (WebGL2). */\nexport function isSupported(): boolean {\n if (typeof document === 'undefined') return false\n try {\n const gl = document.createElement('canvas').getContext('webgl2')\n gl?.getExtension('WEBGL_lose_context')?.loseContext()\n return !!gl\n } catch {\n return false\n }\n}\n"]}
@@ -0,0 +1,58 @@
1
+ export { B as Badgecraft, c as createBadge } from './badge-CCjUxNIG.cjs';
2
+ import { j as MaterialPreset, M as Material, i as MaterialInput, k as MaterialSlot, e as EnvironmentPreset, P as ProceduralEnvironment, f as FrameShape, a as BadgeMode, T as ToneMapping, h as Interaction, I as IdleAnimation } from './types-CHM3-ZZV.cjs';
3
+ export { B as BadgeOptions, b as BadgecraftHandle, c as BrushDirection, E as EnvironmentInput, d as EnvironmentLight, F as FrameOptions, g as ImageEnvironment, l as ProfileShape, R as ReliefOptions, m as ReliefRole } from './types-CHM3-ZZV.cjs';
4
+
5
+ type ResolvedMaterial = Required<Material>;
6
+ /** Built-in materials. Metal colours are artist-tuned sRGB approximations of measured F0 values. */
7
+ declare const materials: Record<MaterialPreset, Material>;
8
+ declare function resolveMaterial(input: MaterialInput | undefined, slot: MaterialSlot): ResolvedMaterial;
9
+
10
+ /**
11
+ * Procedural HDR studio environments. Light positions are relative to the
12
+ * viewer: azimuth 0 is directly behind the camera (what a flat badge face
13
+ * reflects), elevation is degrees above the horizon.
14
+ */
15
+ declare const environments: Record<EnvironmentPreset, ProceduralEnvironment>;
16
+
17
+ /** Frame outlines in a 0..100 box. */
18
+ declare const framePaths: Record<FrameShape, string>;
19
+
20
+ declare const defaults: {
21
+ mode: BadgeMode;
22
+ color: string;
23
+ rim: number;
24
+ outline: "auto";
25
+ autoOutline: number;
26
+ fillHoles: boolean;
27
+ relief: {
28
+ depth: number;
29
+ thickness: number;
30
+ floor: number;
31
+ profile: "round";
32
+ bevel: number;
33
+ edge: number;
34
+ enamelLevel: number;
35
+ enamelDome: number;
36
+ domeWidth: number;
37
+ smoothing: number;
38
+ ao: number;
39
+ };
40
+ exposure: number;
41
+ toneMapping: ToneMapping;
42
+ interaction: Interaction;
43
+ tiltMax: number;
44
+ pose: {
45
+ pitch: number;
46
+ yaw: number;
47
+ roll: number;
48
+ };
49
+ idle: IdleAnimation;
50
+ lockedColor: string;
51
+ shadow: number;
52
+ padding: number;
53
+ };
54
+
55
+ /** True when the browser can render badges (WebGL2). */
56
+ declare function isSupported(): boolean;
57
+
58
+ export { BadgeMode, EnvironmentPreset, FrameShape, IdleAnimation, Interaction, Material, MaterialInput, MaterialPreset, MaterialSlot, ProceduralEnvironment, ToneMapping, defaults, environments, framePaths, isSupported, materials, resolveMaterial };
@@ -0,0 +1,58 @@
1
+ export { B as Badgecraft, c as createBadge } from './badge-B-g_9WFj.js';
2
+ import { j as MaterialPreset, M as Material, i as MaterialInput, k as MaterialSlot, e as EnvironmentPreset, P as ProceduralEnvironment, f as FrameShape, a as BadgeMode, T as ToneMapping, h as Interaction, I as IdleAnimation } from './types-CHM3-ZZV.js';
3
+ export { B as BadgeOptions, b as BadgecraftHandle, c as BrushDirection, E as EnvironmentInput, d as EnvironmentLight, F as FrameOptions, g as ImageEnvironment, l as ProfileShape, R as ReliefOptions, m as ReliefRole } from './types-CHM3-ZZV.js';
4
+
5
+ type ResolvedMaterial = Required<Material>;
6
+ /** Built-in materials. Metal colours are artist-tuned sRGB approximations of measured F0 values. */
7
+ declare const materials: Record<MaterialPreset, Material>;
8
+ declare function resolveMaterial(input: MaterialInput | undefined, slot: MaterialSlot): ResolvedMaterial;
9
+
10
+ /**
11
+ * Procedural HDR studio environments. Light positions are relative to the
12
+ * viewer: azimuth 0 is directly behind the camera (what a flat badge face
13
+ * reflects), elevation is degrees above the horizon.
14
+ */
15
+ declare const environments: Record<EnvironmentPreset, ProceduralEnvironment>;
16
+
17
+ /** Frame outlines in a 0..100 box. */
18
+ declare const framePaths: Record<FrameShape, string>;
19
+
20
+ declare const defaults: {
21
+ mode: BadgeMode;
22
+ color: string;
23
+ rim: number;
24
+ outline: "auto";
25
+ autoOutline: number;
26
+ fillHoles: boolean;
27
+ relief: {
28
+ depth: number;
29
+ thickness: number;
30
+ floor: number;
31
+ profile: "round";
32
+ bevel: number;
33
+ edge: number;
34
+ enamelLevel: number;
35
+ enamelDome: number;
36
+ domeWidth: number;
37
+ smoothing: number;
38
+ ao: number;
39
+ };
40
+ exposure: number;
41
+ toneMapping: ToneMapping;
42
+ interaction: Interaction;
43
+ tiltMax: number;
44
+ pose: {
45
+ pitch: number;
46
+ yaw: number;
47
+ roll: number;
48
+ };
49
+ idle: IdleAnimation;
50
+ lockedColor: string;
51
+ shadow: number;
52
+ padding: number;
53
+ };
54
+
55
+ /** True when the browser can render badges (WebGL2). */
56
+ declare function isSupported(): boolean;
57
+
58
+ export { BadgeMode, EnvironmentPreset, FrameShape, IdleAnimation, Interaction, Material, MaterialInput, MaterialPreset, MaterialSlot, ProceduralEnvironment, ToneMapping, defaults, environments, framePaths, isSupported, materials, resolveMaterial };