@mirage-engine/painter 0.3.0 → 1.0.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.
@@ -1,226 +1,512 @@
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 I = Object.defineProperty;
2
+ var R = (o, e, t) => e in o ? I(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var b = (o, e, t) => (R(o, typeof e != "symbol" ? e + "" : e, t), t);
4
+ import * as d from "three";
5
+ class T {
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 t = this.calculateBaselineFromDOM(e);
15
+ return this.cache.set(e, t), t;
16
+ }
17
+ static calculateBaselineFromDOM(e) {
18
+ if (typeof document > "u")
19
+ return 0;
20
+ const t = document.createElement("div"), a = document.createElement("span"), r = document.createElement("img");
21
+ t.style.visibility = "hidden", t.style.position = "absolute", t.style.top = "0px", t.style.left = "0px", t.style.font = e, t.style.margin = "0", t.style.padding = "0", t.style.border = "none", a.style.margin = "0", a.style.padding = "0", a.style.border = "none", a.style.lineHeight = "normal", r.width = 1, r.height = 1, r.style.verticalAlign = "baseline", a.appendChild(document.createTextNode("Hidden Text")), t.appendChild(a), t.appendChild(r), document.body.appendChild(t);
22
+ const n = r.offsetTop - a.offsetTop;
23
+ return document.body.removeChild(t), n;
24
+ }
29
25
  }
