mirage-engine 0.2.16 → 0.2.18

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,279 +1,639 @@
1
- var X = Object.defineProperty;
2
- var P = (i, e, t) => e in i ? X(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
3
- var h = (i, e, t) => (P(i, typeof e != "symbol" ? e + "" : e, t), t);
4
- import * as d from "three";
5
- const E = 0, O = 1, z = 2, q = 4, D = 8, _ = 16, x = 1, R = 2, k = [
1
+ var de = Object.defineProperty;
2
+ var ue = (i, e, t) => e in i ? de(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
3
+ var u = (i, e, t) => (ue(i, typeof e != "symbol" ? e + "" : e, t), t);
4
+ var se = (i, e, t) => new Promise((s, r) => {
5
+ var a = (c) => {
6
+ try {
7
+ n(t.next(c));
8
+ } catch (l) {
9
+ r(l);
10
+ }
11
+ }, o = (c) => {
12
+ try {
13
+ n(t.throw(c));
14
+ } catch (l) {
15
+ r(l);
16
+ }
17
+ }, n = (c) => c.done ? s(c.value) : Promise.resolve(c.value).then(a, o);
18
+ n((t = t.apply(i, e)).next());
19
+ });
20
+ import * as m from "three";
21
+ const _ = 0, B = 1, N = 2, fe = 4, V = 8, $ = 16, D = 1, X = 2, ge = [
6
22
  "include-tree",
7
23
  "exclude-tree",
8
24
  "include-self",
9
25
  "exclude-self",
10
26
  "end"
11
27
  ];
12
- function Y(i, e, t) {
13
- const r = e.split(`
14
- `), s = [];
15
- return r.forEach((n) => {
16
- const a = n.split(" ");
17
- let o = a[0];
18
- for (let l = 1; l < a.length; l++) {
19
- const c = a[l];
20
- i.measureText(o + " " + c).width < t ? o += " " + c : (s.push(o), o = c);
21
- }
22
- s.push(o);
23
- }), s;
28
+ class ne {
29
+ /**
30
+ * Calculates or retrieves the exact alphabetic baseline (in pixels) for the given font.
31
+ * @param font CSS font shorthand string (e.g., "400 16px Inter")
32
+ * @returns Baseline Y offset in pixels
33
+ */
34
+ static getBaseline(e) {
35
+ if (this.cache.has(e))
36
+ return this.cache.get(e);
37
+ const t = this.calculateBaselineFromDOM(e);
38
+ return this.cache.set(e, t), t;
39
+ }
40
+ static calculateBaselineFromDOM(e) {
41
+ if (typeof document == "undefined")
42
+ return 0;
43
+ const t = document.createElement("div"), s = document.createElement("span"), r = document.createElement("img");
44
+ 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", s.style.margin = "0", s.style.padding = "0", s.style.border = "none", s.style.lineHeight = "normal", r.width = 1, r.height = 1, r.style.verticalAlign = "baseline", s.appendChild(document.createTextNode("Hidden Text")), t.appendChild(s), t.appendChild(r), document.body.appendChild(t);
45
+ const a = r.offsetTop - s.offsetTop;
46
+ return document.body.removeChild(t), a;
47
+ }
24
48
  }
25
- function I(i, e, t, r, s = 2) {
26
- const n = document.createElement("canvas"), a = n.getContext("2d");
27
- if (!a)
28
- throw new Error("[Mirage] Failed to create canvas context");
29
- const l = (window.devicePixelRatio || 1) * s;
30
- n.width = t * l, n.height = r * l, a.scale(l, l), a.font = e.font, a.fillStyle = e.color, a.textBaseline = "top", a.globalAlpha = 1;
31
- const c = Y(a, i, t), g = e.lineHeight;
32
- c.forEach((p, m) => {
33
- const T = m * g + 2;
34
- let v = 0;
35
- e.textAlign === "center" ? v = t / 2 : e.textAlign === "right" && (v = t), a.textAlign = e.textAlign, a.fillText(p, v, T);
36
- });
37
- const u = new d.CanvasTexture(n);
38
- return u.colorSpace = d.SRGBColorSpace, u.minFilter = d.LinearFilter, u.magFilter = d.LinearFilter, u.needsUpdate = !0, u;
49
+ u(ne, "cache", /* @__PURE__ */ new Map());
50
+ class pe extends m.MeshBasicMaterial {
51
+ constructor(t, s, r, a, o = 2) {
52
+ super({
53
+ transparent: !0,
54
+ side: m.FrontSide,
55
+ color: 16777215
56
+ });
57
+ u(this, "canvas");
58
+ u(this, "ctx");
59
+ u(this, "qualityFactor");
60
+ if (this.canvas = document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), !this.ctx)
61
+ throw new Error("[Mirage] Failed to create canvas context");
62
+ this.qualityFactor = o, this.map = new m.CanvasTexture(this.canvas), this.map.colorSpace = m.LinearSRGBColorSpace, this.map.minFilter = m.LinearFilter, this.map.magFilter = m.LinearFilter, this.updateText(t, s, r, a);
63
+ }
64
+ wrapText(t, s) {
65
+ const r = t.split(`
66
+ `), a = [];
67
+ return r.forEach((o) => {
68
+ const n = o.match(/[^\s\-]+\-?|\-|\s+/g) || [];
69
+ if (n.length === 0) {
70
+ a.push("");
71
+ return;
72
+ }
73
+ let c = n[0];
74
+ for (let l = 1; l < n.length; l++) {
75
+ const d = n[l];
76
+ this.ctx.measureText(c + d).width <= s + 2 ? c += d : (c && a.push(c), c = d.trimStart());
77
+ }
78
+ c && a.push(c);
79
+ }), a;
80
+ }
81
+ updateText(t, s, r, a, o) {
82
+ o !== void 0 && (this.qualityFactor = o);
83
+ const c = (window.devicePixelRatio || 1) * this.qualityFactor, l = r * c, d = a * c;
84
+ this.canvas.width !== l || this.canvas.height !== d ? (this.canvas.width = l, this.canvas.height = d) : this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height), this.ctx.setTransform(c, 0, 0, c, 0, 0), this.ctx.font = s.font, this.ctx.fillStyle = s.color, this.ctx.textBaseline = "alphabetic", this.ctx.globalAlpha = 1;
85
+ const f = this.wrapText(t, r), h = s.lineHeight, p = ne.getBaseline(s.font);
86
+ f.forEach((g, y) => {
87
+ const x = y * h + p;
88
+ let T = 0;
89
+ s.textAlign === "center" ? T = r / 2 : s.textAlign === "right" && (T = r), this.ctx.textAlign = s.textAlign, this.ctx.fillText(g, T, x);
90
+ }), this.map && (this.map.needsUpdate = !0);
91
+ }
92
+ dispose() {
93
+ this.map && this.map.dispose(), super.dispose();
94
+ }
39
95
  }
40
- function w(i) {
96
+ function F(i) {
41
97
  return typeof i == "number" ? i : parseFloat(i) || 0;
42
98
  }
43
- function N(i, e) {
44
- var o, l, c, g;
45
- if (!e) {
46
- i.set(0, 0, 0, 0);
47
- return;
99
+ function I(i) {
100
+ if (!i || i === "transparent")
101
+ return { color: new m.Color(16777215), alpha: 0 };
102
+ const e = i.match(
103
+ /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
104
+ );
105
+ if (e) {
106
+ const t = parseInt(e[1], 10), s = parseInt(e[2], 10), r = parseInt(e[3], 10), a = e[4] !== void 0 ? parseFloat(e[4]) : 1;
107
+ return { color: new m.Color(`rgb(${t}, ${s}, ${r})`), alpha: a };
108
+ }
109
+ return { color: new m.Color(i), alpha: 1 };
110
+ }
111
+ function me(i) {
112
+ const e = [];
113
+ let t = "", s = 0;
114
+ for (let r = 0; r < i.length; r++) {
115
+ const a = i[r];
116
+ if (a === "(")
117
+ s++;
118
+ else if (a === ")")
119
+ s--;
120
+ else if (a === "," && s === 0) {
121
+ e.push(t.trim()), t = "";
122
+ continue;
123
+ }
124
+ t += a;
125
+ }
126
+ return t && e.push(t.trim()), e;
127
+ }
128
+ function be(i) {
129
+ if (!i || typeof i != "string" || !i.includes("linear-gradient"))
130
+ return null;
131
+ const e = i.match(/linear-gradient\((.*)\)/);
132
+ if (!e)
133
+ return null;
134
+ const t = e[1], s = me(t);
135
+ let r = Math.PI, a = 0;
136
+ const o = s[0].trim();
137
+ if (o.startsWith("to "))
138
+ o === "to top" ? r = 0 : o === "to right" ? r = Math.PI / 2 : o === "to bottom" ? r = Math.PI : o === "to left" ? r = Math.PI * 1.5 : o === "to top right" || o === "to right top" ? r = Math.PI / 4 : o === "to bottom right" || o === "to right bottom" ? r = Math.PI * 0.75 : o === "to bottom left" || o === "to left bottom" ? r = Math.PI * 1.25 : (o === "to top left" || o === "to left top") && (r = Math.PI * 1.75), a = 1;
139
+ else if (o.endsWith("deg") || o.endsWith("rad") || o.endsWith("turn")) {
140
+ const c = parseFloat(o);
141
+ o.endsWith("deg") ? r = c * (Math.PI / 180) : o.endsWith("rad") ? r = c : o.endsWith("turn") && (r = c * Math.PI * 2), a = 1;
142
+ }
143
+ const n = [];
144
+ for (let c = a; c < s.length && !(n.length >= 8); c++) {
145
+ const l = s[c].trim(), d = l.lastIndexOf(" ");
146
+ let f = l, h = null;
147
+ if (d !== -1 && !l.endsWith(")")) {
148
+ const g = l.substring(d + 1);
149
+ (g.endsWith("%") || g.endsWith("px") || !isNaN(parseFloat(g))) && (f = l.substring(0, d).trim(), h = g);
150
+ }
151
+ const p = I(f);
152
+ n.push({
153
+ color: p.color,
154
+ alpha: p.alpha,
155
+ rawStop: h,
156
+ stop: 0
157
+ });
158
+ }
159
+ if (n.length > 0) {
160
+ for (let l = 0; l < n.length; l++)
161
+ n[l].rawStop !== null && (n[l].stop = parseFloat(n[l].rawStop) / 100);
162
+ n[0].rawStop === null && (n[0].stop = 0), n.length > 1 && n[n.length - 1].rawStop === null && (n[n.length - 1].stop = 1);
163
+ let c = 0;
164
+ for (let l = 1; l < n.length; l++)
165
+ if (n[l].rawStop !== null || l === n.length - 1) {
166
+ const d = l - c;
167
+ if (d > 1) {
168
+ const f = n[c].stop, p = (n[l].stop - f) / d;
169
+ for (let g = 1; g < d; g++)
170
+ n[c + g].stop = f + p * g;
171
+ }
172
+ c = l;
173
+ }
48
174
  }
49
- const t = e.split("/")[0].trim().split(/\s+/), r = w(t[0]), s = w((o = t[1]) != null ? o : t[0]), n = w((l = t[2]) != null ? l : t[0]), a = w((g = (c = t[3]) != null ? c : t[1]) != null ? g : t[0]);
50
- i.set(r, s, n, a);
175
+ return { angle: r, stops: n };
51
176
  }
52
- const U = (
53
- /* glsl */
54
- `
55
- varying vec2 vUv;
56
- varying vec4 vScreenPos;
57
- void main() {
58
- vUv = uv;
59
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
60
- vScreenPos = gl_Position;
61
- }
62
- `
63
- ), W = (
64
- /* glsl */
65
- `
177
+ const xe = `varying vec2 vUv;
178
+ varying vec4 vScreenPos;
179
+ void main() {
180
+ vUv = uv;
181
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
182
+ vScreenPos = gl_Position;
183
+ }`, ve = `varying vec2 vUv;
184
+ uniform vec2 uSize;
185
+ uniform vec4 uBorderRadius;
186
+ uniform float uBorderWidth;
187
+ uniform vec4 uBgColor;
188
+ uniform vec4 uBorderColor;
189
+ uniform float uOpacity;
66
190
 
67
- varying vec2 vUv;
68
-
69
- uniform vec2 uSize;
70
- uniform vec4 uBorderRadius;
71
- uniform float uBorderWidth;
72
- uniform vec3 uBgColor;
73
- uniform vec3 uBorderColor;
74
- uniform float uOpacity;
75
- uniform float uBgOpacity;
76
- uniform float uBorderOpacity;
191
+ uniform int uGradientCount;
192
+ uniform float uGradientAngle;
193
+ uniform vec4 uGradientColors[8];
194
+ uniform float uGradientStops[8];
77
195
 
78
- #INJECT_DECLARATIONS
196
+ #INJECT_DECLARATIONS
79
197
 
80
- float sdRoundedBox(vec2 p, vec2 b, float r) {
81
- vec2 q = abs(p) - b + r;
198
+ vec3 linearToSrgb(vec3 linearColor) {
199
+ vec3 linearPart = 12.92 * linearColor;
200
+ vec3 curvePart = 1.055 * pow(linearColor, vec3(1.0 / 2.4)) - 0.055;
201
+ vec3 switchCondition = step(vec3(0.0031308), linearColor);
202
+ return mix(linearPart, curvePart, switchCondition);
203
+ }
82
204
 
83
- return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
84
- }
205
+ vec3 srgbToLinear(vec3 srgbColor) {
206
+ vec3 linearPart = srgbColor / 12.92;
207
+ vec3 curvePart = pow((srgbColor + vec3(0.055)) / 1.055, vec3(2.4));
208
+ vec3 switchCondition = step(vec3(0.04045), srgbColor);
209
+ return mix(linearPart, curvePart, switchCondition);
210
+ }
85
211
 
86
- void main() {
87
- vec2 p = (vUv - 0.5) * uSize;
88
- vec2 halfSize = uSize * 0.5;
212
+ vec4 blendSrcOverInLinear(vec4 front, vec4 back) {
213
+ front.rgb = srgbToLinear(front.rgb);
214
+ back.rgb = srgbToLinear(back.rgb);
215
+ float aOut = front.a + back.a * (1.0 - front.a);
216
+ float safeAlpha = max(aOut, 0.0001);
217
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
218
+ return vec4(linearToSrgb(cOut), aOut);
219
+ }
89
220
 
90
- #INJECT_UV_MODIFIER
221
+ vec4 blendSrcOver(vec4 front, vec4 back) {
222
+ float aOut = front.a + back.a * (1.0 - front.a);
223
+ float safeAlpha = max(aOut, 0.0001);
224
+ vec3 cOut = (front.rgb * front.a + back.rgb * back.a * (1.0 - front.a)) / safeAlpha;
225
+ return vec4(cOut, aOut);
226
+ }
227
+
228
+ float sdRoundedBox(vec2 p, vec2 b, float r) {
229
+ vec2 q = abs(p) - b + r;
230
+ return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r;
231
+ }
232
+
233
+ float sdVisualBox(vec2 p, vec2 b, float r) {
234
+ vec2 q = abs(p) - b + r;
235
+ float n = 2.01;
236
+ float d = pow(pow(max(q.x, 0.0), n) + pow(max(q.y, 0.0), n), 1.0/n) - r;
237
+ return min(max(q.x, q.y), 0.0) + d;
238
+ }
239
+
240
+ vec4 calculateGradientLayer(vec2 uv) {
241
+ if (uGradientCount < 2) return uGradientColors[0];
242
+
243
+ vec2 dir = vec2(sin(uGradientAngle), cos(uGradientAngle));
244
+ vec2 p = (uv - 0.5) * uSize;
245
+ float proj = dot(p, dir);
246
+ float L = abs(uSize.x * dir.x) + abs(uSize.y * dir.y);
247
+ float t = clamp((proj / L) + 0.5, 0.0, 1.0);
248
+
249
+ vec4 color = uGradientColors[0];
250
+ for (int i = 1; i < 8; i++) {
251
+ if (i >= uGradientCount) break;
252
+ float prevStop = uGradientStops[i-1];
253
+ float currStop = uGradientStops[i];
91
254
 
92
- // color decision pipeline
93
- vec4 baseColor = vec4(uBgColor, uBgOpacity);
255
+ float factor = clamp((t - prevStop) / (currStop - prevStop + 0.00001), 0.0, 1.0);
256
+ color = mix(color, uGradientColors[i], factor);
257
+ }
258
+ // return vec4(linearToSrgb(color.rgb), color.a);
259
+ return vec4(color);
260
+ }
94
261
 
95
- #INJECT_BASE_COLOR
262
+ void main() {
263
+ vec2 p = (vUv - 0.5) * uSize;
264
+ vec2 halfSize = uSize * 0.5;
96
265
 
97
- // sdf shape pipeline
98
- vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
99
- float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
100
- float d = sdRoundedBox(p, halfSize, r);
266
+ #INJECT_UV_MODIFIER
101
267
 
102
- float aa = 1.0;
103
- float bgMask = 1.0 - smoothstep(0.0, aa, d);
268
+ // color decision pipeline
269
+ vec4 baseColor = vec4(uBgColor.rgb, uBgColor.a);
104
270
 
105
- float halfBorder = uBorderWidth * 0.5;
106
- float borderD = abs(d + halfBorder) - halfBorder;
107
- float borderAlpha = (1.0 - smoothstep(0.0, aa, borderD)) * uBorderOpacity;
108
- if (uBorderWidth <= 0.01) {
109
- borderAlpha = 0.0;
110
- }
271
+ if (uGradientCount > 0) {
272
+ vec4 gradColor = calculateGradientLayer(vUv);
273
+ baseColor = blendSrcOver(gradColor, baseColor);
274
+ }
111
275
 
112
- // final blending (border + background)
113
- float aFront = borderAlpha;
114
- float aBack = baseColor.a;
115
- float aOut = aFront + aBack * (1.0 - aFront);
276
+ #INJECT_BASE_COLOR
116
277
 
117
- float safeAlpha = max(aOut, 0.0001);
118
- vec3 cOut = (uBorderColor * aFront + baseColor.rgb * aBack * (1.0 - aFront)) / safeAlpha;
119
- vec4 finalColor = vec4(cOut, aOut);
278
+ // Hybrid SDF
279
+ vec2 xRadii = mix(uBorderRadius.xw, uBorderRadius.yz, step(0.0, p.x));
280
+ float r = mix(xRadii.y, xRadii.x, step(0.0, p.y));
281
+ r = min(r, min(halfSize.x, halfSize.y));
120
282
 
121
- // final color control (Tint, Noise)
122
- #INJECT_COLOR_MODIFIER
283
+ float d = sdRoundedBox(p, halfSize, r);
123
284
 
124
- float finalOpacity = finalColor.a * bgMask * uOpacity;
125
- if (finalOpacity < 0.001) discard;
285
+ float d_smooth = sdVisualBox(p, halfSize, r);
286
+ float d_visual = d_smooth / fwidth(d_smooth);
126
287
 
127
- gl_FragColor = vec4(finalColor.rgb, finalOpacity);
288
+ // rendering pipeline
289
+ float bgMask = 1.0 - smoothstep(-0.5, 0.5, d_visual);
128
290
 
129
- #include <colorspace_fragment>
130
- }
131
- `
132
- );
133
- function S(i) {
134
- if (!i || i === "transparent")
135
- return { color: new d.Color(16777215), alpha: 0 };
136
- const e = i.match(
137
- /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
138
- );
139
- if (e) {
140
- const t = parseInt(e[1], 10), r = parseInt(e[2], 10), s = parseInt(e[3], 10), n = e[4] !== void 0 ? parseFloat(e[4]) : 1;
141
- return { color: new d.Color(`rgb(${t}, ${r}, ${s})`), alpha: n };
291
+ float halfBorder = uBorderWidth * 0.5;
292
+ float borderD = abs(d + halfBorder) - halfBorder;
293
+ float borderAlpha = (1.0 - smoothstep(0.0, 1.0, borderD)) * uBorderColor.a;
294
+ if (uBorderWidth <= 0.01) {
295
+ borderAlpha = 0.0;
142
296
  }
143
- return { color: new d.Color(i), alpha: 1 };
297
+
298
+ // final blending (border + background) using blendSrcOver
299
+ vec4 borderLayer = vec4(uBorderColor.rgb, borderAlpha);
300
+ vec4 finalColor = blendSrcOver(borderLayer, baseColor);
301
+ // final color control (Tint, Noise)
302
+ #INJECT_COLOR_MODIFIER
303
+
304
+ float finalOpacity = finalColor.a * bgMask * uOpacity;
305
+ if (finalOpacity < 0.001) discard;
306
+
307
+ gl_FragColor = vec4(finalColor.rgb, finalOpacity);
308
+
309
+
310
+ // #include <colorspace_fragment>
144
311
  }
145
- function H(i, e, t, r = null, s) {
146
- var v;
147
- const n = r !== null, a = n ? (
148
- /* glsl */
149
- `
150
- uniform sampler2D uTexture;
151
- varying vec4 vScreenPos;
152
- `
153
- ) : "", o = n ? (
154
- /* glsl */
155
- `
156
- vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
157
- vec2 resultUv = screenUv;
158
- ${(s == null ? void 0 : s.uvModifier) || ""}
159
- `
160
- ) : "", l = n ? (
161
- /* glsl */
162
- `
163
- baseColor = texture2D(uTexture, resultUv);
164
- `
165
- ) : "", c = (s == null ? void 0 : s.colorModifier) || "", g = W.replace("#INJECT_DECLARATIONS", a).replace("#INJECT_UV_MODIFIER", o).replace("#INJECT_BASE_COLOR", l).replace("#INJECT_COLOR_MODIFIER", c), u = S(i.backgroundColor), p = S(i.borderColor), m = {
166
- uSize: { value: new d.Vector2(e, t) },
167
- uBorderRadius: { value: new d.Vector4(0, 0, 0, 0) },
168
- uBorderWidth: { value: w(i.borderWidth) },
169
- uBgColor: { value: u.color },
170
- uBorderColor: { value: p.color },
171
- uOpacity: { value: (v = i.opacity) != null ? v : 1 },
172
- uBgOpacity: { value: u.alpha },
173
- uBorderOpacity: { value: p.alpha },
174
- uTexture: { value: null }
312
+ `, ye = `uniform sampler2D uTexture;
313
+ varying vec4 vScreenPos;
314
+ uniform vec2 uTextureRepeat;
315
+ uniform vec2 uTextureOffset;`, we = `vec2 screenUv = (vScreenPos.xy / vScreenPos.w) * 0.5 + 0.5;
316
+ vec2 resultUv = screenUv;
317
+
318
+ `, Ce = `vec4 texColor = texture2D(uTexture, resultUv);
319
+ baseColor = blendSrcOver(baseColor, texColor);`, oe = {
320
+ vertexShader: xe,
321
+ fragmentShader: ve
322
+ }, H = {
323
+ declChunk: ye,
324
+ uvChunk: we,
325
+ baseColorChunk: Ce
326
+ };
327
+ function Te(i, e, t, s = null, r) {
328
+ var x;
329
+ const a = s !== null || !!i.imageSrc, o = a ? H.declChunk : "", n = i.isTraveler ? H.uvChunk : `vec2 resultUv = vUv * uTextureRepeat + uTextureOffset;
330
+ `, c = a ? n + ((r == null ? void 0 : r.uvModifier) || "") : "", l = a ? H.baseColorChunk : "", d = (r == null ? void 0 : r.colorModifier) || "", f = oe.fragmentShader.replace("#INJECT_DECLARATIONS", o).replace("#INJECT_UV_MODIFIER", c).replace("#INJECT_BASE_COLOR", l).replace("#INJECT_COLOR_MODIFIER", d), h = I(i.backgroundColor), p = I(i.borderColor), g = {
331
+ uSize: { value: new m.Vector2(e, t) },
332
+ uBgColor: {
333
+ value: new m.Vector4(
334
+ h.color.r,
335
+ h.color.g,
336
+ h.color.b,
337
+ h.alpha
338
+ )
339
+ },
340
+ uBorderColor: {
341
+ value: new m.Vector4(
342
+ p.color.r,
343
+ p.color.g,
344
+ p.color.b,
345
+ p.alpha
346
+ )
347
+ },
348
+ uBorderRadius: { value: new m.Vector4(0, 0, 0, 0) },
349
+ uBorderWidth: { value: F(i.borderWidth) },
350
+ uOpacity: { value: (x = i.opacity) != null ? x : 1 },
351
+ uTexture: { value: null },
352
+ uTextureRepeat: { value: new m.Vector2(1, 1) },
353
+ uTextureOffset: { value: new m.Vector2(0, 0) },
354
+ uGradientCount: { value: 0 },
355
+ uGradientAngle: { value: 0 },
356
+ uGradientColors: {
357
+ value: Array.from({ length: 8 }, () => new m.Vector4(0, 0, 0, 0))
358
+ },
359
+ uGradientStops: { value: new Float32Array(8) }
175
360
  };
176
- return N(m.uBorderRadius.value, i.borderRadius), n && (m.uTexture.value = r), new d.ShaderMaterial({
177
- uniforms: m,
178
- vertexShader: U,
179
- fragmentShader: g,
361
+ ae(g.uBorderRadius.value, i.borderRadius), a && (g.uTexture.value = s);
362
+ const y = new m.ShaderMaterial({
363
+ uniforms: g,
364
+ vertexShader: oe.vertexShader,
365
+ fragmentShader: f,
180
366
  transparent: !0,
181
- side: d.FrontSide
367
+ side: m.FrontSide
182
368
  // for better performance
183
369
  });
370
+ return i.backgroundImage && J(y, { backgroundImage: i.backgroundImage }), y;
184
371
  }
185
- function $(i, e, t, r, s) {
186
- var o;
187
- const n = S(e.backgroundColor), a = S(e.borderColor);
188
- i.uniforms.uSize.value.set(t, r), N(i.uniforms.uBorderRadius.value, e.borderRadius), i.uniforms.uBorderWidth.value = w(e.borderWidth), i.uniforms.uBgColor.value.copy(n.color), i.uniforms.uBorderColor.value.copy(a.color), i.uniforms.uOpacity.value = (o = e.opacity) != null ? o : 1, i.uniforms.uBgOpacity.value = n.alpha, i.uniforms.uBorderOpacity.value = a.alpha, i.uniforms.uTexture && s !== void 0 && (i.uniforms.uTexture.value = s);
372
+ function Se(i, e, t, s, r) {
373
+ const a = F(e.borderWidth);
374
+ J(i, {
375
+ width: t,
376
+ height: s,
377
+ borderRadius: e.borderRadius,
378
+ borderWidth: a,
379
+ backgroundColor: e.backgroundColor,
380
+ borderColor: e.borderColor,
381
+ opacity: e.opacity,
382
+ texture: r,
383
+ backgroundImage: e.backgroundImage
384
+ });
189
385
  }
190
- const F = {
191
- create(i, e, t, r, s, n = 2, a = null) {
192
- if (i === "BOX")
193
- return H(e, r, s, a);
194
- if (i === "TEXT") {
195
- const o = I(
196
- t || "",
197
- e,
198
- r,
199
- s,
200
- n
386
+ function J(i, e) {
387
+ var s, r, a;
388
+ if (e.width !== void 0 && e.height !== void 0 && i.uniforms.uSize.value.set(e.width, e.height), e.borderRadius !== void 0 && ae(i.uniforms.uBorderRadius.value, e.borderRadius), e.borderWidth !== void 0 && (i.uniforms.uBorderWidth.value = e.borderWidth), e.backgroundColor !== void 0)
389
+ if (Array.isArray(e.backgroundColor)) {
390
+ const o = i.uniforms.uBgColor.value.w;
391
+ i.uniforms.uBgColor.value.set(
392
+ e.backgroundColor[0],
393
+ e.backgroundColor[1],
394
+ e.backgroundColor[2],
395
+ o
396
+ );
397
+ } else if (typeof e.backgroundColor == "string") {
398
+ const o = I(e.backgroundColor);
399
+ i.uniforms.uBgColor.value.set(
400
+ o.color.r,
401
+ o.color.g,
402
+ o.color.b,
403
+ o.alpha
404
+ );
405
+ } else {
406
+ const o = i.uniforms.uBgColor.value.w;
407
+ i.uniforms.uBgColor.value.set(
408
+ e.backgroundColor.r,
409
+ e.backgroundColor.g,
410
+ e.backgroundColor.b,
411
+ o
201
412
  );
202
- return new d.MeshBasicMaterial({
203
- map: o,
204
- transparent: !0,
205
- side: d.FrontSide,
206
- color: 16777215
207
- });
208
413
  }
209
- return new d.MeshBasicMaterial({ visible: !1 });
210
- },
211
- update(i, e, t, r, s, n, a = 2, o) {
212
- if (e === "BOX")
213
- $(
214
- i,
215
- t,
216
- s,
217
- n,
414
+ if (e.borderColor !== void 0)
415
+ if (Array.isArray(e.borderColor)) {
416
+ const o = i.uniforms.uBorderColor.value.w;
417
+ i.uniforms.uBorderColor.value.set(
418
+ e.borderColor[0],
419
+ e.borderColor[1],
420
+ e.borderColor[2],
218
421
  o
219
422
  );
220
- else if (e === "TEXT") {
221
- const l = i;
222
- l.map && l.map.dispose();
223
- const c = I(
224
- r || "",
225
- t,
226
- s,
227
- n,
228
- a
423
+ } else if (typeof e.borderColor == "string") {
424
+ const o = I(e.borderColor);
425
+ i.uniforms.uBorderColor.value.set(
426
+ o.color.r,
427
+ o.color.g,
428
+ o.color.b,
429
+ o.alpha
430
+ );
431
+ } else {
432
+ const o = i.uniforms.uBorderColor.value.w;
433
+ i.uniforms.uBorderColor.value.set(
434
+ e.borderColor.r,
435
+ e.borderColor.g,
436
+ e.borderColor.b,
437
+ o
229
438
  );
230
- l.map = c, l.needsUpdate = !0;
231
439
  }
440
+ e.opacity !== void 0 && (i.uniforms.uOpacity.value = e.opacity), e.bgOpacity !== void 0 && (i.uniforms.uBgColor.value.w = e.bgOpacity), e.borderOpacity !== void 0 && (i.uniforms.uBorderColor.value.w = e.borderOpacity), i.uniforms.uTexture && e.texture !== void 0 && (i.uniforms.uTexture.value = e.texture);
441
+ const t = e.texture !== void 0 ? e.texture : (s = i.uniforms.uTexture) == null ? void 0 : s.value;
442
+ if (t && (t.image instanceof ImageBitmap || t.image instanceof HTMLImageElement || t.image instanceof HTMLCanvasElement)) {
443
+ const o = t.image.width, n = t.image.height, c = (r = e.width) != null ? r : i.uniforms.uSize.value.x, l = (a = e.height) != null ? a : i.uniforms.uSize.value.y;
444
+ if (o && n && c && l) {
445
+ const d = o / n, f = c / l;
446
+ if (d > f) {
447
+ const h = f / d;
448
+ i.uniforms.uTextureRepeat.value.set(h, 1), i.uniforms.uTextureOffset.value.set((1 - h) / 2, 0);
449
+ } else {
450
+ const h = d / f;
451
+ i.uniforms.uTextureRepeat.value.set(1, h), i.uniforms.uTextureOffset.value.set(0, (1 - h) / 2);
452
+ }
453
+ }
454
+ } else
455
+ i.uniforms.uTextureRepeat && (i.uniforms.uTextureRepeat.value.set(1, 1), i.uniforms.uTextureOffset.value.set(0, 0));
456
+ if (e.backgroundImage !== void 0) {
457
+ const o = be(e.backgroundImage);
458
+ if (o) {
459
+ i.uniforms.uGradientCount.value = o.stops.length, i.uniforms.uGradientAngle.value = o.angle;
460
+ for (let n = 0; n < 8; n++)
461
+ if (n < o.stops.length) {
462
+ const c = o.stops[n];
463
+ i.uniforms.uGradientColors.value[n].set(
464
+ c.color.r,
465
+ c.color.g,
466
+ c.color.b,
467
+ c.alpha
468
+ ), console.log(c.color.r, c.color.g, c.color.b), i.uniforms.uGradientStops.value[n] = c.stop;
469
+ } else
470
+ i.uniforms.uGradientColors.value[n].set(0, 0, 0, 0), i.uniforms.uGradientStops.value[n] = 1;
471
+ } else
472
+ i.uniforms.uGradientCount.value = 0;
473
+ }
474
+ }
475
+ function ae(i, e) {
476
+ var n, c, l, d;
477
+ if (e == null) {
478
+ i.set(0, 0, 0, 0);
479
+ return;
480
+ }
481
+ if (typeof e == "number") {
482
+ i.set(e, e, e, e);
483
+ return;
484
+ }
485
+ if (Array.isArray(e)) {
486
+ i.set(e[0], e[1], e[2], e[3]);
487
+ return;
488
+ }
489
+ const t = e.split("/")[0].trim().split(/\s+/), s = F(t[0]), r = F((n = t[1]) != null ? n : t[0]), a = F((c = t[2]) != null ? c : t[0]), o = F((d = (l = t[3]) != null ? l : t[1]) != null ? d : t[0]);
490
+ i.set(s, r, a, o);
491
+ }
492
+ const z = {
493
+ create(i, e, t, s, r, a = 2, o = null, n) {
494
+ return i === "BOX" ? Te(
495
+ e,
496
+ s,
497
+ r,
498
+ o,
499
+ n
500
+ ) : i === "TEXT" ? new pe(
501
+ t || "",
502
+ e,
503
+ s,
504
+ r,
505
+ a
506
+ ) : new m.MeshBasicMaterial({ visible: !1 });
507
+ },
508
+ update(i, e, t, s, r, a, o = 2, n) {
509
+ e === "BOX" ? Se(
510
+ i,
511
+ t,
512
+ r,
513
+ a,
514
+ n
515
+ ) : e === "TEXT" && i.updateText(
516
+ s || "",
517
+ t,
518
+ r,
519
+ a,
520
+ o
521
+ );
522
+ },
523
+ forceUpdateUniforms(i, e) {
524
+ J(i, e);
232
525
  }
233
526
  };
234
- class G {
235
- constructor(e, t, r) {
236
- h(this, "canvas");
237
- h(this, "scene");
238
- h(this, "camera");
239
- h(this, "renderer");
240
- h(this, "renderTarget", null);
241
- h(this, "renderOrder", 0);
242
- h(this, "qualityFactor", 2);
243
- h(this, "mode", "overlay");
244
- h(this, "target");
245
- h(this, "mountContainer");
246
- h(this, "targetRect");
247
- h(this, "meshMap", /* @__PURE__ */ new Map());
248
- var a, o;
249
- this.target = e, this.mountContainer = r, this.mode = (a = t.mode) != null ? a : "overlay", this.canvas = document.createElement("canvas"), this.scene = new d.Scene(), this.targetRect = this.target.getBoundingClientRect();
250
- const s = this.targetRect.width, n = this.targetRect.height;
251
- this.camera = new d.OrthographicCamera(
252
- s / -2,
253
- s / 2,
254
- n / 2,
255
- n / -2,
527
+ class Re {
528
+ constructor(e) {
529
+ u(this, "observer");
530
+ u(this, "textures", /* @__PURE__ */ new WeakMap());
531
+ u(this, "loadStatus", /* @__PURE__ */ new WeakMap());
532
+ u(this, "elementUrls", /* @__PURE__ */ new WeakMap());
533
+ u(this, "onUpdate");
534
+ this.onUpdate = e, this.observer = new IntersectionObserver(
535
+ (t) => {
536
+ for (const s of t) {
537
+ const r = s.target;
538
+ s.isIntersecting ? this.loadTexture(r) : this.disposeTexture(r);
539
+ }
540
+ },
541
+ { rootMargin: "300px" }
542
+ );
543
+ }
544
+ register(e, t) {
545
+ if (e.nodeType !== Node.ELEMENT_NODE)
546
+ return;
547
+ this.elementUrls.get(e) !== t && (this.elementUrls.set(e, t), this.observer.unobserve(e), this.observer.observe(e));
548
+ }
549
+ unregister(e) {
550
+ e.nodeType === Node.ELEMENT_NODE && this.observer.unobserve(e), this.disposeTexture(e), this.elementUrls.delete(e), this.loadStatus.delete(e);
551
+ }
552
+ loadTexture(e) {
553
+ return se(this, null, function* () {
554
+ if (this.loadStatus.get(e) || this.textures.has(e))
555
+ return;
556
+ const t = this.elementUrls.get(e);
557
+ if (t) {
558
+ this.loadStatus.set(e, !0);
559
+ try {
560
+ const r = yield (yield fetch(t)).blob(), a = yield createImageBitmap(r, { imageOrientation: "flipY" });
561
+ if (this.elementUrls.get(e) !== t) {
562
+ a.close();
563
+ return;
564
+ }
565
+ const o = new m.CanvasTexture(a);
566
+ o.needsUpdate = !0, this.textures.set(e, o), this.onUpdate(e, o);
567
+ } catch (s) {
568
+ console.warn("[MirageEngine] Failed to load texture:", t, s);
569
+ } finally {
570
+ this.elementUrls.has(e) && this.loadStatus.set(e, !1);
571
+ }
572
+ }
573
+ });
574
+ }
575
+ disposeTexture(e) {
576
+ const t = this.textures.get(e);
577
+ t && (t.dispose(), this.textures.delete(e), this.onUpdate(e, null)), this.loadStatus.set(e, !1);
578
+ }
579
+ get(e) {
580
+ return this.textures.get(e);
581
+ }
582
+ disposeAll() {
583
+ this.observer.disconnect();
584
+ }
585
+ }
586
+ class Me {
587
+ constructor(e, t, s, r) {
588
+ u(this, "canvas");
589
+ u(this, "scene");
590
+ u(this, "camera");
591
+ u(this, "renderer");
592
+ u(this, "renderTarget", null);
593
+ u(this, "renderOrder", 0);
594
+ u(this, "qualityFactor", 2);
595
+ u(this, "mode", "overlay");
596
+ u(this, "clipArea", 1);
597
+ u(this, "target");
598
+ u(this, "mountContainer");
599
+ u(this, "registry");
600
+ u(this, "targetRect");
601
+ u(this, "travelers", /* @__PURE__ */ new Set());
602
+ u(this, "textureManager");
603
+ // private meshMap: Map<HTMLElement, THREE.Mesh> = new Map();
604
+ u(this, "fixedMeshes", /* @__PURE__ */ new Set());
605
+ var n, c, l;
606
+ this.target = e, this.mountContainer = s, this.registry = r, this.textureManager = new Re((d, f) => {
607
+ const h = this.registry.get(d);
608
+ h && h.material instanceof m.ShaderMaterial && z.forceUpdateUniforms(h.material, { texture: f });
609
+ }), this.mode = (n = t.mode) != null ? n : "overlay", this.clipArea = (c = t.travelerClipArea) != null ? c : 1, this.canvas = document.createElement("canvas"), this.scene = new m.Scene(), this.targetRect = this.target.getBoundingClientRect();
610
+ const a = this.targetRect.width, o = this.targetRect.height;
611
+ this.camera = new m.OrthographicCamera(
612
+ a / -2,
613
+ a / 2,
614
+ o / 2,
615
+ o / -2,
256
616
  1,
257
617
  1e3
258
- ), this.camera.position.z = 100, this.camera.layers.set(0), this.renderer = new d.WebGLRenderer({
618
+ ), this.camera.position.z = 100, this.camera.layers.set(0), this.renderer = new m.WebGLRenderer({
259
619
  canvas: this.canvas,
260
620
  alpha: !0,
261
621
  antialias: !0
262
622
  // [new]
263
623
  // premultipliedAlpha: true
264
- }), this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setSize(s, n), this.applyTextQuality((o = t.quality) != null ? o : "medium");
624
+ }), m.ColorManagement.enabled = !1, this.renderer.outputColorSpace = m.LinearSRGBColorSpace, this.renderer.setPixelRatio(window.devicePixelRatio), this.renderer.setSize(a, o), this.applyTextQuality((l = t.quality) != null ? l : "medium");
265
625
  }
266
626
  createRenderTarget() {
267
- this.renderTarget = new d.WebGLRenderTarget(
627
+ this.renderTarget = new m.WebGLRenderTarget(
268
628
  this.targetRect.width * this.qualityFactor,
269
629
  this.targetRect.height * this.qualityFactor,
270
630
  {
271
- minFilter: d.LinearFilter,
272
- magFilter: d.LinearFilter,
273
- format: d.RGBAFormat,
631
+ minFilter: m.LinearFilter,
632
+ magFilter: m.LinearFilter,
633
+ format: m.RGBAFormat,
274
634
  stencilBuffer: !1,
275
- depthBuffer: !0,
276
- samples: 4
635
+ depthBuffer: !0
636
+ // samples: 0.7,
277
637
  }
278
638
  );
279
639
  }
@@ -302,7 +662,7 @@ class G {
302
662
  this.canvas.style.width = `${this.targetRect.width}px`, this.canvas.style.height = `${this.targetRect.height}px`, this.mode === "duplicate" ? (this.canvas.style.position = "", this.canvas.style.top = "", this.canvas.style.left = "", this.canvas.style.display = "block") : (this.canvas.style.position = "absolute", this.canvas.style.top = `${this.target.offsetTop}px`, this.canvas.style.left = `${this.target.offsetLeft}px`, this.canvas.style.display = "block");
303
663
  }
304
664
  dispose() {
305
- this.renderer.dispose(), this.canvas.remove();
665
+ this.renderer.dispose(), this.canvas.remove(), this.textureManager.disposeAll();
306
666
  }
307
667
  setSize(e, t) {
308
668
  this.renderer.setSize(e, t), this.renderTarget && this.renderTarget.setSize(
@@ -310,72 +670,95 @@ class G {
310
670
  t * this.qualityFactor
311
671
  ), this.camera.left = e / -2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = t / -2, this.camera.updateProjectionMatrix();
312
672
  }
313
- syncScene(e) {
314
- const t = this.target.getBoundingClientRect(), r = Math.abs(t.width - this.targetRect.width) > 0.1 || Math.abs(t.height - this.targetRect.height) > 0.1, s = this.mode === "overlay" && (Math.abs(t.top - this.targetRect.top) > 0.1 || Math.abs(t.left - this.targetRect.left) > 0.1);
315
- r ? (this.targetRect = t, this.setSize(this.targetRect.width, this.targetRect.height), this.updateCanvasLayout()) : s ? (this.targetRect = t, this.updateCanvasLayout()) : this.targetRect = t, this.renderOrder = 0;
316
- const n = /* @__PURE__ */ new Set();
317
- this.reconcileNode(e, n);
318
- for (const [a, o] of this.meshMap.entries())
319
- n.has(a) || (this.scene.remove(o), o.geometry.dispose(), o.material instanceof d.Material && o.material.dispose(), this.meshMap.delete(a));
673
+ syncScene(e, t) {
674
+ const s = this.target.getBoundingClientRect(), r = Math.abs(s.width - this.targetRect.width) > 0.1 || Math.abs(s.height - this.targetRect.height) > 0.1, a = this.mode === "overlay" && (Math.abs(s.top - this.targetRect.top) > 0.1 || Math.abs(s.left - this.targetRect.left) > 0.1);
675
+ r ? (this.targetRect = s, this.setSize(this.targetRect.width, this.targetRect.height), this.updateCanvasLayout()) : a ? (this.targetRect = s, this.updateCanvasLayout()) : this.targetRect = s, this.renderOrder = 0, this.reconcileNode(e), t.size > 0 && t.forEach((o) => {
676
+ const n = this.registry.get(o);
677
+ n && (this.scene.remove(n), this.travelers.delete(n), this.fixedMeshes.delete(n), n.geometry.dispose(), n.traverse((c) => {
678
+ c instanceof m.Mesh && (c.geometry && c.geometry.dispose(), c.material && (Array.isArray(c.material) ? c.material.forEach((l) => l.dispose()) : c.material.dispose()));
679
+ }), this.registry.remove(o), this.textureManager.unregister(o));
680
+ });
320
681
  }
321
- reconcileNode(e, t) {
682
+ // 탐색 후 완성된 Scene node를 이용하여 mesh를 만들거나 조정
683
+ // => 이 과정에서 scene node에 있는 ele를 넣은 hash => activeElements
684
+ // => 이후 activeElements를 이용하여 mesh를 정리!!!+ map에서도 삭제
685
+ // private reconcileNode(node: SceneNode, activeElements: Set<HTMLElement>) {
686
+ reconcileNode(e) {
322
687
  var s;
323
- t.add(e.element);
324
- let r = this.meshMap.get(e.element);
325
- if (!r) {
326
- const n = new d.PlaneGeometry(1, 1);
688
+ let t = this.registry.get(e.element);
689
+ if (!t) {
690
+ const r = new m.PlaneGeometry(1, 1);
327
691
  let a;
328
- a = F.create(
692
+ const o = e.isTraveler ? (s = this.renderTarget) == null ? void 0 : s.texture : this.textureManager.get(e.element);
693
+ a = z.create(
329
694
  "BOX",
330
695
  e.styles,
331
696
  "",
332
697
  e.rect.width,
333
698
  e.rect.height,
334
699
  this.qualityFactor,
335
- e.isTraveler ? (s = this.renderTarget) == null ? void 0 : s.texture : void 0
336
- ), r = new d.Mesh(n, a), e.type === "TEXT" && (r.name = "BG_MESH"), this.scene.add(r), this.meshMap.set(e.element, r);
700
+ o,
701
+ e.shaderHooks
702
+ ), t = new m.Mesh(r, a), e.type === "TEXT" && (t.name = "BG_MESH"), this.scene.add(t), this.registry.register(e.element, t);
337
703
  }
338
- if (r.userData.domRect = e.rect, this.updateMeshProperties(r, e), this.updateMeshLayers(r, e), e.isTraveler && r.layers.enable(28), e.type === "BOX")
339
- for (const n of e.children)
340
- this.reconcileNode(n, t);
704
+ if (t.userData.domRect = e.rect, this.updateMeshProperties(t, e), this.updateMeshLayers(t, e), e.isTraveler ? (t.layers.enable(28), this.travelers.add(t)) : (t.layers.disable(28), this.travelers.delete(t)), e.isFixed ? this.fixedMeshes.add(t) : this.fixedMeshes.delete(t), e.styles.imageSrc ? this.textureManager.register(e.element, e.styles.imageSrc) : this.textureManager.unregister(e.element), e.type === "BOX")
705
+ for (const r of e.children)
706
+ this.reconcileNode(r);
341
707
  else
342
- e.type === "TEXT" && this.reconcileTextChild(r, e);
708
+ e.type === "TEXT" && this.reconcileTextChild(t, e);
343
709
  }
344
710
  reconcileTextChild(e, t) {
345
- var o, l;
346
- let r = e.children.find(
347
- (c) => c.name === "TEXT_CHILD"
348
- );
349
- const s = JSON.stringify(t.textStyles), n = (o = r == null ? void 0 : r.userData) == null ? void 0 : o.styleHash;
350
- if (!r || t.dirtyMask & _ || s !== n) {
351
- r && ((l = r.material.map) == null || l.dispose(), r.geometry.dispose(), e.remove(r));
352
- const c = F.create(
353
- "TEXT",
354
- t.textStyles,
355
- t.textContent || "",
356
- t.rect.width,
357
- t.rect.height,
358
- this.qualityFactor
359
- ), g = new d.PlaneGeometry(1, 1);
360
- r = new d.Mesh(g, c), r.name = "TEXT_CHILD", r.userData = { styleHash: s }, this.updateMeshLayers(r, t), r.position.z = 5e-3, e.add(r);
361
- }
362
- if (r) {
363
- const c = e.userData.domRect, g = c.x + c.width / 2, u = c.y + c.height / 2, p = t.rect.x + t.rect.width / 2, m = t.rect.y + t.rect.height / 2, T = p - g, v = -(m - u);
364
- r.position.set(T, v, 5e-3);
711
+ var n;
712
+ const s = t.textLines || [{ text: t.textContent || "", rect: t.rect }], r = JSON.stringify(t.textStyles) + t.textContent + s.map((c) => c.text).join("|"), a = (n = e.userData) == null ? void 0 : n.textChildStyleHash;
713
+ if (t.dirtyMask & $ || r !== a) {
714
+ e.children.filter((h) => h.name.startsWith("TEXT_CHILD")).forEach((h) => {
715
+ var g;
716
+ const p = h;
717
+ (g = p.material.map) == null || g.dispose(), p.geometry.dispose(), e.remove(p);
718
+ });
719
+ const l = t.rect, d = l.x + l.width / 2, f = l.y + l.height / 2;
720
+ s.forEach((h, p) => {
721
+ const g = z.create(
722
+ "TEXT",
723
+ t.textStyles,
724
+ h.text,
725
+ h.rect.width,
726
+ h.rect.height,
727
+ this.qualityFactor
728
+ ), y = new m.PlaneGeometry(1, 1), x = new m.Mesh(y, g);
729
+ x.name = `TEXT_CHILD_${p}`, this.updateMeshLayers(x, t);
730
+ const T = t.rect.width === 0 ? 1 : h.rect.width / t.rect.width, S = t.rect.height === 0 ? 1 : h.rect.height / t.rect.height;
731
+ x.scale.set(T, S, 1);
732
+ const M = h.rect.x + h.rect.width / 2, E = h.rect.y + h.rect.height / 2, b = M - d, w = -(E - f);
733
+ x.position.set(
734
+ t.rect.width === 0 ? 0 : b / t.rect.width,
735
+ t.rect.height === 0 ? 0 : w / t.rect.height,
736
+ 5e-3
737
+ ), e.add(x);
738
+ }), e.userData.textChildStyleHash = r;
365
739
  }
366
740
  }
367
741
  updateMeshProperties(e, t) {
368
- var m;
369
- const { rect: r, styles: s } = t, n = this.renderer.getPixelRatio(), a = this.renderer.domElement.width / n, o = this.renderer.domElement.height / n;
370
- e.scale.set(r.width, r.height, 1);
371
- const l = 1e-3;
742
+ var b;
743
+ const { rect: s, styles: r } = t, a = this.renderer.getPixelRatio(), o = this.renderer.domElement.width / a, n = this.renderer.domElement.height / a;
744
+ e.scale.set(s.width, s.height, 1);
745
+ const c = 1e-3;
372
746
  this.renderOrder++;
373
- const c = this.targetRect.left + window.scrollX, g = this.targetRect.top + window.scrollY, u = r.x - c, p = r.y - g;
747
+ const l = this.targetRect.left + window.scrollX, d = this.targetRect.top + window.scrollY, f = s.x - l, h = s.y - d, p = f - o / 2 + s.width / 2, g = -h + n / 2 - s.height / 2;
374
748
  e.position.set(
375
- u - a / 2 + r.width / 2,
376
- -p + o / 2 - r.height / 2,
377
- s.zIndex + this.renderOrder * l
378
- ), F.update(
749
+ p,
750
+ g,
751
+ r.zIndex + this.renderOrder * c
752
+ );
753
+ const y = s.x, x = s.y;
754
+ e.userData.basePosition = { x: p, y: g }, e.userData.originalBasePosition = { x: p, y: g }, e.userData.baseSize = { width: s.width, height: s.height }, e.userData.baseDOM = { x: y, y: x }, e.userData.isFixed = t.isFixed, e.userData.initialScroll = { x: window.scrollX, y: window.scrollY };
755
+ const T = t.element.nodeType === Node.TEXT_NODE ? t.element.parentElement : t.element, S = window.getComputedStyle(T);
756
+ let M = 0, E = 0;
757
+ if (S.transform && S.transform !== "none") {
758
+ const w = new DOMMatrix(S.transform);
759
+ M = w.m41, E = w.m42;
760
+ }
761
+ e.userData.baseTransform = { x: M, y: E }, delete e.userData.originRatioX, delete e.userData.originRatioY, z.update(
379
762
  e.material,
380
763
  "BOX",
381
764
  t.styles,
@@ -383,28 +766,28 @@ class G {
383
766
  t.rect.width,
384
767
  t.rect.height,
385
768
  this.qualityFactor,
386
- t.isTraveler ? (m = this.renderTarget) == null ? void 0 : m.texture : void 0
769
+ t.isTraveler ? (b = this.renderTarget) == null ? void 0 : b.texture : this.textureManager.get(t.element)
387
770
  );
388
771
  }
389
772
  updateMeshLayers(e, t) {
390
- const r = (1 - (t.visibility & x)) * 30;
391
- e.layers.set(r), t.visibility === (x | R) && e.layers.enable(29);
773
+ const s = (1 - (t.visibility & D)) * 30;
774
+ e.layers.set(s), t.visibility === (D | X) && e.layers.enable(29);
392
775
  }
393
776
  captureRenderTarget() {
394
- const e = [];
395
- for (const l of this.meshMap.values())
396
- l.layers.mask & 1 << 28 && e.push(l);
397
- if (e.length === 0)
777
+ if (this.travelers.size === 0)
398
778
  return;
399
- const t = new d.Color(), r = this.renderer.getClearAlpha();
400
- this.renderer.getClearColor(t), this.renderer.setClearColor(0, 0), this.renderer.setRenderTarget(this.renderTarget), this.renderer.clear(), this.renderer.autoClear = !1, this.renderer.setScissorTest(!0), this.camera.layers.set(29);
401
- const s = new d.Vector3(), n = this.targetRect.width, a = this.targetRect.height, o = this.renderer.getPixelRatio();
402
- for (const l of e) {
403
- s.setFromMatrixPosition(l.matrixWorld), s.project(this.camera);
404
- const c = (s.x + 1) / 2 * n, g = (s.y + 1) / 2 * a, u = l.scale.x, p = l.scale.y, m = c - u / 2, T = g - p / 2, v = m * this.qualityFactor / o, B = T * this.qualityFactor / o, b = u * this.qualityFactor / o, f = p * this.qualityFactor / o;
405
- this.renderer.setScissor(v, B, b, f), this.renderer.render(this.scene, this.camera);
779
+ const e = new m.Color(), t = this.renderer.getClearAlpha();
780
+ this.renderer.getClearColor(e), this.renderer.setClearColor(0, 0), this.renderer.setRenderTarget(this.renderTarget), this.renderer.clear(), this.renderer.autoClear = !1, this.renderer.setScissorTest(!0), this.camera.layers.set(29);
781
+ const s = new m.Vector3(), r = this.targetRect.width, a = this.targetRect.height, o = this.renderer.getPixelRatio();
782
+ for (const n of this.travelers) {
783
+ s.setFromMatrixPosition(n.matrixWorld), s.project(this.camera);
784
+ const c = (s.x + 1) / 2 * r, l = (s.y + 1) / 2 * a;
785
+ let d = 0, f = 1;
786
+ typeof this.clipArea == "number" ? f = this.clipArea : this.clipArea.endsWith("%") ? f = parseFloat(this.clipArea) / 100 : this.clipArea.endsWith("px") && (d = parseFloat(this.clipArea));
787
+ const h = n.scale.x * f + 0.5, p = n.scale.y * f + 0.5, g = c - h / 2, y = l - p / 2, x = (g * this.qualityFactor - d) / o, T = (y * this.qualityFactor - d) / o, S = (h * this.qualityFactor + d * 2) / o, M = (p * this.qualityFactor + d * 2) / o;
788
+ this.renderer.setScissor(x, T, S, M), this.renderer.render(this.scene, this.camera);
406
789
  }
407
- this.renderer.setScissorTest(!1), this.renderer.autoClear = !0, this.renderer.setRenderTarget(null), this.camera.layers.set(28), this.renderer.setClearColor(t, r);
790
+ this.renderer.setScissorTest(!1), this.renderer.autoClear = !0, this.renderer.setRenderTarget(null), this.camera.layers.set(0), this.renderer.setClearColor(e, t);
408
791
  }
409
792
  render() {
410
793
  this.renderTarget && this.captureRenderTarget(), this.renderer.render(this.scene, this.camera);
@@ -413,166 +796,302 @@ class G {
413
796
  showScissoredRenderTarget() {
414
797
  if (!this.renderTarget)
415
798
  return;
416
- const e = this.targetRect.width, t = this.targetRect.height, r = new d.PlaneGeometry(e, t), s = new d.MeshBasicMaterial({
799
+ const e = this.targetRect.width, t = this.targetRect.height, s = new m.PlaneGeometry(e, t), r = new m.MeshBasicMaterial({
417
800
  map: this.renderTarget.texture,
418
- side: d.DoubleSide,
801
+ side: m.DoubleSide,
419
802
  transparent: !0,
420
803
  opacity: 0.8
421
- }), n = new d.Mesh(r, s);
422
- n.position.set(0, 0, 90), n.layers.set(28), this.scene.add(n);
804
+ }), a = new m.Mesh(s, r);
805
+ a.position.set(0, 0, 90), a.layers.set(28), this.scene.add(a);
423
806
  }
424
807
  }
425
- function J(i) {
426
- const e = document.createRange();
427
- e.selectNodeContents(i);
428
- const t = e.getBoundingClientRect();
429
- return {
430
- left: t.left,
431
- top: t.top,
432
- width: t.width,
433
- height: t.height
434
- };
808
+ function Ee(i) {
809
+ const e = i.textContent || "", t = [];
810
+ let s = "", r = null, a = -1;
811
+ const o = (l, d) => {
812
+ for (let f = 0; f < l.length; f++) {
813
+ const h = l[f], p = document.createRange();
814
+ p.setStart(i, d + f), p.setEnd(i, d + f + 1);
815
+ const g = p.getBoundingClientRect();
816
+ if (g.width === 0 && g.height === 0) {
817
+ s += h;
818
+ continue;
819
+ }
820
+ a === -1 || Math.abs(g.top - a) > g.height / 2 ? (s && r && t.push({
821
+ text: s,
822
+ rect: {
823
+ left: r.left,
824
+ top: r.top,
825
+ width: r.right - r.left,
826
+ height: r.bottom - r.top
827
+ }
828
+ }), s = h, r = { left: g.left, top: g.top, right: g.right, bottom: g.bottom }, a = g.top) : (s += h, r && (r.left = Math.min(r.left, g.left), r.top = Math.min(r.top, g.top), r.right = Math.max(r.right, g.right), r.bottom = Math.max(r.bottom, g.bottom)));
829
+ }
830
+ }, n = e.match(/[^\s\-]+\-?|\-|\s+/g) || [];
831
+ let c = 0;
832
+ for (const l of n) {
833
+ const d = document.createRange();
834
+ d.setStart(i, c), d.setEnd(i, c + l.length);
835
+ const f = d.getClientRects();
836
+ if (f.length > 1)
837
+ o(l, c);
838
+ else {
839
+ const h = f.length === 1 ? f[0] : d.getBoundingClientRect();
840
+ if (h.width === 0 && h.height === 0) {
841
+ s += l, c += l.length;
842
+ continue;
843
+ }
844
+ a === -1 || Math.abs(h.top - a) > h.height / 2 ? (s && r && t.push({
845
+ text: s,
846
+ rect: {
847
+ left: r.left,
848
+ top: r.top,
849
+ width: r.right - r.left,
850
+ height: r.bottom - r.top
851
+ }
852
+ }), s = l, r = { left: h.left, top: h.top, right: h.right, bottom: h.bottom }, a = h.top) : (s += l, r && (r.left = Math.min(r.left, h.left), r.top = Math.min(r.top, h.top), r.right = Math.max(r.right, h.right), r.bottom = Math.max(r.bottom, h.bottom)));
853
+ }
854
+ c += l.length;
855
+ }
856
+ return s && r && t.push({
857
+ text: s,
858
+ rect: {
859
+ left: r.left,
860
+ top: r.top,
861
+ width: r.right - r.left,
862
+ height: r.bottom - r.top
863
+ }
864
+ }), t.filter((l) => l.text.trim().length > 0 && l.rect.width > 0 && l.rect.height > 0);
435
865
  }
436
- function V(i) {
866
+ function De(i) {
437
867
  const e = parseFloat(i.fontSize);
438
868
  let t = parseFloat(i.lineHeight);
439
869
  isNaN(t) && (t = e * 1.2);
440
- let r = parseFloat(i.letterSpacing);
441
- return isNaN(r) && (r = 0), {
870
+ let s = parseFloat(i.letterSpacing);
871
+ return isNaN(s) && (s = 0), {
442
872
  font: `${i.fontStyle} ${i.fontWeight} ${i.fontSize} ${i.fontFamily}`,
873
+ fontSize: i.fontSize,
443
874
  color: i.color,
444
875
  textAlign: i.textAlign || "start",
445
876
  textBaseline: "alphabetic",
446
877
  direction: i.direction || "inherit",
447
878
  lineHeight: t,
448
- letterSpacing: r
879
+ letterSpacing: s
449
880
  };
450
881
  }
451
- function A(i, e = O | z | q | _ | D, t, r) {
882
+ function ce(i, e = B | N | fe | $ | V, t, s) {
452
883
  if (i.nodeType === Node.TEXT_NODE) {
453
- const f = i;
454
- if (!f.textContent || !f.textContent.trim())
884
+ const b = i;
885
+ if (!b.textContent || !b.textContent.trim())
886
+ return null;
887
+ const w = b.textContent.replace(/\s+/g, " ");
888
+ if (w.length === 0)
455
889
  return null;
456
- const C = f.textContent.replace(/\s+/g, " ").trim();
457
- if (C.length === 0)
890
+ const R = Ee(b);
891
+ if (R.length === 0)
458
892
  return null;
459
- const y = J(f);
460
- if (y.width === 0 || y.height === 0)
893
+ const k = b.parentElement, O = k ? window.getComputedStyle(k) : null;
894
+ if (!O)
461
895
  return null;
462
- const L = f.parentElement, M = L ? window.getComputedStyle(L) : null;
463
- return M ? {
896
+ const A = Math.min(...R.map((v) => v.rect.left)), L = Math.min(...R.map((v) => v.rect.top)), P = Math.max(...R.map((v) => v.rect.left + v.rect.width)), Y = Math.max(...R.map((v) => v.rect.top + v.rect.height));
897
+ return {
464
898
  id: Math.random().toString(36).substring(2, 9),
465
899
  type: "TEXT",
466
- element: f,
900
+ element: b,
467
901
  rect: {
468
- x: y.left + window.scrollX,
469
- y: y.top + window.scrollY,
470
- width: y.width,
471
- height: y.height
902
+ x: A + window.scrollX,
903
+ y: L + window.scrollY,
904
+ width: P - A,
905
+ height: Y - L
472
906
  },
473
907
  styles: {
474
908
  backgroundColor: "transparent",
475
- opacity: parseFloat(M.opacity),
909
+ backgroundImage: "",
910
+ opacity: k && k.dataset.mirageDom === "hide" ? 1 : parseFloat(O.opacity),
476
911
  zIndex: 0,
477
912
  borderRadius: "0px",
478
913
  borderColor: "transparent",
479
- borderWidth: "0px"
914
+ borderWidth: "0px",
915
+ isTraveler: !1
480
916
  },
481
- textContent: C,
482
- textStyles: V(M),
917
+ textContent: w,
918
+ textLines: R.map((v) => ({
919
+ text: v.text.trim(),
920
+ rect: {
921
+ x: v.rect.left + window.scrollX,
922
+ y: v.rect.top + window.scrollY,
923
+ width: v.rect.width,
924
+ height: v.rect.height
925
+ }
926
+ })),
927
+ textStyles: De(O),
483
928
  dirtyMask: e,
484
929
  visibility: t,
485
930
  isTraveler: !1,
931
+ isFixed: O.position === "fixed",
486
932
  children: []
487
- } : null;
488
- }
489
- const s = i, n = s.dataset.mirageFilter;
490
- let a = t, o = t;
491
- if (n) {
492
- const f = new Set(n.split(/\s+/));
493
- for (const C of f)
494
- if (!k.includes(C))
933
+ };
934
+ }
935
+ if (i.nodeType !== Node.ELEMENT_NODE)
936
+ return null;
937
+ const r = i, a = r.dataset.mirageFilter;
938
+ let o = t, n = t;
939
+ if (a) {
940
+ const b = new Set(a.split(/\s+/));
941
+ for (const w of b)
942
+ if (!ge.includes(w))
495
943
  throw new Error(
496
- `[MirageEngine] Invalid filter token: '${C}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
944
+ `[MirageEngine] Invalid filter token: '${w}'. Expected one of: 'include-tree', 'exclude-tree', 'include-self', 'exclude-self', 'end'.`
497
945
  );
498
- if (f.has("end"))
946
+ if (b.has("end"))
499
947
  return null;
500
- if (f.has("include-tree") && f.has("exclude-tree"))
948
+ if (b.has("include-tree") && b.has("exclude-tree"))
501
949
  throw new Error(
502
950
  "[MirageEngine] Conflicting filters: 'include-tree' and 'exclude-tree' cannot be used together on the same element."
503
951
  );
504
- if (f.has("include-self") && f.has("exclude-self"))
952
+ if (b.has("include-self") && b.has("exclude-self"))
505
953
  throw new Error(
506
954
  "[MirageEngine] Conflicting filters: 'include-self' and 'exclude-self' cannot be used together on the same element."
507
955
  );
508
- f.has("include-tree") ? a = a | x : f.has("exclude-tree") && (a = a & ~x), o = a, f.has("include-self") ? o = o | x : f.has("exclude-self") && (o = o & ~x);
509
- }
510
- o = o | t & R;
511
- const l = s.dataset.mirageTravel;
512
- let c = !1;
513
- l && new Set(l.split(/\s+/)).has("traveler") && (o = o & ~R, a = a & ~R, c = !0);
514
- const g = s.getBoundingClientRect(), u = window.getComputedStyle(s);
515
- if (g.width === 0 || g.height === 0 || u.display === "none")
956
+ b.has("include-tree") ? o = o | D : b.has("exclude-tree") && (o = o & ~D), n = o, b.has("include-self") ? n = n | D : b.has("exclude-self") && (n = n & ~D);
957
+ }
958
+ n = n | t & X;
959
+ const c = r.dataset.mirageTravel;
960
+ let l = !1;
961
+ c && new Set(c.split(/\s+/)).has("traveler") && (n = n & ~X, o = o & ~X, l = !0);
962
+ const d = r.dataset.mirageShader;
963
+ let f;
964
+ d && (f = JSON.parse(d));
965
+ const h = r.getBoundingClientRect(), p = window.getComputedStyle(r);
966
+ if (h.width === 0 || h.height === 0 || p.display === "none")
516
967
  return null;
517
- let p = s.getAttribute("data-mid");
518
- p || (p = Math.random().toString(36).substring(2, 11), s.setAttribute("data-mid", p));
519
- const m = parseInt(u.zIndex), T = {
520
- backgroundColor: u.backgroundColor,
521
- opacity: parseFloat(u.opacity),
522
- zIndex: isNaN(m) ? 0 : m,
523
- borderRadius: u.borderRadius,
524
- borderColor: u.borderColor,
525
- borderWidth: u.borderWidth
968
+ let g = r.getAttribute("data-mid");
969
+ g || (g = Math.random().toString(36).substring(2, 11), r.setAttribute("data-mid", g));
970
+ const y = parseInt(p.zIndex);
971
+ let x;
972
+ if (r.tagName === "IMG")
973
+ x = r.src;
974
+ else if (p.backgroundImage && p.backgroundImage !== "none") {
975
+ const b = p.backgroundImage.match(/url\(['"]?(.*?)['"]?\)/);
976
+ b && (x = b[1]);
977
+ }
978
+ const T = {
979
+ backgroundColor: p.backgroundColor,
980
+ backgroundImage: p.backgroundImage,
981
+ opacity: r.dataset.mirageDom === "hide" ? 1 : parseFloat(p.opacity),
982
+ zIndex: isNaN(y) ? 0 : y,
983
+ borderRadius: p.borderRadius,
984
+ borderColor: p.borderColor,
985
+ borderWidth: p.borderWidth,
986
+ imageSrc: x,
987
+ isTraveler: l
526
988
  };
527
- let v, B;
528
- const b = [];
529
- return Array.from(s.childNodes).forEach((f) => {
530
- const C = f.nodeType === Node.TEXT_NODE ? o : a, y = A(
531
- f,
989
+ let S, M;
990
+ const E = [];
991
+ return Array.from(r.childNodes).forEach((b) => {
992
+ const w = b.nodeType === Node.TEXT_NODE ? n : o, R = ce(
993
+ b,
532
994
  e,
533
- C
995
+ w
534
996
  );
535
- y && b.push(y);
997
+ R && E.push(R);
536
998
  }), {
537
- id: p,
999
+ id: g,
538
1000
  type: "BOX",
539
- element: s,
1001
+ element: r,
540
1002
  rect: {
541
- x: g.left + window.scrollX,
542
- y: g.top + window.scrollY,
543
- width: g.width,
544
- height: g.height
1003
+ x: h.left + window.scrollX,
1004
+ y: h.top + window.scrollY,
1005
+ width: h.width,
1006
+ height: h.height
545
1007
  },
546
1008
  styles: T,
547
- textContent: v,
548
- textStyles: B,
1009
+ textContent: S,
1010
+ textStyles: M,
549
1011
  dirtyMask: e,
550
- visibility: o,
551
- isTraveler: c,
552
- children: b
1012
+ visibility: n,
1013
+ isTraveler: l,
1014
+ isFixed: p.position === "fixed",
1015
+ children: E,
1016
+ shaderHooks: f
553
1017
  };
554
1018
  }
555
- class j {
556
- constructor(e, t, r) {
557
- h(this, "target");
558
- h(this, "renderer");
559
- h(this, "filter");
560
- h(this, "observer");
561
- h(this, "isDomDirty", !1);
562
- h(this, "isRunning", !1);
563
- h(this, "isTravelEnabled", !1);
564
- h(this, "pendingMask", E);
565
- h(this, "mutationTimer", null);
566
- h(this, "cssTimer", null);
567
- h(this, "resizeConfig");
568
- h(this, "resizeTimer", null);
569
- h(this, "isResizing", !1);
570
- h(this, "onTransitionFinished", (e) => {
571
- this.target.contains(e.target) && this.mutationTimer === null && (this.cssTimer && clearTimeout(this.cssTimer), this.pendingMask |= O | z, this.cssTimer = window.setTimeout(() => {
1019
+ function ke(i, e) {
1020
+ e.size !== 0 && e.forEach((t, s) => {
1021
+ var b, w, R, k, O, A, L, P, Y, v, j, Q, Z, K, ee, te, re, ie;
1022
+ const r = i.get(s);
1023
+ if (!r || !r.userData.basePosition)
1024
+ return;
1025
+ let { x: a, y: o } = r.userData.basePosition;
1026
+ const { width: n, height: c } = r.userData.baseSize, l = (b = t.width) != null ? b : n, d = (w = t.height) != null ? w : c, f = l - n, h = d - c;
1027
+ if (t.width !== void 0 && r.userData.originRatioX === void 0 && Math.abs(f) > 0.1) {
1028
+ const U = s.getBoundingClientRect(), W = (R = t.x) != null ? R : 0, G = (O = (k = r.userData.baseTransform) == null ? void 0 : k.x) != null ? O : 0, q = r.userData.isFixed ? 0 : window.scrollX;
1029
+ let C = -(U.left + q - W + G - r.userData.baseDOM.x) / f;
1030
+ Math.abs(C) < 0.05 ? C = 0 : Math.abs(C - 1) < 0.05 ? C = 1 : Math.abs(C - 0.5) < 0.05 && (C = 0.5), r.userData.originRatioX = C;
1031
+ }
1032
+ if (t.height !== void 0 && r.userData.originRatioY === void 0 && Math.abs(h) > 0.1) {
1033
+ const U = s.getBoundingClientRect(), W = (A = t.y) != null ? A : 0, G = (P = (L = r.userData.baseTransform) == null ? void 0 : L.y) != null ? P : 0, q = r.userData.isFixed ? 0 : window.scrollY;
1034
+ let C = -(U.top + q - W + G - r.userData.baseDOM.y) / h;
1035
+ Math.abs(C) < 0.05 ? C = 0 : Math.abs(C - 1) < 0.05 ? C = 1 : Math.abs(C - 0.5) < 0.05 && (C = 0.5), r.userData.originRatioY = C;
1036
+ }
1037
+ const p = (Y = r.userData.originRatioX) != null ? Y : 0.5, g = (v = r.userData.originRatioY) != null ? v : 0.5, y = f * (0.5 - p), x = h * (0.5 - g), T = (Q = (j = r.userData.baseTransform) == null ? void 0 : j.x) != null ? Q : 0, S = (K = (Z = r.userData.baseTransform) == null ? void 0 : Z.y) != null ? K : 0, M = ((ee = t.x) != null ? ee : T) - T, E = ((te = t.y) != null ? te : S) - S;
1038
+ r.position.setX(a + y + M), r.position.setY(o - (x + E)), r.scale.set(l, d, 1), z.forceUpdateUniforms(r.material, {
1039
+ backgroundColor: t.backgroundColor,
1040
+ backgroundImage: t.backgroundImage,
1041
+ opacity: t.opacity,
1042
+ borderRadius: (ie = t.borderRadius) != null ? ie : (re = r.userData.baseStyles) == null ? void 0 : re.borderRadius,
1043
+ width: l,
1044
+ height: d
1045
+ });
1046
+ });
1047
+ }
1048
+ function Oe(i, e, t) {
1049
+ i.forEach((s) => {
1050
+ if (s.userData.isFixed && s.userData.initialScroll && s.userData.originalBasePosition) {
1051
+ const r = e - s.userData.initialScroll.x, a = t - s.userData.initialScroll.y;
1052
+ s.userData.basePosition.x = s.userData.originalBasePosition.x + r, s.userData.basePosition.y = s.userData.originalBasePosition.y - a, s.position.x = s.userData.basePosition.x, s.position.y = s.userData.basePosition.y;
1053
+ }
1054
+ });
1055
+ }
1056
+ function Be(i) {
1057
+ const e = {};
1058
+ if (i.opacity && (e.opacity = parseFloat(i.opacity)), i.backgroundColor && i.backgroundColor !== "rgba(0, 0, 0, 0)") {
1059
+ const t = I(i.backgroundColor);
1060
+ e.backgroundColor = [t.color.r, t.color.g, t.color.b];
1061
+ }
1062
+ if (i.backgroundImage ? e.backgroundImage = i.backgroundImage : i.background && (e.backgroundImage = i.background), i.borderRadius && (e.borderRadius = parseFloat(i.borderRadius)), i.width && (e.width = parseFloat(i.width)), i.height && (e.height = parseFloat(i.height)), i.transform && i.transform !== "none") {
1063
+ const t = new DOMMatrix(i.transform);
1064
+ e.x = t.m41, e.y = t.m42, e.z = t.m43;
1065
+ }
1066
+ return e;
1067
+ }
1068
+ class Fe {
1069
+ constructor(e, t, s, r) {
1070
+ u(this, "target");
1071
+ u(this, "renderer");
1072
+ u(this, "registry");
1073
+ u(this, "filter");
1074
+ u(this, "observer");
1075
+ u(this, "pendingDeletions", /* @__PURE__ */ new Set());
1076
+ u(this, "pendingStyles", /* @__PURE__ */ new Map());
1077
+ u(this, "isDomDirty", !1);
1078
+ u(this, "isRunning", !1);
1079
+ u(this, "isTravelEnabled", !1);
1080
+ u(this, "pendingMask", _);
1081
+ u(this, "mutationTimer", null);
1082
+ u(this, "cssTimer", null);
1083
+ u(this, "resizeConfig");
1084
+ u(this, "resizeTimer", null);
1085
+ u(this, "isResizing", !1);
1086
+ u(this, "lastScrollX", 0);
1087
+ u(this, "lastScrollY", 0);
1088
+ u(this, "scrollTimer", null);
1089
+ u(this, "onTransitionFinished", (e) => {
1090
+ this.target.contains(e.target) && this.mutationTimer === null && (this.cssTimer && clearTimeout(this.cssTimer), this.pendingStyles.size == 0 && (this.pendingMask |= B | N, this.cssTimer = window.setTimeout(() => {
572
1091
  this.isDomDirty = !0, this.cssTimer = null;
573
- }, 50));
1092
+ }, 50)));
574
1093
  });
575
- h(this, "onWindowResize", () => {
1094
+ u(this, "onWindowResize", () => {
576
1095
  if (!this.resizeConfig.enabled) {
577
1096
  this.isDomDirty = !0;
578
1097
  return;
@@ -581,24 +1100,42 @@ class j {
581
1100
  this.isDomDirty = !0, this.resizeConfig.onEnd && this.resizeConfig.onEnd(), this.isResizing = !1, this.resizeTimer = null;
582
1101
  }, this.resizeConfig.delay);
583
1102
  });
584
- h(this, "renderLoop", () => {
585
- this.isRunning && (this.isDomDirty && this.forceUpdateScene(), this.renderer.render(), requestAnimationFrame(this.renderLoop));
1103
+ u(this, "renderLoop", () => {
1104
+ if (!this.isRunning)
1105
+ return;
1106
+ this.isDomDirty && this.forceUpdateScene();
1107
+ const e = window.scrollX, t = window.scrollY;
1108
+ (e !== this.lastScrollX || t !== this.lastScrollY) && (Oe(this.renderer.fixedMeshes, e, t), this.lastScrollX = e, this.lastScrollY = t, this.scrollTimer && clearTimeout(this.scrollTimer), this.scrollTimer = window.setTimeout(() => {
1109
+ this.pendingMask |= B, this.isDomDirty = !0, this.scrollTimer = null;
1110
+ }, 150)), this.pendingStyles.size > 0 && (ke(this.registry, this.pendingStyles), this.pendingStyles.clear()), this.renderer.render(), requestAnimationFrame(this.renderLoop);
586
1111
  });
587
- var n, a;
588
- this.target = e, this.renderer = t, this.filter = r.filter;
589
- const s = (n = r.resizeDebounce) != null ? n : !0;
590
- s === !1 ? this.resizeConfig = { enabled: !1, delay: 0 } : s === !0 ? this.resizeConfig = { enabled: !0, delay: 150 } : this.resizeConfig = {
1112
+ var o, n;
1113
+ this.target = e, this.renderer = t, this.registry = s, this.filter = r.filter;
1114
+ const a = (o = r.resizeDebounce) != null ? o : !0;
1115
+ a === !1 ? this.resizeConfig = { enabled: !1, delay: 0 } : a === !0 ? this.resizeConfig = { enabled: !0, delay: 150 } : this.resizeConfig = {
591
1116
  enabled: !0,
592
- delay: (a = s.delay) != null ? a : 150,
593
- onStart: s.onStart,
594
- onEnd: s.onEnd
595
- }, this.observer = new MutationObserver((o) => {
596
- let l = E;
597
- for (const c of o)
598
- c.type === "childList" ? l |= D : c.type === "attributes" && (c.attributeName === "style" || c.attributeName === "class") && (l |= O | z);
599
- if (l !== E) {
600
- if (this.pendingMask |= l, l & D) {
601
- this.clearTimers(), console.log("Structural Change detected"), this.isDomDirty = !0;
1117
+ delay: (n = a.delay) != null ? n : 150,
1118
+ onStart: a.onStart,
1119
+ onEnd: a.onEnd
1120
+ }, this.observer = new MutationObserver((c) => {
1121
+ let l = _;
1122
+ for (const d of c)
1123
+ if (d.type === "childList")
1124
+ l |= V, d.removedNodes.length > 0 && d.removedNodes.forEach((f) => {
1125
+ f instanceof HTMLElement && this.pendingDeletions.add(f);
1126
+ });
1127
+ else if (d.type === "attributes")
1128
+ if (d.attributeName === "style") {
1129
+ l |= B | N;
1130
+ const f = d.target, h = Be(f.style);
1131
+ this.pendingStyles.set(f, h);
1132
+ } else
1133
+ d.attributeName === "class" && (l |= B | N);
1134
+ else
1135
+ d.type === "characterData" && (l |= $ | B);
1136
+ if (l !== _) {
1137
+ if (this.pendingMask |= l, l & V) {
1138
+ this.clearTimers(), this.isDomDirty = !0;
602
1139
  return;
603
1140
  }
604
1141
  this.mutationTimer && clearTimeout(this.mutationTimer), this.mutationTimer = window.setTimeout(() => {
@@ -619,32 +1156,71 @@ class j {
619
1156
  this.isRunning = !1, this.observer.disconnect(), this.clearTimers(), this.target.removeEventListener("transitionend", this.onTransitionFinished), this.target.removeEventListener("animationend", this.onTransitionFinished), window.removeEventListener("resize", this.onWindowResize);
620
1157
  }
621
1158
  clearTimers() {
622
- this.mutationTimer && (clearTimeout(this.mutationTimer), this.mutationTimer = null), this.cssTimer && (clearTimeout(this.cssTimer), this.cssTimer = null);
1159
+ this.mutationTimer && (clearTimeout(this.mutationTimer), this.mutationTimer = null), this.cssTimer && (clearTimeout(this.cssTimer), this.cssTimer = null), this.scrollTimer && (clearTimeout(this.scrollTimer), this.scrollTimer = null);
623
1160
  }
624
1161
  forceUpdateScene() {
625
- this.isDomDirty = !1;
1162
+ this.isDomDirty = !1, this.lastScrollX = window.scrollX, this.lastScrollY = window.scrollY;
626
1163
  const e = document.querySelector("[data-mirage-travel='traveler']") !== null;
627
1164
  e && !this.isTravelEnabled && (this.isTravelEnabled = !0, this.renderer.createRenderTarget());
628
- const t = A(
1165
+ const t = ce(
629
1166
  this.target,
630
1167
  this.pendingMask,
631
- e ? x | R : x,
1168
+ e ? D | X : D,
632
1169
  this.filter
633
1170
  );
634
- t && this.renderer.syncScene(t), this.pendingMask = E;
1171
+ t && (this.renderer.syncScene(t, this.pendingDeletions), this.pendingDeletions.clear()), this.pendingMask = _;
1172
+ }
1173
+ // [ThinkPoint] change call back pattern when after
1174
+ }
1175
+ class Ie {
1176
+ constructor() {
1177
+ u(this, "store");
1178
+ this.store = /* @__PURE__ */ new WeakMap();
1179
+ }
1180
+ register(e, t) {
1181
+ this.store.set(e, t);
1182
+ }
1183
+ get(e) {
1184
+ return this.store.get(e);
1185
+ }
1186
+ // public register(element: HTMLElement, meshGroup: THREE.Group): void {
1187
+ // this.store.set(element, meshGroup);
1188
+ // }
1189
+ // public get(element: HTMLElement): THREE.Group | undefined {
1190
+ // return this.store.get(element);
1191
+ // }
1192
+ has(e) {
1193
+ return this.store.has(e);
1194
+ }
1195
+ // Optional
1196
+ remove(e) {
1197
+ this.store.delete(e);
635
1198
  }
636
1199
  }
637
- class Q {
1200
+ class Ae {
638
1201
  constructor(e, t) {
639
- h(this, "renderer");
640
- h(this, "syncer");
641
- h(this, "target");
642
- var s, n, a;
643
- this.target = e;
644
- let r;
645
- if (t.mode === "duplicate" ? r = (n = (s = t.container) != null ? s : this.target.parentElement) != null ? n : void 0 : r = (a = this.target.parentElement) != null ? a : void 0, !r)
1202
+ u(this, "renderer");
1203
+ u(this, "syncer");
1204
+ u(this, "target");
1205
+ u(this, "registry");
1206
+ var r, a, o;
1207
+ if (this.target = e, this.registry = new Ie(), !document.getElementById("mirage-engine-styles")) {
1208
+ const n = document.createElement("style");
1209
+ n.id = "mirage-engine-styles", n.textContent = `
1210
+ [data-mirage-dom="hide"] {
1211
+ opacity: 0 !important;
1212
+ }
1213
+ `, document.head.appendChild(n);
1214
+ }
1215
+ let s;
1216
+ if (t.mode === "duplicate" ? s = (a = (r = t.container) != null ? r : this.target.parentElement) != null ? a : void 0 : s = (o = this.target.parentElement) != null ? o : void 0, !s)
646
1217
  throw new Error("[Mirage] Cannot find a container (parent or option).");
647
- this.renderer = new G(this.target, t, r), this.renderer.mount(), this.syncer = new j(this.target, this.renderer, t);
1218
+ this.renderer = new Me(
1219
+ this.target,
1220
+ t,
1221
+ s,
1222
+ this.registry
1223
+ ), this.renderer.mount(), this.syncer = new Fe(this.target, this.renderer, this.registry, t);
648
1224
  }
649
1225
  start() {
650
1226
  this.syncer.start();
@@ -655,13 +1231,35 @@ class Q {
655
1231
  dispose() {
656
1232
  this.syncer.stop(), this.renderer.dispose();
657
1233
  }
1234
+ test() {
1235
+ const e = this.registry.get(
1236
+ document.querySelector("#box2")
1237
+ );
1238
+ if (!e)
1239
+ return;
1240
+ const t = {
1241
+ ArrowRight: !1,
1242
+ ArrowLeft: !1,
1243
+ ArrowUp: !1,
1244
+ ArrowDown: !1
1245
+ };
1246
+ window.addEventListener("keydown", (a) => {
1247
+ t[a.key] !== void 0 && (t[a.key] = !0);
1248
+ }), window.addEventListener("keyup", (a) => {
1249
+ t[a.key] !== void 0 && (t[a.key] = !1);
1250
+ });
1251
+ const s = 2, r = () => {
1252
+ requestAnimationFrame(r), t.ArrowRight && e.position.setX(e.position.x + s), t.ArrowLeft && e.position.setX(e.position.x - s), t.ArrowUp && e.position.setY(e.position.y + s), t.ArrowDown && e.position.setY(e.position.y - s);
1253
+ };
1254
+ r();
1255
+ }
658
1256
  }
659
- class K {
1257
+ class ze {
660
1258
  constructor(e, t) {
661
- h(this, "_engine");
1259
+ u(this, "_engine");
662
1260
  if (!e)
663
1261
  throw new Error("[Mirage] Target element is required.");
664
- this._engine = new Q(e, t);
1262
+ this._engine = new Ae(e, t);
665
1263
  }
666
1264
  start() {
667
1265
  this._engine.start();
@@ -672,7 +1270,10 @@ class K {
672
1270
  destroy() {
673
1271
  this._engine.dispose();
674
1272
  }
1273
+ test() {
1274
+ this._engine.test();
1275
+ }
675
1276
  }
676
1277
  export {
677
- K as Mirage
1278
+ ze as Mirage
678
1279
  };