@mirage-engine/painter 0.4.0 → 1.0.1

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.
@@ -1,226 +1,526 @@
1
- import * as l from "three";
2
- function h(e, r, o) {
3
- const i = r.split(`
4
- `), a = [];
5
- return i.forEach((n) => {
6
- const t = n.split(" ");
7
- let c = t[0];
8
- for (let u = 1; u < t.length; u++) {
9
- const s = t[u];
10
- e.measureText(c + " " + s).width < o ? c += " " + s : (a.push(c), c = s);
11
- }
12
- a.push(c);
13
- }), a;
14
- }
15
- function m(e, r, o, i, a = 2) {
16
- const n = document.createElement("canvas"), t = n.getContext("2d");
17
- if (!t)
18
- throw new Error("[Mirage] Failed to create canvas context");
19
- const u = (window.devicePixelRatio || 1) * a;
20
- n.width = o * u, n.height = i * u, t.scale(u, u), t.font = r.font, t.fillStyle = r.color, t.textBaseline = "top", t.globalAlpha = 1;
21
- const s = h(t, e, o), v = r.lineHeight;
22
- s.forEach((B, p) => {
23
- const g = p * v + 2;
24
- let C = 0;
25
- r.textAlign === "center" ? C = o / 2 : r.textAlign === "right" && (C = o), t.textAlign = r.textAlign, t.fillText(B, C, g);
26
- });
27
- const d = new l.CanvasTexture(n);
28
- return d.colorSpace = l.SRGBColorSpace, d.minFilter = l.LinearFilter, d.magFilter = l.LinearFilter, d.needsUpdate = !0, d;
1
+ var R = Object.defineProperty;
2
+ var M = (r, e, n) => e in r ? R(r, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : r[e] = n;
3
+ var w = (r, e, n) => (M(r, typeof e != "symbol" ? e + "" : e, n), n);
4
+ import * as d from "three";
5
+ class I {
6
+ /**
7
+ * Calculates or retrieves the exact alphabetic baseline (in pixels) for the given font.
8
+ * @param font CSS font shorthand string (e.g., "400 16px Inter")
9
+ * @returns Baseline Y offset in pixels
10
+ */
11
+ static getBaseline(e) {
12
+ if (this.cache.has(e))
13
+ return this.cache.get(e);
14
+ const n = this.calculateBaselineFromDOM(e);
15
+ return this.cache.set(e, n), n;
16
+ }
17
+ static calculateBaselineFromDOM(e) {
18
+ if (typeof document > "u")
19
+ return 0;
20
+ const n = document.createElement("div"), a = document.createElement("span"), o = document.createElement("img");
21
+ n.style.visibility = "hidden", n.style.position = "absolute", n.style.top = "0px", n.style.left = "0px", n.style.font = e, n.style.margin = "0", n.style.padding = "0", n.style.border = "none", a.style.margin = "0", a.style.padding = "0", a.style.border = "none", a.style.lineHeight = "normal", o.width = 1, o.height = 1, o.style.verticalAlign = "baseline", a.appendChild(document.createTextNode("Hidden Text")), n.appendChild(a), n.appendChild(o), document.body.appendChild(n);
22
+ const i = o.offsetTop - a.offsetTop;
23
+ return document.body.removeChild(n), i;
24
+ }
29
25
  }
30
- function f(e) {
31
- return typeof e == "number" ? e : parseFloat(e) || 0;
26
+ w(I, "cache", /* @__PURE__ */ new Map());
27
+ class k extends d.MeshBasicMaterial {
28
+ constructor(n, a, o, i, t = 2) {
29
+ super({
30
+ transparent: !0,
31
+ side: d.FrontSide,
32
+ color: 16777215
33
+ });
34
+ w(this, "canvas");
35
+ w(this, "ctx");
36
+ w(this, "qualityFactor");
37
+ if (this.canvas = document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), !this.ctx)
38
+ throw new Error("[Mirage] Failed to create canvas context");
39
+ this.qualityFactor = t, this.map = new d.CanvasTexture(this.canvas), this.map.colorSpace = d.LinearSRGBColorSpace, this.map.minFilter = d.LinearFilter, this.map.magFilter = d.LinearFilter, this.updateText(n, a, o, i);
40
+ }
41
+ wrapText(n, a) {
42
+ const o = n.split(`
43
+ `), i = [];
44
+ return o.forEach((t) => {
45
+ const c = t.match(/[^\s\-]+\-?|\-|\s+/g) || [];
46
+ if (c.length === 0) {
47
+ i.push("");
48
+ return;
49
+ }
50
+ let s = c[0];
51
+ for (let l = 1; l < c.length; l++) {
52
+ const u = c[l];
53
+ this.ctx.measureText(s + u).width <= a + 2 ? s += u : (s && i.push(s), s = u.trimStart());
54
+ }
55
+ s && i.push(s);
56
+ }), i;
57
+ }
58
+ updateText(n, a, o, i, t) {
59
+ t !== void 0 && (this.qualityFactor = t);
60
+ const s = (window.devicePixelRatio || 1) * this.qualityFactor, l = o * s, u = i * s;
61
+ this.canvas.width !== l || this.canvas.height !== u ? (this.canvas.width = l, this.canvas.height = u) : this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height), this.ctx.setTransform(s, 0, 0, s, 0, 0), this.ctx.font = a.font, this.ctx.fillStyle = a.color, this.ctx.textBaseline = "alphabetic", this.ctx.globalAlpha = 1;
62
+ const p = this.wrapText(n, o), b = a.lineHeight, v = I.getBaseline(a.font);
63
+ p.forEach((f, m) => {
64
+ const S = m * b + v;
65
+ let C = 0;
66
+ a.textAlign === "center" ? C = o / 2 : a.textAlign === "right" && (C = o), this.ctx.textAlign = a.textAlign, this.ctx.fillText(f, C, S);
67
+ }), this.map && (this.map.needsUpdate = !0);
68
+ }
69
+ dispose() {
70
+ this.map && this.map.dispose(), super.dispose();
71
+ }
32
72
  }
33
- function b(e, r) {
34
- if (!r) {
35
- e.set(0, 0, 0, 0);
36
- return;
73
+ function x(r) {
74
+ return typeof r == "number" ? r : parseFloat(r) || 0;
75
+ }
76
+ function y(r) {
77
+ if (!r || r === "transparent")
78
+ return { color: new d.Color(16777215), alpha: 0 };
79
+ const e = r.match(
80
+ /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
81
+ );
82
+ if (e) {
83
+ const n = parseInt(e[1], 10), a = parseInt(e[2], 10), o = parseInt(e[3], 10), i = e[4] !== void 0 ? parseFloat(e[4]) : 1;
84
+ return { color: new d.Color(`rgb(${n}, ${a}, ${o})`), alpha: i };
37
85
  }
38
- const o = r.split("/")[0].trim().split(/\s+/), i = f(o[0]), a = f(o[1] ?? o[0]), n = f(o[2] ?? o[0]), t = f(o[3] ?? o[1] ?? o[0]);
39
- e.set(i, a, n, t);
40
- }
41
- const O = (
42
- /* glsl */
43
- `
44
- varying vec2 vUv;
45
- varying vec4 vScreenPos;
46
- void main() {
47
- vUv = uv;
48
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
49
- vScreenPos = gl_Position;
50
- }
51
- `
52
- ), T = (
53
- /* glsl */
54
- `
55
-
56
- varying vec2 vUv;
57
-
58
- uniform vec2 uSize;
59
- uniform vec4 uBorderRadius;
60
- uniform float uBorderWidth;
61
- uniform vec3 uBgColor;
62
- uniform vec3 uBorderColor;
63
- uniform float uOpacity;
64
- uniform float uBgOpacity;
65
- uniform float uBorderOpacity;
86
+ return { color: new d.Color(r), alpha: 1 };
87
+ }
88
+ function P(r) {
89
+ const e = [];
90
+ let n = "", a = 0;
91
+ for (let o = 0; o < r.length; o++) {
92
+ const i = r[o];
93
+ if (i === "(")
94
+ a++;
95
+ else if (i === ")")
96
+ a--;
97
+ else if (i === "," && a === 0) {
98
+ e.push(n.trim()), n = "";
99
+ continue;
100
+ }
101
+ n += i;
102
+ }
103
+ return n && e.push(n.trim()), e;
104
+ }
105
+ function G(r) {
106
+ if (!r || typeof r != "string" || !r.includes("linear-gradient"))
107
+ return null;
108
+ const e = r.match(/linear-gradient\((.*)\)/);
109
+ if (!e)
110
+ return null;
111
+ const n = e[1], a = P(n);
112
+ let o = Math.PI, i = 0;
113
+ const t = a[0].trim();
114
+ if (t.startsWith("to "))
115
+ t === "to top" ? o = 0 : t === "to right" ? o = Math.PI / 2 : t === "to bottom" ? o = Math.PI : t === "to left" ? o = Math.PI * 1.5 : t === "to top right" || t === "to right top" ? o = Math.PI / 4 : t === "to bottom right" || t === "to right bottom" ? o = Math.PI * 0.75 : t === "to bottom left" || t === "to left bottom" ? o = Math.PI * 1.25 : (t === "to top left" || t === "to left top") && (o = Math.PI * 1.75), i = 1;
116
+ else if (t.endsWith("deg") || t.endsWith("rad") || t.endsWith("turn")) {
117
+ const s = parseFloat(t);
118
+ t.endsWith("deg") ? o = s * (Math.PI / 180) : t.endsWith("rad") ? o = s : t.endsWith("turn") && (o = s * Math.PI * 2), i = 1;
119
+ }
120
+ const c = [];
121
+ for (let s = i; s < a.length && !(c.length >= 8); s++) {
122
+ const l = a[s].trim(), u = l.lastIndexOf(" ");
123
+ let p = l, b = null;
124
+ if (u !== -1 && !l.endsWith(")")) {
125
+ const f = l.substring(u + 1);
126
+ (f.endsWith("%") || f.endsWith("px") || !isNaN(parseFloat(f))) && (p = l.substring(0, u).trim(), b = f);
127
+ }
128
+ const v = y(p);
129
+ c.push({
130
+ color: v.color,
131
+ alpha: v.alpha,
132
+ rawStop: b,
133
+ stop: 0
134
+ });
135
+ }
136
+ if (c.length > 0) {
137
+ for (let l = 0; l < c.length; l++)
138
+ c[l].rawStop !== null && (c[l].stop = parseFloat(c[l].rawStop) / 100);
139
+ c[0].rawStop === null && (c[0].stop = 0), c.length > 1 && c[c.length - 1].rawStop === null && (c[c.length - 1].stop = 1);
140
+ let s = 0;
141
+ for (let l = 1; l < c.length; l++)
142
+ if (c[l].rawStop !== null || l === c.length - 1) {
143
+ const u = l - s;
144
+ if (u > 1) {
145
+ const p = c[s].stop, v = (c[l].stop - p) / u;
146
+ for (let f = 1; f < u; f++)
147
+ c[s + f].stop = p + v * f;
148
+ }
149
+ s = l;
150
+ }
151
+ }
152
+ return { angle: o, stops: c };
153
+ }
154
+ const E = `varying vec2 vUv;
155
+ varying vec4 vScreenPos;
156
+ void main() {
157
+ vUv = uv;
158
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
159
+ vScreenPos = gl_Position;
160
+ }`, L = `varying vec2 vUv;
161
+ uniform vec2 uSize;
162
+ uniform vec4 uBorderRadius;
163
+ uniform float uBorderWidth;
164
+ uniform vec4 uBgColor;
165
+ uniform vec4 uBorderColor;
166
+ uniform float uOpacity;
66
167
 
67
- #INJECT_DECLARATIONS
168
+ uniform int uGradientCount;
169
+ uniform float uGradientAngle;
170
+ uniform vec4 uGradientColors[8];
171
+ uniform float uGradientStops[8];
68
172
 
69
- float sdRoundedBox(vec2 p, vec2 b, float r) {
70
- vec2 q = abs(p) - b + r;
173
+ #INJECT_DECLARATIONS
71
174
 
72
- return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
73
- }
175
+ vec3 linearToSrgb(vec3 linearColor) {
176
+ vec3 linearPart = 12.92 * linearColor;
177
+ vec3 curvePart = 1.055 * pow(linearColor, vec3(1.0 / 2.4)) - 0.055;
178
+ vec3 switchCondition = step(vec3(0.0031308), linearColor);
179
+ return mix(linearPart, curvePart, switchCondition);
180
+ }
181
+
182
+ vec3 srgbToLinear(vec3 srgbColor) {
183
+ vec3 linearPart = srgbColor / 12.92;
184
+ vec3 curvePart = pow((srgbColor + vec3(0.055)) / 1.055, vec3(2.4));
185
+ vec3 switchCondition = step(vec3(0.04045), srgbColor);
186
+ return mix(linearPart, curvePart, switchCondition);
187
+ }
188
+
189
+ vec4 blendSrcOverInLinear(vec4 front, vec4 back) {
190
+ front.rgb = srgbToLinear(front.rgb);
191
+ back.rgb = srgbToLinear(back.rgb);
192
+ float aOut = front.a + back.a * (1.0 - front.a);
193
+ float safeAlpha = max(aOut, 0.0001);
194
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
195
+ return vec4(linearToSrgb(cOut), aOut);
196
+ }
197
+
198
+ vec4 blendSrcOver(vec4 front, vec4 back) {
199
+ float aOut = front.a + back.a * (1.0 - front.a);
200
+ float safeAlpha = max(aOut, 0.0001);
201
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
202
+ return vec4(cOut, aOut);
203
+ }
204
+
205
+ float sdRoundedBox(vec2 p, vec2 b, float r) {
206
+ vec2 q = abs(p) - b + r;
207
+ return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
208
+ }
209
+
210
+ float sdVisualBox(vec2 p, vec2 b, float r) {
211
+ vec2 q = abs(p) - b + r;
212
+ float n = 2.01;
213
+ float d = pow(pow(max(q.x, 0.0), n) + pow(max(q.y, 0.0), n), 1.0/n) - r;
214
+ return min(max(q.x, q.y), 0.0) + d;
215
+ }
74
216
 
75
- void main() {
76
- vec2 p = (vUv - 0.5) * uSize;
77
- vec2 halfSize = uSize * 0.5;
217
+ vec4 calculateGradientLayer(vec2 uv) {
218
+ if (uGradientCount < 2) return uGradientColors[0];
78
219
 
79
- #INJECT_UV_MODIFIER
220
+ vec2 dir = vec2(sin(uGradientAngle), cos(uGradientAngle));
221
+ vec2 p = (uv - 0.5) * uSize;
222
+ float proj = dot(p, dir);
223
+ float L = abs(uSize.x * dir.x) + abs(uSize.y * dir.y);
224
+ float t = clamp((proj / L) + 0.5, 0.0, 1.0);
225
+
226
+ vec4 color = uGradientColors[0];
227
+ for (int i = 1; i < 8; i++) {
228
+ if (i >= uGradientCount) break;
229
+ float prevStop = uGradientStops[i-1];
230
+ float currStop = uGradientStops[i];
80
231
 
81
- // color decision pipeline
82
- vec4 baseColor = vec4(uBgColor, uBgOpacity);
232
+ float factor = clamp((t - prevStop) / (currStop - prevStop + 0.00001), 0.0, 1.0);
233
+ color = mix(color, uGradientColors[i], factor);
234
+ }
235
+ // return vec4(linearToSrgb(color.rgb), color.a);
236
+ return vec4(color);
237
+ }
83
238
 
84
- #INJECT_BASE_COLOR
239
+ void main() {
240
+ vec2 p = (vUv - 0.5) * uSize;
241
+ vec2 halfSize = uSize * 0.5;
85
242
 
86
- // sdf shape pipeline
87
- vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
88
- float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
89
- float d = sdRoundedBox(p, halfSize, r);
243
+ #INJECT_UV_MODIFIER
90
244
 
91
- float aa = 1.0;
92
- float bgMask = 1.0 - smoothstep(0.0, aa, d);
245
+ // color decision pipeline
246
+ vec4 baseColor = vec4(uBgColor.rgb, uBgColor.a);
93
247
 
94
- float halfBorder = uBorderWidth * 0.5;
95
- float borderD = abs(d + halfBorder) - halfBorder;
96
- float borderAlpha = (1.0 - smoothstep(0.0, aa, borderD)) * uBorderOpacity;
97
- if (uBorderWidth <= 0.01) {
98
- borderAlpha = 0.0;
99
- }
248
+ if (uGradientCount > 0) {
249
+ vec4 gradColor = calculateGradientLayer(vUv);
250
+ baseColor = blendSrcOver(gradColor, baseColor);
251
+ }
100
252
 
101
- // final blending (border + background)
102
- float aFront = borderAlpha;
103
- float aBack = baseColor.a;
104
- float aOut = aFront + aBack * (1.0 - aFront);
253
+ #INJECT_BASE_COLOR
105
254
 
106
- float safeAlpha = max(aOut, 0.0001);
107
- vec3 cOut = (uBorderColor * aFront + baseColor.rgb * aBack * (1.0 - aFront)) / safeAlpha;
108
- vec4 finalColor = vec4(cOut, aOut);
255
+ // Hybrid SDF
256
+ vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
257
+ float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
258
+ r = min(r, min(halfSize.x, halfSize.y));
109
259
 
110
- // final color control (Tint, Noise)
111
- #INJECT_COLOR_MODIFIER
260
+ float d = sdRoundedBox(p, halfSize, r);
112
261
 
113
- float finalOpacity = finalColor.a * bgMask * uOpacity;
114
- if (finalOpacity < 0.001) discard;
262
+ float d_smooth = sdVisualBox(p, halfSize, r);
263
+ float d_visual = d_smooth / fwidth(d_smooth);
115
264
 
116
- gl_FragColor = vec4(finalColor.rgb, finalOpacity);
265
+ // rendering pipeline
266
+ float bgMask = 1.0 - smoothstep(-0.5, 0.5, d_visual);
117
267
 
118
- #include <colorspace_fragment>
268
+ float halfBorder = uBorderWidth * 0.5;
269
+ float borderD = abs(d + halfBorder) - halfBorder;
270
+ float borderAlpha = (1.0 - smoothstep(0.0, 1.0, borderD)) * uBorderColor.a;
271
+ if (uBorderWidth <= 0.01) {
272
+ borderAlpha = 0.0;
119
273
  }
120
- `
121
- );
122
- function x(e) {
123
- if (!e || e === "transparent")
124
- return { color: new l.Color(16777215), alpha: 0 };
125
- const r = e.match(
126
- /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
127
- );
128
- if (r) {
129
- const o = parseInt(r[1], 10), i = parseInt(r[2], 10), a = parseInt(r[3], 10), n = r[4] !== void 0 ? parseFloat(r[4]) : 1;
130
- return { color: new l.Color(`rgb(${o}, ${i}, ${a})`), alpha: n };
131
- }
132
- return { color: new l.Color(e), alpha: 1 };
133
- }
134
- function R(e, r, o, i = null, a) {
135
- const n = i !== null, t = n ? (
136
- /* glsl */
137
- `
138
- uniform sampler2D uTexture;
139
- varying vec4 vScreenPos;
140
- `
141
- ) : "", c = n ? (
142
- /* glsl */
143
- `
144
- vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
145
- vec2 resultUv = screenUv;
146
- ${(a == null ? void 0 : a.uvModifier) || ""}
147
- `
148
- ) : "", u = n ? (
149
- /* glsl */
150
- `
151
- baseColor = texture2D(uTexture, resultUv);
152
- `
153
- ) : "", s = (a == null ? void 0 : a.colorModifier) || "", v = T.replace("#INJECT_DECLARATIONS", t).replace("#INJECT_UV_MODIFIER", c).replace("#INJECT_BASE_COLOR", u).replace("#INJECT_COLOR_MODIFIER", s), d = x(e.backgroundColor), B = x(e.borderColor), p = {
154
- uSize: { value: new l.Vector2(r, o) },
155
- uBorderRadius: { value: new l.Vector4(0, 0, 0, 0) },
156
- uBorderWidth: { value: f(e.borderWidth) },
157
- uBgColor: { value: d.color },
158
- uBorderColor: { value: B.color },
159
- uOpacity: { value: e.opacity ?? 1 },
160
- uBgOpacity: { value: d.alpha },
161
- uBorderOpacity: { value: B.alpha },
162
- uTexture: { value: null }
274
+
275
+ // final blending (border + background) using blendSrcOver
276
+ vec4 borderLayer = vec4(uBorderColor.rgb, borderAlpha);
277
+ vec4 finalColor = blendSrcOver(borderLayer, baseColor);
278
+ // final color control (Tint, Noise)
279
+ #INJECT_COLOR_MODIFIER
280
+
281
+ float finalOpacity = finalColor.a * bgMask * uOpacity;
282
+ if (finalOpacity < 0.001) discard;
283
+
284
+ gl_FragColor = vec4(finalColor.rgb, finalOpacity);
285
+
286
+
287
+ // #include <colorspace_fragment>
288
+ }
289
+ `, F = `uniform sampler2D uTexture;
290
+ varying vec4 vScreenPos;
291
+ uniform vec2 uTextureRepeat;
292
+ uniform vec2 uTextureOffset;`, _ = `vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
293
+ vec2 resultUv = screenUv;
294
+
295
+ `, W = `vec4 texColor = texture2D(uTexture, resultUv);
296
+ baseColor = blendSrcOver(baseColor, texColor);`, O = {
297
+ vertexShader: E,
298
+ fragmentShader: L
299
+ }, B = {
300
+ declChunk: F,
301
+ uvChunk: _,
302
+ baseColorChunk: W
303
+ };
304
+ function U(r, e, n, a = null, o) {
305
+ const i = a !== null || !!r.imageSrc;
306
+ let t = "";
307
+ const c = {};
308
+ if (o != null && o.uniforms)
309
+ for (const [h, g] of Object.entries(o.uniforms))
310
+ typeof g == "number" ? (t += `uniform float ${h};
311
+ `, c[h] = { value: g }) : Array.isArray(g) ? g.length === 2 ? (t += `uniform vec2 ${h};
312
+ `, c[h] = { value: new d.Vector2(...g) }) : g.length === 3 ? (t += `uniform vec3 ${h};
313
+ `, c[h] = { value: new d.Vector3(...g) }) : g.length === 4 && (t += `uniform vec4 ${h};
314
+ `, c[h] = { value: new d.Vector4(...g) }) : (t += `uniform float ${h};
315
+ `, c[h] = { value: g });
316
+ const s = (i ? B.declChunk : "") + `
317
+ ` + t, l = r.isTraveler ? B.uvChunk : `vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
318
+ `, u = i ? l + ((o == null ? void 0 : o.uvModifier) || "") : "", p = i ? B.baseColorChunk : "", b = (o == null ? void 0 : o.colorModifier) || "", v = O.fragmentShader.replace("#INJECT_DECLARATIONS", s).replace("#INJECT_UV_MODIFIER", u).replace("#INJECT_BASE_COLOR", p).replace("#INJECT_COLOR_MODIFIER", b), f = y(r.backgroundColor), m = y(r.borderColor), S = {
319
+ uSize: { value: new d.Vector2(e, n) },
320
+ uBgColor: {
321
+ value: new d.Vector4(
322
+ f.color.r,
323
+ f.color.g,
324
+ f.color.b,
325
+ f.alpha
326
+ )
327
+ },
328
+ uBorderColor: {
329
+ value: new d.Vector4(
330
+ m.color.r,
331
+ m.color.g,
332
+ m.color.b,
333
+ m.alpha
334
+ )
335
+ },
336
+ uBorderRadius: { value: new d.Vector4(0, 0, 0, 0) },
337
+ uBorderWidth: { value: x(r.borderWidth) },
338
+ uOpacity: { value: r.opacity ?? 1 },
339
+ uTexture: { value: null },
340
+ uTextureRepeat: { value: new d.Vector2(1, 1) },
341
+ uTextureOffset: { value: new d.Vector2(0, 0) },
342
+ uGradientCount: { value: 0 },
343
+ uGradientAngle: { value: 0 },
344
+ uGradientColors: {
345
+ value: Array.from({ length: 8 }, () => new d.Vector4(0, 0, 0, 0))
346
+ },
347
+ uGradientStops: { value: new Float32Array(8) }
163
348
  };
164
- return b(p.uBorderRadius.value, e.borderRadius), n && (p.uTexture.value = i), new l.ShaderMaterial({
165
- uniforms: p,
166
- vertexShader: O,
349
+ A(S.uBorderRadius.value, r.borderRadius), i && (S.uTexture.value = a);
350
+ const C = new d.ShaderMaterial({
351
+ uniforms: { ...S, ...c },
352
+ vertexShader: O.vertexShader,
167
353
  fragmentShader: v,
168
354
  transparent: !0,
169
- side: l.FrontSide
355
+ side: d.FrontSide
170
356
  // for better performance
171
357
  });
358
+ return r.backgroundImage && T(C, { backgroundImage: r.backgroundImage }), C;
359
+ }
360
+ function V(r, e, n, a, o) {
361
+ const i = x(e.borderWidth);
362
+ T(r, {
363
+ width: n,
364
+ height: a,
365
+ borderRadius: e.borderRadius,
366
+ borderWidth: i,
367
+ backgroundColor: e.backgroundColor,
368
+ borderColor: e.borderColor,
369
+ opacity: e.opacity,
370
+ texture: o,
371
+ backgroundImage: e.backgroundImage
372
+ });
172
373
  }
173
- function E(e, r, o, i, a) {
174
- const n = x(r.backgroundColor), t = x(r.borderColor);
175
- e.uniforms.uSize.value.set(o, i), b(e.uniforms.uBorderRadius.value, r.borderRadius), e.uniforms.uBorderWidth.value = f(r.borderWidth), e.uniforms.uBgColor.value.copy(n.color), e.uniforms.uBorderColor.value.copy(t.color), e.uniforms.uOpacity.value = r.opacity ?? 1, e.uniforms.uBgOpacity.value = n.alpha, e.uniforms.uBorderOpacity.value = t.alpha, e.uniforms.uTexture && a !== void 0 && (e.uniforms.uTexture.value = a);
176
- }
177
- const S = {
178
- create(e, r, o, i, a, n = 2, t = null, c) {
179
- if (e === "BOX")
180
- return R(r, i, a, t, c);
181
- if (e === "TEXT") {
182
- const u = m(
183
- o || "",
184
- r,
185
- i,
186
- a,
187
- n
374
+ function T(r, e) {
375
+ var a;
376
+ if (e.width !== void 0 && e.height !== void 0 && r.uniforms.uSize.value.set(e.width, e.height), e.borderRadius !== void 0 && A(r.uniforms.uBorderRadius.value, e.borderRadius), e.borderWidth !== void 0 && (r.uniforms.uBorderWidth.value = e.borderWidth), e.backgroundColor !== void 0)
377
+ if (Array.isArray(e.backgroundColor)) {
378
+ const o = r.uniforms.uBgColor.value.w;
379
+ r.uniforms.uBgColor.value.set(
380
+ e.backgroundColor[0],
381
+ e.backgroundColor[1],
382
+ e.backgroundColor[2],
383
+ o
384
+ );
385
+ } else if (typeof e.backgroundColor == "string") {
386
+ const o = y(e.backgroundColor);
387
+ r.uniforms.uBgColor.value.set(
388
+ o.color.r,
389
+ o.color.g,
390
+ o.color.b,
391
+ o.alpha
392
+ );
393
+ } else {
394
+ const o = r.uniforms.uBgColor.value.w;
395
+ r.uniforms.uBgColor.value.set(
396
+ e.backgroundColor.r,
397
+ e.backgroundColor.g,
398
+ e.backgroundColor.b,
399
+ o
188
400
  );
189
- return new l.MeshBasicMaterial({
190
- map: u,
191
- transparent: !0,
192
- side: l.FrontSide,
193
- color: 16777215
194
- });
195
401
  }
196
- return new l.MeshBasicMaterial({ visible: !1 });
197
- },
198
- update(e, r, o, i, a, n, t = 2, c) {
199
- if (r === "BOX")
200
- E(
201
- e,
202
- o,
203
- a,
204
- n,
205
- c
402
+ if (e.borderColor !== void 0)
403
+ if (Array.isArray(e.borderColor)) {
404
+ const o = r.uniforms.uBorderColor.value.w;
405
+ r.uniforms.uBorderColor.value.set(
406
+ e.borderColor[0],
407
+ e.borderColor[1],
408
+ e.borderColor[2],
409
+ o
410
+ );
411
+ } else if (typeof e.borderColor == "string") {
412
+ const o = y(e.borderColor);
413
+ r.uniforms.uBorderColor.value.set(
414
+ o.color.r,
415
+ o.color.g,
416
+ o.color.b,
417
+ o.alpha
206
418
  );
207
- else if (r === "TEXT") {
208
- const u = e;
209
- u.map && u.map.dispose();
210
- const s = m(
211
- i || "",
212
- o,
213
- a,
214
- n,
215
- t
419
+ } else {
420
+ const o = r.uniforms.uBorderColor.value.w;
421
+ r.uniforms.uBorderColor.value.set(
422
+ e.borderColor.r,
423
+ e.borderColor.g,
424
+ e.borderColor.b,
425
+ o
216
426
  );
217
- u.map = s, u.needsUpdate = !0;
218
427
  }
428
+ e.opacity !== void 0 && (r.uniforms.uOpacity.value = e.opacity), e.bgOpacity !== void 0 && (r.uniforms.uBgColor.value.w = e.bgOpacity), e.borderOpacity !== void 0 && (r.uniforms.uBorderColor.value.w = e.borderOpacity), r.uniforms.uTexture && e.texture !== void 0 && (r.uniforms.uTexture.value = e.texture);
429
+ const n = e.texture !== void 0 ? e.texture : (a = r.uniforms.uTexture) == null ? void 0 : a.value;
430
+ if (n && (n.image instanceof ImageBitmap || n.image instanceof HTMLImageElement || n.image instanceof HTMLCanvasElement)) {
431
+ const o = n.image.width, i = n.image.height, t = e.width ?? r.uniforms.uSize.value.x, c = e.height ?? r.uniforms.uSize.value.y;
432
+ if (o && i && t && c) {
433
+ const s = o / i, l = t / c;
434
+ if (s > l) {
435
+ const u = l / s;
436
+ r.uniforms.uTextureRepeat.value.set(u, 1), r.uniforms.uTextureOffset.value.set((1 - u) / 2, 0);
437
+ } else {
438
+ const u = s / l;
439
+ r.uniforms.uTextureRepeat.value.set(1, u), r.uniforms.uTextureOffset.value.set(0, (1 - u) / 2);
440
+ }
441
+ }
442
+ } else
443
+ r.uniforms.uTextureRepeat && (r.uniforms.uTextureRepeat.value.set(1, 1), r.uniforms.uTextureOffset.value.set(0, 0));
444
+ if (e.backgroundImage !== void 0) {
445
+ const o = G(e.backgroundImage);
446
+ if (o) {
447
+ r.uniforms.uGradientCount.value = o.stops.length, r.uniforms.uGradientAngle.value = o.angle;
448
+ for (let i = 0; i < 8; i++)
449
+ if (i < o.stops.length) {
450
+ const t = o.stops[i];
451
+ r.uniforms.uGradientColors.value[i].set(
452
+ t.color.r,
453
+ t.color.g,
454
+ t.color.b,
455
+ t.alpha
456
+ ), r.uniforms.uGradientStops.value[i] = t.stop;
457
+ } else
458
+ r.uniforms.uGradientColors.value[i].set(0, 0, 0, 0), r.uniforms.uGradientStops.value[i] = 1;
459
+ } else
460
+ r.uniforms.uGradientCount.value = 0;
461
+ }
462
+ for (const o of Object.keys(e))
463
+ o !== "width" && o !== "height" && o !== "borderRadius" && o !== "borderWidth" && o !== "backgroundColor" && o !== "borderColor" && o !== "opacity" && o !== "bgOpacity" && o !== "borderOpacity" && o !== "texture" && o !== "backgroundImage" && r.uniforms[o] !== void 0 && (r.uniforms[o].value !== void 0 && r.uniforms[o].value !== null && typeof r.uniforms[o].value.set == "function" ? Array.isArray(e[o]) ? r.uniforms[o].value.set(...e[o]) : e[o] !== void 0 && (e[o].copy ? r.uniforms[o].value.copy(e[o]) : r.uniforms[o].value = e[o]) : r.uniforms[o].value = e[o]);
464
+ }
465
+ function A(r, e) {
466
+ if (e == null) {
467
+ r.set(0, 0, 0, 0);
468
+ return;
469
+ }
470
+ if (typeof e == "number") {
471
+ r.set(e, e, e, e);
472
+ return;
473
+ }
474
+ if (Array.isArray(e)) {
475
+ r.set(e[0], e[1], e[2], e[3]);
476
+ return;
477
+ }
478
+ const n = e.split("/")[0].trim().split(/\s+/), a = x(n[0]), o = x(n[1] ?? n[0]), i = x(n[2] ?? n[0]), t = x(n[3] ?? n[1] ?? n[0]);
479
+ r.set(a, o, i, t);
480
+ }
481
+ const N = {
482
+ create(r, e, n, a, o, i = 2, t = null, c) {
483
+ return r === "BOX" ? U(
484
+ e,
485
+ a,
486
+ o,
487
+ t,
488
+ c
489
+ ) : r === "TEXT" ? new k(
490
+ n || "",
491
+ e,
492
+ a,
493
+ o,
494
+ i
495
+ ) : new d.MeshBasicMaterial({ visible: !1 });
496
+ },
497
+ update(r, e, n, a, o, i, t = 2, c) {
498
+ e === "BOX" ? V(
499
+ r,
500
+ n,
501
+ o,
502
+ i,
503
+ c
504
+ ) : e === "TEXT" && r.updateText(
505
+ a || "",
506
+ n,
507
+ o,
508
+ i,
509
+ t
510
+ );
511
+ },
512
+ forceUpdateUniforms(r, e) {
513
+ T(r, e);
219
514
  }
220
515
  };
221
516
  export {
222
- S as Painter,
223
- R as createBoxMaterial,
224
- m as createTextTexture,
225
- E as updateBoxMaterial
517
+ N as Painter,
518
+ k as TextGenerator,
519
+ U as createBoxMaterial,
520
+ y as parseColor,
521
+ G as parseLinearGradient,
522
+ x as parsePixelValue,
523
+ T as setBoxUniforms,
524
+ P as splitByComma,
525
+ V as updateBoxMaterial
226
526
  };