30
- function f(e) {
31
- return typeof e == "number" ? e : parseFloat(e) || 0;
26
+ b(T, "cache", /* @__PURE__ */ new Map());
27
+ class A extends d.MeshBasicMaterial {
28
+ constructor(t, a, r, n, i = 2) {
29
+ super({
30
+ transparent: !0,
31
+ side: d.FrontSide,
32
+ color: 16777215
33
+ });
34
+ b(this, "canvas");
35
+ b(this, "ctx");
36
+ b(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 = i, this.map = new d.CanvasTexture(this.canvas), this.map.colorSpace = d.LinearSRGBColorSpace, this.map.minFilter = d.LinearFilter, this.map.magFilter = d.LinearFilter, this.updateText(t, a, r, n);
40
+ }
41
+ wrapText(t, a) {
42
+ const r = t.split(`
43
+ `), n = [];
44
+ return r.forEach((i) => {
45
+ const c = i.match(/[^\s\-]+\-?|\-|\s+/g) || [];
46
+ if (c.length === 0) {
47
+ n.push("");
48
+ return;
49
+ }
50
+ let l = c[0];
51
+ for (let s = 1; s < c.length; s++) {
52
+ const u = c[s];
53
+ this.ctx.measureText(l + u).width <= a + 2 ? l += u : (l && n.push(l), l = u.trimStart());
54
+ }
55
+ l && n.push(l);
56
+ }), n;
57
+ }
58
+ updateText(t, a, r, n, i) {
59
+ i !== void 0 && (this.qualityFactor = i);
60
+ const l = (window.devicePixelRatio || 1) * this.qualityFactor, s = r * l, u = n * l;
61
+ this.canvas.width !== s || this.canvas.height !== u ? (this.canvas.width = s, this.canvas.height = u) : this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height), this.ctx.setTransform(l, 0, 0, l, 0, 0), this.ctx.font = a.font, this.ctx.fillStyle = a.color, this.ctx.textBaseline = "alphabetic", this.ctx.globalAlpha = 1;
62
+ const h = this.wrapText(t, r), g = a.lineHeight, p = T.getBaseline(a.font);
63
+ h.forEach((f, m) => {
64
+ const y = m * g + p;
65
+ let x = 0;
66
+ a.textAlign === "center" ? x = r / 2 : a.textAlign === "right" && (x = r), this.ctx.textAlign = a.textAlign, this.ctx.fillText(f, x, y);
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 v(o) {
74
+ return typeof o == "number" ? o : parseFloat(o) || 0;
75
+ }
76
+ function C(o) {
77
+ if (!o || o === "transparent")
78
+ return { color: new d.Color(16777215), alpha: 0 };
79
+ const e = o.match(
80
+ /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
81
+ );
82
+ if (e) {
83
+ const t = parseInt(e[1], 10), a = parseInt(e[2], 10), r = parseInt(e[3], 10), n = e[4] !== void 0 ? parseFloat(e[4]) : 1;
84
+ return { color: new d.Color(`rgb(${t}, ${a}, ${r})`), alpha: n };
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(o), alpha: 1 };
87
+ }
88
+ function k(o) {
89
+ const e = [];
90
+ let t = "", a = 0;
91
+ for (let r = 0; r < o.length; r++) {
92
+ const n = o[r];
93
+ if (n === "(")
94
+ a++;
95
+ else if (n === ")")
96
+ a--;
97
+ else if (n === "," && a === 0) {
98
+ e.push(t.trim()), t = "";
99
+ continue;
100
+ }
101
+ t += n;
102
+ }
103
+ return t && e.push(t.trim()), e;
104
+ }
105
+ function M(o) {
106
+ if (!o || typeof o != "string" || !o.includes("linear-gradient"))
107
+ return null;
108
+ const e = o.match(/linear-gradient\((.*)\)/);
109
+ if (!e)
110
+ return null;
111
+ const t = e[1], a = k(t);
112
+ let r = Math.PI, n = 0;
113
+ const i = a[0].trim();
114
+ if (i.startsWith("to "))
115
+ i === "to top" ? r = 0 : i === "to right" ? r = Math.PI / 2 : i === "to bottom" ? r = Math.PI : i === "to left" ? r = Math.PI * 1.5 : i === "to top right" || i === "to right top" ? r = Math.PI / 4 : i === "to bottom right" || i === "to right bottom" ? r = Math.PI * 0.75 : i === "to bottom left" || i === "to left bottom" ? r = Math.PI * 1.25 : (i === "to top left" || i === "to left top") && (r = Math.PI * 1.75), n = 1;
116
+ else if (i.endsWith("deg") || i.endsWith("rad") || i.endsWith("turn")) {
117
+ const l = parseFloat(i);
118
+ i.endsWith("deg") ? r = l * (Math.PI / 180) : i.endsWith("rad") ? r = l : i.endsWith("turn") && (r = l * Math.PI * 2), n = 1;
119
+ }
120
+ const c = [];
121
+ for (let l = n; l < a.length && !(c.length >= 8); l++) {
122
+ const s = a[l].trim(), u = s.lastIndexOf(" ");
123
+ let h = s, g = null;
124
+ if (u !== -1 && !s.endsWith(")")) {
125
+ const f = s.substring(u + 1);
126
+ (f.endsWith("%") || f.endsWith("px") || !isNaN(parseFloat(f))) && (h = s.substring(0, u).trim(), g = f);
127
+ }
128
+ const p = C(h);
129
+ c.push({
130
+ color: p.color,
131
+ alpha: p.alpha,
132
+ rawStop: g,
133
+ stop: 0
134
+ });
135
+ }
136
+ if (c.length > 0) {
137
+ for (let s = 0; s < c.length; s++)
138
+ c[s].rawStop !== null && (c[s].stop = parseFloat(c[s].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 l = 0;
141
+ for (let s = 1; s < c.length; s++)
142
+ if (c[s].rawStop !== null || s === c.length - 1) {
143
+ const u = s - l;
144
+ if (u > 1) {
145
+ const h = c[l].stop, p = (c[s].stop - h) / u;
146
+ for (let f = 1; f < u; f++)
147
+ c[l + f].stop = h + p * f;
148
+ }
149
+ l = s;
150
+ }
151
+ }
152
+ return { angle: r, stops: c };
153
+ }
154
+ const P = `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
+ }`, G = `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
+ `, E = `uniform sampler2D uTexture;
290
+ varying vec4 vScreenPos;
291
+ uniform vec2 uTextureRepeat;
292
+ uniform vec2 uTextureOffset;`, L = `vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
293
+ vec2 resultUv = screenUv;
294
+
295
+ `, F = `vec4 texColor = texture2D(uTexture, resultUv);
296
+ baseColor = blendSrcOver(baseColor, texColor);`, B = {
297
+ vertexShader: P,
298
+ fragmentShader: G
299
+ }, S = {
300
+ declChunk: E,
301
+ uvChunk: L,
302
+ baseColorChunk: F
303
+ };
304
+ function _(o, e, t, a = null, r) {
305
+ const n = a !== null || !!o.imageSrc, i = n ? S.declChunk : "", c = o.isTraveler ? S.uvChunk : `vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
306
+ `, l = n ? c + ((r == null ? void 0 : r.uvModifier) || "") : "", s = n ? S.baseColorChunk : "", u = (r == null ? void 0 : r.colorModifier) || "", h = B.fragmentShader.replace("#INJECT_DECLARATIONS", i).replace("#INJECT_UV_MODIFIER", l).replace("#INJECT_BASE_COLOR", s).replace("#INJECT_COLOR_MODIFIER", u), g = C(o.backgroundColor), p = C(o.borderColor), f = {
307
+ uSize: { value: new d.Vector2(e, t) },
308
+ uBgColor: {
309
+ value: new d.Vector4(
310
+ g.color.r,
311
+ g.color.g,
312
+ g.color.b,
313
+ g.alpha
314
+ )
315
+ },
316
+ uBorderColor: {
317
+ value: new d.Vector4(
318
+ p.color.r,
319
+ p.color.g,
320
+ p.color.b,
321
+ p.alpha
322
+ )
323
+ },
324
+ uBorderRadius: { value: new d.Vector4(0, 0, 0, 0) },
325
+ uBorderWidth: { value: v(o.borderWidth) },
326
+ uOpacity: { value: o.opacity ?? 1 },
327
+ uTexture: { value: null },
328
+ uTextureRepeat: { value: new d.Vector2(1, 1) },
329
+ uTextureOffset: { value: new d.Vector2(0, 0) },
330
+ uGradientCount: { value: 0 },
331
+ uGradientAngle: { value: 0 },
332
+ uGradientColors: {
333
+ value: Array.from({ length: 8 }, () => new d.Vector4(0, 0, 0, 0))
334
+ },
335
+ uGradientStops: { value: new Float32Array(8) }
163
336
  };
164
- return b(p.uBorderRadius.value, e.borderRadius), n && (p.uTexture.value = i), new l.ShaderMaterial({
165
- uniforms: p,
166
- vertexShader: O,
167
- fragmentShader: v,
337
+ O(f.uBorderRadius.value, o.borderRadius), n && (f.uTexture.value = a);
338
+ const m = new d.ShaderMaterial({
339
+ uniforms: f,
340
+ vertexShader: B.vertexShader,
341
+ fragmentShader: h,
168
342
  transparent: !0,
169
- side: l.FrontSide
343
+ side: d.FrontSide
170
344
  // for better performance
171
345
  });
346
+ return o.backgroundImage && w(m, { backgroundImage: o.backgroundImage }), m;
347
+ }
348
+ function W(o, e, t, a, r) {
349
+ const n = v(e.borderWidth);
350
+ w(o, {
351
+ width: t,
352
+ height: a,
353
+ borderRadius: e.borderRadius,
354
+ borderWidth: n,
355
+ backgroundColor: e.backgroundColor,
356
+ borderColor: e.borderColor,
357
+ opacity: e.opacity,
358
+ texture: r,
359
+ backgroundImage: e.backgroundImage
360
+ });
172
361
  }
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) {
179
- if (e === "BOX")
180
- return R(r, i, a, t);
181
- if (e === "TEXT") {
182
- const c = m(
183
- o || "",
184
- r,
185
- i,
186
- a,
187
- n
362
+ function w(o, e) {
363
+ var a;
364
+ if (e.width !== void 0 && e.height !== void 0 && o.uniforms.uSize.value.set(e.width, e.height), e.borderRadius !== void 0 && O(o.uniforms.uBorderRadius.value, e.borderRadius), e.borderWidth !== void 0 && (o.uniforms.uBorderWidth.value = e.borderWidth), e.backgroundColor !== void 0)
365
+ if (Array.isArray(e.backgroundColor)) {
366
+ const r = o.uniforms.uBgColor.value.w;
367
+ o.uniforms.uBgColor.value.set(
368
+ e.backgroundColor[0],
369
+ e.backgroundColor[1],
370
+ e.backgroundColor[2],
371
+ r
372
+ );
373
+ } else if (typeof e.backgroundColor == "string") {
374
+ const r = C(e.backgroundColor);
375
+ o.uniforms.uBgColor.value.set(
376
+ r.color.r,
377
+ r.color.g,
378
+ r.color.b,
379
+ r.alpha
380
+ );
381
+ } else {
382
+ const r = o.uniforms.uBgColor.value.w;
383
+ o.uniforms.uBgColor.value.set(
384
+ e.backgroundColor.r,
385
+ e.backgroundColor.g,
386
+ e.backgroundColor.b,
387
+ r
188
388
  );
189
- return new l.MeshBasicMaterial({
190
- map: c,
191
- transparent: !0,
192
- side: l.FrontSide,
193
- color: 16777215
194
- });
195
389
  }
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
390
+ if (e.borderColor !== void 0)
391
+ if (Array.isArray(e.borderColor)) {
392
+ const r = o.uniforms.uBorderColor.value.w;
393
+ o.uniforms.uBorderColor.value.set(
394
+ e.borderColor[0],
395
+ e.borderColor[1],
396
+ e.borderColor[2],
397
+ r
398
+ );
399
+ } else if (typeof e.borderColor == "string") {
400
+ const r = C(e.borderColor);
401
+ o.uniforms.uBorderColor.value.set(
402
+ r.color.r,
403
+ r.color.g,
404
+ r.color.b,
405
+ r.alpha
206
406
  );
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
407
+ } else {
408
+ const r = o.uniforms.uBorderColor.value.w;
409
+ o.uniforms.uBorderColor.value.set(
410
+ e.borderColor.r,
411
+ e.borderColor.g,
412
+ e.borderColor.b,
413
+ r
216
414
  );
217
- u.map = s, u.needsUpdate = !0;
218
415
  }
416
+ e.opacity !== void 0 && (o.uniforms.uOpacity.value = e.opacity), e.bgOpacity !== void 0 && (o.uniforms.uBgColor.value.w = e.bgOpacity), e.borderOpacity !== void 0 && (o.uniforms.uBorderColor.value.w = e.borderOpacity), o.uniforms.uTexture && e.texture !== void 0 && (o.uniforms.uTexture.value = e.texture);
417
+ const t = e.texture !== void 0 ? e.texture : (a = o.uniforms.uTexture) == null ? void 0 : a.value;
418
+ if (t && (t.image instanceof ImageBitmap || t.image instanceof HTMLImageElement || t.image instanceof HTMLCanvasElement)) {
419
+ const r = t.image.width, n = t.image.height, i = e.width ?? o.uniforms.uSize.value.x, c = e.height ?? o.uniforms.uSize.value.y;
420
+ if (r && n && i && c) {
421
+ const l = r / n, s = i / c;
422
+ if (l > s) {
423
+ const u = s / l;
424
+ o.uniforms.uTextureRepeat.value.set(u, 1), o.uniforms.uTextureOffset.value.set((1 - u) / 2, 0);
425
+ } else {
426
+ const u = l / s;
427
+ o.uniforms.uTextureRepeat.value.set(1, u), o.uniforms.uTextureOffset.value.set(0, (1 - u) / 2);
428
+ }
429
+ }
430
+ } else
431
+ o.uniforms.uTextureRepeat && (o.uniforms.uTextureRepeat.value.set(1, 1), o.uniforms.uTextureOffset.value.set(0, 0));
432
+ if (e.backgroundImage !== void 0) {
433
+ const r = M(e.backgroundImage);
434
+ if (r) {
435
+ o.uniforms.uGradientCount.value = r.stops.length, o.uniforms.uGradientAngle.value = r.angle;
436
+ for (let n = 0; n < 8; n++)
437
+ if (n < r.stops.length) {
438
+ const i = r.stops[n];
439
+ o.uniforms.uGradientColors.value[n].set(
440
+ i.color.r,
441
+ i.color.g,
442
+ i.color.b,
443
+ i.alpha
444
+ ), console.log(i.color.r, i.color.g, i.color.b), o.uniforms.uGradientStops.value[n] = i.stop;
445
+ } else
446
+ o.uniforms.uGradientColors.value[n].set(0, 0, 0, 0), o.uniforms.uGradientStops.value[n] = 1;
447
+ } else
448
+ o.uniforms.uGradientCount.value = 0;
449
+ }
450
+ }
451
+ function O(o, e) {
452
+ if (e == null) {
453
+ o.set(0, 0, 0, 0);
454
+ return;
455
+ }
456
+ if (typeof e == "number") {
457
+ o.set(e, e, e, e);
458
+ return;
459
+ }
460
+ if (Array.isArray(e)) {
461
+ o.set(e[0], e[1], e[2], e[3]);
462
+ return;
463
+ }
464
+ const t = e.split("/")[0].trim().split(/\s+/), a = v(t[0]), r = v(t[1] ?? t[0]), n = v(t[2] ?? t[0]), i = v(t[3] ?? t[1] ?? t[0]);
465
+ o.set(a, r, n, i);
466
+ }
467
+ const z = {
468
+ create(o, e, t, a, r, n = 2, i = null, c) {
469
+ return o === "BOX" ? _(
470
+ e,
471
+ a,
472
+ r,
473
+ i,
474
+ c
475
+ ) : o === "TEXT" ? new A(
476
+ t || "",
477
+ e,
478
+ a,
479
+ r,
480
+ n
481
+ ) : new d.MeshBasicMaterial({ visible: !1 });
482
+ },
483
+ update(o, e, t, a, r, n, i = 2, c) {
484
+ e === "BOX" ? W(
485
+ o,
486
+ t,
487
+ r,
488
+ n,
489
+ c
490
+ ) : e === "TEXT" && o.updateText(
491
+ a || "",
492
+ t,
493
+ r,
494
+ n,
495
+ i
496
+ );
497
+ },
498
+ forceUpdateUniforms(o, e) {
499
+ w(o, e);
219
500
  }
220
501
  };
221
502
  export {
222
- S as Painter,
223
- R as createBoxMaterial,
224
- m as createTextTexture,
225
- E as updateBoxMaterial
503
+ z as Painter,
504
+ A as TextGenerator,
505
+ _ as createBoxMaterial,
506
+ C as parseColor,
507
+ M as parseLinearGradient,
508
+ v as parsePixelValue,
509
+ w as setBoxUniforms,
510
+ k as splitByComma,
511
+ W as updateBoxMaterial
226
512
  };