beauticode-dsh 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.zh-CN.md +2 -2
- package/agent.mjs +69 -69
- package/atmosphere.js +306 -306
- package/bin/beauticode-dsh +7 -7
- package/cli.js +118 -118
- package/client.js +640 -161
- package/console.js +284 -244
- package/control-client.mjs +6 -6
- package/gallery-host.mjs +253 -253
- package/gallery.js +178 -178
- package/index.mjs +27 -23
- package/package.json +1 -1
- package/skin-center.json +3 -3
- package/ui-host.mjs +497 -497
- package/vendor/adapter-dsh/bridge.js +6 -3
- package/vendor/core/media-server.js +49 -10
package/atmosphere.js
CHANGED
|
@@ -1,306 +1,306 @@
|
|
|
1
|
-
(() => {
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
const STYLE_ID = "beauticode-atmosphere-style";
|
|
5
|
-
const ROOT_ID = "beauticode-gallery-bg";
|
|
6
|
-
const CANVAS_URL =
|
|
7
|
-
(typeof globalThis !== "undefined" && globalThis.__BEAUTICODE_CANVAS_URL) ||
|
|
8
|
-
"/__beauticode/themes/bg-canvas.png?v=uhd";
|
|
9
|
-
|
|
10
|
-
function createWaterSim(simWidth, simHeight) {
|
|
11
|
-
const width = Math.max(24, simWidth | 0);
|
|
12
|
-
const height = Math.max(16, simHeight | 0);
|
|
13
|
-
let current = new Float32Array(width * height);
|
|
14
|
-
let next = new Float32Array(width * height);
|
|
15
|
-
let clock = 0;
|
|
16
|
-
|
|
17
|
-
function poke(cx, cy, strength, radius) {
|
|
18
|
-
const x0 = cx | 0;
|
|
19
|
-
const y0 = cy | 0;
|
|
20
|
-
const rad = Math.max(1, radius);
|
|
21
|
-
const r2 = rad * rad;
|
|
22
|
-
const reach = Math.ceil(rad);
|
|
23
|
-
for (let y = -reach; y <= reach; y += 1) {
|
|
24
|
-
for (let x = -reach; x <= reach; x += 1) {
|
|
25
|
-
const px = x0 + x;
|
|
26
|
-
const py = y0 + y;
|
|
27
|
-
if (px < 1 || py < 1 || px >= width - 1 || py >= height - 1) continue;
|
|
28
|
-
const falloff = (x * x + y * y) / r2;
|
|
29
|
-
if (falloff > 1) continue;
|
|
30
|
-
current[py * width + px] += strength * (0.5 + 0.5 * Math.cos(Math.PI * Math.sqrt(falloff)));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function step(dt) {
|
|
36
|
-
clock += dt;
|
|
37
|
-
for (let y = 1; y < height - 1; y += 1) {
|
|
38
|
-
let i = y * width + 1;
|
|
39
|
-
for (let x = 1; x < width - 1; x += 1, i += 1) {
|
|
40
|
-
next[i] =
|
|
41
|
-
((current[i - 1] + current[i + 1] + current[i - width] + current[i + width]) * 0.5 -
|
|
42
|
-
next[i]) *
|
|
43
|
-
0.9855 +
|
|
44
|
-
0.0024 * Math.sin(clock * 0.7 + x * 0.05 + y * 0.021) +
|
|
45
|
-
0.0019 * Math.sin(clock * 0.43 - x * 0.023 + y * 0.041);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
const swap = current;
|
|
49
|
-
current = next;
|
|
50
|
-
next = swap;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
width,
|
|
55
|
-
height,
|
|
56
|
-
poke,
|
|
57
|
-
step,
|
|
58
|
-
heights() {
|
|
59
|
-
return current;
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function ensureStyle() {
|
|
65
|
-
if (typeof document === "undefined") return null;
|
|
66
|
-
let style = document.getElementById(STYLE_ID);
|
|
67
|
-
if (!style) {
|
|
68
|
-
style = document.createElement("style");
|
|
69
|
-
style.id = STYLE_ID;
|
|
70
|
-
document.head.append(style);
|
|
71
|
-
}
|
|
72
|
-
style.textContent = `
|
|
73
|
-
#beauticode-gallery-bg{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;background:#0b1018}
|
|
74
|
-
#beauticode-gallery-bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center center;display:block;pointer-events:none;z-index:0;image-rendering:auto;-webkit-backface-visibility:hidden}
|
|
75
|
-
#beauticode-gallery-bg canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1;mix-blend-mode:soft-light;opacity:.32}
|
|
76
|
-
html[data-bc-gallery="true"] #beauticode-bg-stage{background:transparent!important}
|
|
77
|
-
html[data-bc-gallery="true"] #beauticode-bg-stage::after{display:none!important;background:transparent!important}
|
|
78
|
-
html[data-bc-gallery="true"],html[data-bc-gallery="true"] body{background:transparent!important}
|
|
79
|
-
html[data-bc-gallery="true"] body{
|
|
80
|
-
--dsw-alias-bg-base:rgba(17,20,27,.10);
|
|
81
|
-
--dsw-alias-bg-layer-1:rgba(26,30,39,.28);
|
|
82
|
-
--dsw-alias-bg-layer-2:rgba(35,40,51,.32);
|
|
83
|
-
--dsw-alias-bg-overlay:rgba(17,20,27,.12);
|
|
84
|
-
--dsw-specific-sidebar-fill:rgba(23,27,35,.28);
|
|
85
|
-
}
|
|
86
|
-
html[data-bc-resolved-tone="light"][data-bc-gallery="true"] body{
|
|
87
|
-
--dsw-alias-bg-base:rgba(248,250,252,.12);
|
|
88
|
-
--dsw-alias-bg-layer-1:rgba(255,255,255,.28);
|
|
89
|
-
--dsw-alias-bg-layer-2:rgba(248,250,252,.32);
|
|
90
|
-
--dsw-alias-bg-overlay:rgba(255,255,255,.14);
|
|
91
|
-
--dsw-specific-sidebar-fill:rgba(255,255,255,.28);
|
|
92
|
-
}
|
|
93
|
-
html[data-bc-gallery="true"] #root{position:relative;z-index:1;background:transparent!important}
|
|
94
|
-
html[data-bc-gallery="true"] [class*="_fade"]{display:none!important}
|
|
95
|
-
html[data-bc-gallery="true"] #beauticode-bg-stage>img,
|
|
96
|
-
html[data-bc-gallery="true"] #beauticode-bg-stage>video{opacity:0!important}
|
|
97
|
-
html[data-bc-fish="true"] #root{opacity:0!important;visibility:hidden!important;pointer-events:none!important}
|
|
98
|
-
`;
|
|
99
|
-
return style;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const runtime = {
|
|
103
|
-
windowMode: "closed",
|
|
104
|
-
layer: null,
|
|
105
|
-
token: 0,
|
|
106
|
-
loop: 0,
|
|
107
|
-
lastTick: 0,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
function stopLoop() {
|
|
111
|
-
if (runtime.loop) {
|
|
112
|
-
cancelAnimationFrame(runtime.loop);
|
|
113
|
-
runtime.loop = 0;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function attachWater(canvas) {
|
|
118
|
-
const dpr = () => Math.max(1, Math.min(2, window.devicePixelRatio || 1));
|
|
119
|
-
let sim = null;
|
|
120
|
-
let output = null;
|
|
121
|
-
let work = null;
|
|
122
|
-
let last = null;
|
|
123
|
-
|
|
124
|
-
function sizeSim() {
|
|
125
|
-
const width = Math.max(32, canvas.clientWidth || window.innerWidth || 1);
|
|
126
|
-
const height = Math.max(32, canvas.clientHeight || window.innerHeight || 1);
|
|
127
|
-
const pixel = dpr();
|
|
128
|
-
canvas.width = Math.round(width * pixel);
|
|
129
|
-
canvas.height = Math.round(height * pixel);
|
|
130
|
-
const simWidth = Math.max(80, Math.min(420, Math.round(width / 4)));
|
|
131
|
-
const simHeight = Math.max(45, Math.round(simWidth * (height / width)));
|
|
132
|
-
sim = createWaterSim(simWidth, simHeight);
|
|
133
|
-
output = null;
|
|
134
|
-
work = null;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function localPoint(event) {
|
|
138
|
-
const rect = canvas.getBoundingClientRect();
|
|
139
|
-
if (!rect.width || !rect.height || !sim) return null;
|
|
140
|
-
return {
|
|
141
|
-
x: ((event.clientX - rect.left) / rect.width) * sim.width,
|
|
142
|
-
y: ((event.clientY - rect.top) / rect.height) * sim.height,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function follow(event) {
|
|
147
|
-
if (!sim) return;
|
|
148
|
-
const point = localPoint(event);
|
|
149
|
-
if (!point) return;
|
|
150
|
-
if (last) {
|
|
151
|
-
const dx = point.x - last.x;
|
|
152
|
-
const dy = point.y - last.y;
|
|
153
|
-
const dist = Math.hypot(dx, dy);
|
|
154
|
-
const steps = Math.max(1, Math.min(8, Math.ceil(dist / 6)));
|
|
155
|
-
const strength = 0.55 + Math.min(1.8, dist / 18);
|
|
156
|
-
for (let i = 1; i <= steps; i += 1) {
|
|
157
|
-
const t = i / steps;
|
|
158
|
-
sim.poke(last.x + dx * t, last.y + dy * t, strength / steps, 2.4);
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
sim.poke(point.x, point.y, 0.7, 2.2);
|
|
162
|
-
}
|
|
163
|
-
last = point;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function render() {
|
|
167
|
-
if (!sim) return;
|
|
168
|
-
sim.step(0.033);
|
|
169
|
-
const ctx = canvas.getContext("2d");
|
|
170
|
-
if (!output) output = ctx.createImageData(sim.width, sim.height);
|
|
171
|
-
const dest = output.data;
|
|
172
|
-
const heights = sim.heights();
|
|
173
|
-
for (let y = 0; y < sim.height; y += 1) {
|
|
174
|
-
const up = y > 0 ? y - 1 : y;
|
|
175
|
-
const down = y < sim.height - 1 ? y + 1 : y;
|
|
176
|
-
for (let x = 0; x < sim.width; x += 1) {
|
|
177
|
-
const i = y * sim.width + x;
|
|
178
|
-
const gx = heights[x > 0 ? i - 1 : i] - heights[x < sim.width - 1 ? i + 1 : i];
|
|
179
|
-
const gy = heights[up * sim.width + x] - heights[down * sim.width + x];
|
|
180
|
-
const di = i * 4;
|
|
181
|
-
let alpha = gy * 160;
|
|
182
|
-
if (alpha >= 0) {
|
|
183
|
-
dest[di] = 224;
|
|
184
|
-
dest[di + 1] = 238;
|
|
185
|
-
dest[di + 2] = 255;
|
|
186
|
-
dest[di + 3] = alpha > 110 ? 110 : alpha;
|
|
187
|
-
} else {
|
|
188
|
-
alpha = -alpha;
|
|
189
|
-
dest[di] = 8;
|
|
190
|
-
dest[di + 1] = 16;
|
|
191
|
-
dest[di + 2] = 32;
|
|
192
|
-
dest[di + 3] = alpha > 90 ? 90 : alpha;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (!work) {
|
|
197
|
-
work = document.createElement("canvas");
|
|
198
|
-
work.width = sim.width;
|
|
199
|
-
work.height = sim.height;
|
|
200
|
-
}
|
|
201
|
-
work.getContext("2d").putImageData(output, 0, 0);
|
|
202
|
-
const pixel = dpr();
|
|
203
|
-
ctx.setTransform(pixel, 0, 0, pixel, 0, 0);
|
|
204
|
-
ctx.imageSmoothingEnabled = true;
|
|
205
|
-
if (ctx.imageSmoothingQuality) ctx.imageSmoothingQuality = "high";
|
|
206
|
-
ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
|
|
207
|
-
ctx.drawImage(work, 0, 0, canvas.clientWidth, canvas.clientHeight);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
sizeSim();
|
|
211
|
-
window.addEventListener("pointermove", follow, { passive: true });
|
|
212
|
-
window.addEventListener("resize", sizeSim);
|
|
213
|
-
|
|
214
|
-
return {
|
|
215
|
-
render,
|
|
216
|
-
destroy() {
|
|
217
|
-
window.removeEventListener("pointermove", follow);
|
|
218
|
-
window.removeEventListener("resize", sizeSim);
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function markPage(on) {
|
|
224
|
-
const root = document.documentElement;
|
|
225
|
-
if (on) {
|
|
226
|
-
root.dataset.bcGallery = "true";
|
|
227
|
-
root.dataset.bcActive = "true";
|
|
228
|
-
} else {
|
|
229
|
-
delete root.dataset.bcGallery;
|
|
230
|
-
if (!document.querySelector("#beauticode-bg-stage img, #beauticode-bg-stage video")) {
|
|
231
|
-
root.removeAttribute("data-bc-active");
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function closeLayer() {
|
|
237
|
-
stopLoop();
|
|
238
|
-
runtime.layer?.water?.destroy();
|
|
239
|
-
runtime.layer?.node.remove();
|
|
240
|
-
runtime.layer = null;
|
|
241
|
-
markPage(false);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
async function openLayer() {
|
|
245
|
-
const token = (runtime.token += 1);
|
|
246
|
-
ensureStyle();
|
|
247
|
-
closeLayer();
|
|
248
|
-
markPage(true);
|
|
249
|
-
const node = document.createElement("div");
|
|
250
|
-
node.id = ROOT_ID;
|
|
251
|
-
node.setAttribute("aria-hidden", "true");
|
|
252
|
-
const image = document.createElement("img");
|
|
253
|
-
image.alt = "";
|
|
254
|
-
image.decoding = "async";
|
|
255
|
-
image.fetchPriority = "high";
|
|
256
|
-
image.draggable = false;
|
|
257
|
-
const canvas = document.createElement("canvas");
|
|
258
|
-
node.append(image, canvas);
|
|
259
|
-
document.body.prepend(node);
|
|
260
|
-
|
|
261
|
-
await new Promise((resolve) => {
|
|
262
|
-
image.onload = resolve;
|
|
263
|
-
image.onerror = resolve;
|
|
264
|
-
image.src = CANVAS_URL;
|
|
265
|
-
});
|
|
266
|
-
if (token !== runtime.token || runtime.windowMode === "closed") {
|
|
267
|
-
node.remove();
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const water = attachWater(canvas);
|
|
272
|
-
runtime.layer = { node, water };
|
|
273
|
-
const tick = (ts) => {
|
|
274
|
-
if (!runtime.layer) return;
|
|
275
|
-
if (ts - runtime.lastTick > 32) {
|
|
276
|
-
runtime.lastTick = ts;
|
|
277
|
-
water.render();
|
|
278
|
-
}
|
|
279
|
-
runtime.loop = requestAnimationFrame(tick);
|
|
280
|
-
};
|
|
281
|
-
runtime.loop = requestAnimationFrame(tick);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function setWindowMode(mode) {
|
|
285
|
-
const next = mode === "on" || mode === "window" || mode === "full" ? "on" : "closed";
|
|
286
|
-
runtime.windowMode = next;
|
|
287
|
-
if (next === "closed") closeLayer();
|
|
288
|
-
else void openLayer();
|
|
289
|
-
return next;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
function getState() {
|
|
293
|
-
return { windowMode: runtime.windowMode };
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const api = {
|
|
297
|
-
createWaterSim,
|
|
298
|
-
setWindowMode,
|
|
299
|
-
getState,
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
globalThis.BeauticodeAtmosphere = api;
|
|
303
|
-
if (typeof module !== "undefined" && module.exports) {
|
|
304
|
-
module.exports = api;
|
|
305
|
-
}
|
|
306
|
-
})();
|
|
1
|
+
(() => {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const STYLE_ID = "beauticode-atmosphere-style";
|
|
5
|
+
const ROOT_ID = "beauticode-gallery-bg";
|
|
6
|
+
const CANVAS_URL =
|
|
7
|
+
(typeof globalThis !== "undefined" && globalThis.__BEAUTICODE_CANVAS_URL) ||
|
|
8
|
+
"/__beauticode/themes/bg-canvas.png?v=uhd";
|
|
9
|
+
|
|
10
|
+
function createWaterSim(simWidth, simHeight) {
|
|
11
|
+
const width = Math.max(24, simWidth | 0);
|
|
12
|
+
const height = Math.max(16, simHeight | 0);
|
|
13
|
+
let current = new Float32Array(width * height);
|
|
14
|
+
let next = new Float32Array(width * height);
|
|
15
|
+
let clock = 0;
|
|
16
|
+
|
|
17
|
+
function poke(cx, cy, strength, radius) {
|
|
18
|
+
const x0 = cx | 0;
|
|
19
|
+
const y0 = cy | 0;
|
|
20
|
+
const rad = Math.max(1, radius);
|
|
21
|
+
const r2 = rad * rad;
|
|
22
|
+
const reach = Math.ceil(rad);
|
|
23
|
+
for (let y = -reach; y <= reach; y += 1) {
|
|
24
|
+
for (let x = -reach; x <= reach; x += 1) {
|
|
25
|
+
const px = x0 + x;
|
|
26
|
+
const py = y0 + y;
|
|
27
|
+
if (px < 1 || py < 1 || px >= width - 1 || py >= height - 1) continue;
|
|
28
|
+
const falloff = (x * x + y * y) / r2;
|
|
29
|
+
if (falloff > 1) continue;
|
|
30
|
+
current[py * width + px] += strength * (0.5 + 0.5 * Math.cos(Math.PI * Math.sqrt(falloff)));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function step(dt) {
|
|
36
|
+
clock += dt;
|
|
37
|
+
for (let y = 1; y < height - 1; y += 1) {
|
|
38
|
+
let i = y * width + 1;
|
|
39
|
+
for (let x = 1; x < width - 1; x += 1, i += 1) {
|
|
40
|
+
next[i] =
|
|
41
|
+
((current[i - 1] + current[i + 1] + current[i - width] + current[i + width]) * 0.5 -
|
|
42
|
+
next[i]) *
|
|
43
|
+
0.9855 +
|
|
44
|
+
0.0024 * Math.sin(clock * 0.7 + x * 0.05 + y * 0.021) +
|
|
45
|
+
0.0019 * Math.sin(clock * 0.43 - x * 0.023 + y * 0.041);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const swap = current;
|
|
49
|
+
current = next;
|
|
50
|
+
next = swap;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
width,
|
|
55
|
+
height,
|
|
56
|
+
poke,
|
|
57
|
+
step,
|
|
58
|
+
heights() {
|
|
59
|
+
return current;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function ensureStyle() {
|
|
65
|
+
if (typeof document === "undefined") return null;
|
|
66
|
+
let style = document.getElementById(STYLE_ID);
|
|
67
|
+
if (!style) {
|
|
68
|
+
style = document.createElement("style");
|
|
69
|
+
style.id = STYLE_ID;
|
|
70
|
+
document.head.append(style);
|
|
71
|
+
}
|
|
72
|
+
style.textContent = `
|
|
73
|
+
#beauticode-gallery-bg{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;background:#0b1018}
|
|
74
|
+
#beauticode-gallery-bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center center;display:block;pointer-events:none;z-index:0;image-rendering:auto;-webkit-backface-visibility:hidden}
|
|
75
|
+
#beauticode-gallery-bg canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1;mix-blend-mode:soft-light;opacity:.32}
|
|
76
|
+
html[data-bc-gallery="true"] #beauticode-bg-stage{background:transparent!important}
|
|
77
|
+
html[data-bc-gallery="true"] #beauticode-bg-stage::after{display:none!important;background:transparent!important}
|
|
78
|
+
html[data-bc-gallery="true"],html[data-bc-gallery="true"] body{background:transparent!important}
|
|
79
|
+
html[data-bc-gallery="true"] body{
|
|
80
|
+
--dsw-alias-bg-base:rgba(17,20,27,.10);
|
|
81
|
+
--dsw-alias-bg-layer-1:rgba(26,30,39,.28);
|
|
82
|
+
--dsw-alias-bg-layer-2:rgba(35,40,51,.32);
|
|
83
|
+
--dsw-alias-bg-overlay:rgba(17,20,27,.12);
|
|
84
|
+
--dsw-specific-sidebar-fill:rgba(23,27,35,.28);
|
|
85
|
+
}
|
|
86
|
+
html[data-bc-resolved-tone="light"][data-bc-gallery="true"] body{
|
|
87
|
+
--dsw-alias-bg-base:rgba(248,250,252,.12);
|
|
88
|
+
--dsw-alias-bg-layer-1:rgba(255,255,255,.28);
|
|
89
|
+
--dsw-alias-bg-layer-2:rgba(248,250,252,.32);
|
|
90
|
+
--dsw-alias-bg-overlay:rgba(255,255,255,.14);
|
|
91
|
+
--dsw-specific-sidebar-fill:rgba(255,255,255,.28);
|
|
92
|
+
}
|
|
93
|
+
html[data-bc-gallery="true"] #root{position:relative;z-index:1;background:transparent!important}
|
|
94
|
+
html[data-bc-gallery="true"] [class*="_fade"]{display:none!important}
|
|
95
|
+
html[data-bc-gallery="true"] #beauticode-bg-stage>img,
|
|
96
|
+
html[data-bc-gallery="true"] #beauticode-bg-stage>video{opacity:0!important}
|
|
97
|
+
html[data-bc-fish="true"] #root{opacity:0!important;visibility:hidden!important;pointer-events:none!important}
|
|
98
|
+
`;
|
|
99
|
+
return style;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const runtime = {
|
|
103
|
+
windowMode: "closed",
|
|
104
|
+
layer: null,
|
|
105
|
+
token: 0,
|
|
106
|
+
loop: 0,
|
|
107
|
+
lastTick: 0,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
function stopLoop() {
|
|
111
|
+
if (runtime.loop) {
|
|
112
|
+
cancelAnimationFrame(runtime.loop);
|
|
113
|
+
runtime.loop = 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function attachWater(canvas) {
|
|
118
|
+
const dpr = () => Math.max(1, Math.min(2, window.devicePixelRatio || 1));
|
|
119
|
+
let sim = null;
|
|
120
|
+
let output = null;
|
|
121
|
+
let work = null;
|
|
122
|
+
let last = null;
|
|
123
|
+
|
|
124
|
+
function sizeSim() {
|
|
125
|
+
const width = Math.max(32, canvas.clientWidth || window.innerWidth || 1);
|
|
126
|
+
const height = Math.max(32, canvas.clientHeight || window.innerHeight || 1);
|
|
127
|
+
const pixel = dpr();
|
|
128
|
+
canvas.width = Math.round(width * pixel);
|
|
129
|
+
canvas.height = Math.round(height * pixel);
|
|
130
|
+
const simWidth = Math.max(80, Math.min(420, Math.round(width / 4)));
|
|
131
|
+
const simHeight = Math.max(45, Math.round(simWidth * (height / width)));
|
|
132
|
+
sim = createWaterSim(simWidth, simHeight);
|
|
133
|
+
output = null;
|
|
134
|
+
work = null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function localPoint(event) {
|
|
138
|
+
const rect = canvas.getBoundingClientRect();
|
|
139
|
+
if (!rect.width || !rect.height || !sim) return null;
|
|
140
|
+
return {
|
|
141
|
+
x: ((event.clientX - rect.left) / rect.width) * sim.width,
|
|
142
|
+
y: ((event.clientY - rect.top) / rect.height) * sim.height,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function follow(event) {
|
|
147
|
+
if (!sim) return;
|
|
148
|
+
const point = localPoint(event);
|
|
149
|
+
if (!point) return;
|
|
150
|
+
if (last) {
|
|
151
|
+
const dx = point.x - last.x;
|
|
152
|
+
const dy = point.y - last.y;
|
|
153
|
+
const dist = Math.hypot(dx, dy);
|
|
154
|
+
const steps = Math.max(1, Math.min(8, Math.ceil(dist / 6)));
|
|
155
|
+
const strength = 0.55 + Math.min(1.8, dist / 18);
|
|
156
|
+
for (let i = 1; i <= steps; i += 1) {
|
|
157
|
+
const t = i / steps;
|
|
158
|
+
sim.poke(last.x + dx * t, last.y + dy * t, strength / steps, 2.4);
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
sim.poke(point.x, point.y, 0.7, 2.2);
|
|
162
|
+
}
|
|
163
|
+
last = point;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function render() {
|
|
167
|
+
if (!sim) return;
|
|
168
|
+
sim.step(0.033);
|
|
169
|
+
const ctx = canvas.getContext("2d");
|
|
170
|
+
if (!output) output = ctx.createImageData(sim.width, sim.height);
|
|
171
|
+
const dest = output.data;
|
|
172
|
+
const heights = sim.heights();
|
|
173
|
+
for (let y = 0; y < sim.height; y += 1) {
|
|
174
|
+
const up = y > 0 ? y - 1 : y;
|
|
175
|
+
const down = y < sim.height - 1 ? y + 1 : y;
|
|
176
|
+
for (let x = 0; x < sim.width; x += 1) {
|
|
177
|
+
const i = y * sim.width + x;
|
|
178
|
+
const gx = heights[x > 0 ? i - 1 : i] - heights[x < sim.width - 1 ? i + 1 : i];
|
|
179
|
+
const gy = heights[up * sim.width + x] - heights[down * sim.width + x];
|
|
180
|
+
const di = i * 4;
|
|
181
|
+
let alpha = gy * 160;
|
|
182
|
+
if (alpha >= 0) {
|
|
183
|
+
dest[di] = 224;
|
|
184
|
+
dest[di + 1] = 238;
|
|
185
|
+
dest[di + 2] = 255;
|
|
186
|
+
dest[di + 3] = alpha > 110 ? 110 : alpha;
|
|
187
|
+
} else {
|
|
188
|
+
alpha = -alpha;
|
|
189
|
+
dest[di] = 8;
|
|
190
|
+
dest[di + 1] = 16;
|
|
191
|
+
dest[di + 2] = 32;
|
|
192
|
+
dest[di + 3] = alpha > 90 ? 90 : alpha;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (!work) {
|
|
197
|
+
work = document.createElement("canvas");
|
|
198
|
+
work.width = sim.width;
|
|
199
|
+
work.height = sim.height;
|
|
200
|
+
}
|
|
201
|
+
work.getContext("2d").putImageData(output, 0, 0);
|
|
202
|
+
const pixel = dpr();
|
|
203
|
+
ctx.setTransform(pixel, 0, 0, pixel, 0, 0);
|
|
204
|
+
ctx.imageSmoothingEnabled = true;
|
|
205
|
+
if (ctx.imageSmoothingQuality) ctx.imageSmoothingQuality = "high";
|
|
206
|
+
ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
|
|
207
|
+
ctx.drawImage(work, 0, 0, canvas.clientWidth, canvas.clientHeight);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
sizeSim();
|
|
211
|
+
window.addEventListener("pointermove", follow, { passive: true });
|
|
212
|
+
window.addEventListener("resize", sizeSim);
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
render,
|
|
216
|
+
destroy() {
|
|
217
|
+
window.removeEventListener("pointermove", follow);
|
|
218
|
+
window.removeEventListener("resize", sizeSim);
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function markPage(on) {
|
|
224
|
+
const root = document.documentElement;
|
|
225
|
+
if (on) {
|
|
226
|
+
root.dataset.bcGallery = "true";
|
|
227
|
+
root.dataset.bcActive = "true";
|
|
228
|
+
} else {
|
|
229
|
+
delete root.dataset.bcGallery;
|
|
230
|
+
if (!document.querySelector("#beauticode-bg-stage img, #beauticode-bg-stage video")) {
|
|
231
|
+
root.removeAttribute("data-bc-active");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function closeLayer() {
|
|
237
|
+
stopLoop();
|
|
238
|
+
runtime.layer?.water?.destroy();
|
|
239
|
+
runtime.layer?.node.remove();
|
|
240
|
+
runtime.layer = null;
|
|
241
|
+
markPage(false);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function openLayer() {
|
|
245
|
+
const token = (runtime.token += 1);
|
|
246
|
+
ensureStyle();
|
|
247
|
+
closeLayer();
|
|
248
|
+
markPage(true);
|
|
249
|
+
const node = document.createElement("div");
|
|
250
|
+
node.id = ROOT_ID;
|
|
251
|
+
node.setAttribute("aria-hidden", "true");
|
|
252
|
+
const image = document.createElement("img");
|
|
253
|
+
image.alt = "";
|
|
254
|
+
image.decoding = "async";
|
|
255
|
+
image.fetchPriority = "high";
|
|
256
|
+
image.draggable = false;
|
|
257
|
+
const canvas = document.createElement("canvas");
|
|
258
|
+
node.append(image, canvas);
|
|
259
|
+
document.body.prepend(node);
|
|
260
|
+
|
|
261
|
+
await new Promise((resolve) => {
|
|
262
|
+
image.onload = resolve;
|
|
263
|
+
image.onerror = resolve;
|
|
264
|
+
image.src = CANVAS_URL;
|
|
265
|
+
});
|
|
266
|
+
if (token !== runtime.token || runtime.windowMode === "closed") {
|
|
267
|
+
node.remove();
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const water = attachWater(canvas);
|
|
272
|
+
runtime.layer = { node, water };
|
|
273
|
+
const tick = (ts) => {
|
|
274
|
+
if (!runtime.layer) return;
|
|
275
|
+
if (ts - runtime.lastTick > 32) {
|
|
276
|
+
runtime.lastTick = ts;
|
|
277
|
+
water.render();
|
|
278
|
+
}
|
|
279
|
+
runtime.loop = requestAnimationFrame(tick);
|
|
280
|
+
};
|
|
281
|
+
runtime.loop = requestAnimationFrame(tick);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function setWindowMode(mode) {
|
|
285
|
+
const next = mode === "on" || mode === "window" || mode === "full" ? "on" : "closed";
|
|
286
|
+
runtime.windowMode = next;
|
|
287
|
+
if (next === "closed") closeLayer();
|
|
288
|
+
else void openLayer();
|
|
289
|
+
return next;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function getState() {
|
|
293
|
+
return { windowMode: runtime.windowMode };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const api = {
|
|
297
|
+
createWaterSim,
|
|
298
|
+
setWindowMode,
|
|
299
|
+
getState,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
globalThis.BeauticodeAtmosphere = api;
|
|
303
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
304
|
+
module.exports = api;
|
|
305
|
+
}
|
|
306
|
+
})();
|
package/bin/beauticode-dsh
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { runCli } from "../cli.js";
|
|
3
|
-
|
|
4
|
-
runCli().catch((error) => {
|
|
5
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
6
|
-
process.exit(1);
|
|
7
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCli } from "../cli.js";
|
|
3
|
+
|
|
4
|
+
runCli().catch((error) => {
|
|
5
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
6
|
+
process.exit(1);
|
|
7
|
+
});
|