@walrosproject/ui 0.3.4 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -233
- package/dist/assets/walros-logo-3d.glb +0 -0
- package/dist/index.d.ts +39 -2
- package/dist/index.js +456 -344
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +4 -0
- package/dist/model.js +6 -0
- package/dist/model.js.map +1 -0
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -1,359 +1,273 @@
|
|
|
1
1
|
// src/components/WalrosPortalTransition.tsx
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
import { useState as useState3 } from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
|
|
5
|
+
// src/assets.ts
|
|
6
|
+
var walrosPortalSilhouetteUrl = new URL(
|
|
7
|
+
"./assets/walros-portal-silhouette.svg",
|
|
8
|
+
import.meta.url
|
|
9
|
+
).href;
|
|
10
|
+
var walrosLogoChromeUrl = new URL(
|
|
11
|
+
"./assets/walros-logo-chrome.png",
|
|
12
|
+
import.meta.url
|
|
13
|
+
).href;
|
|
14
|
+
var walrosWordmarkLightUrl = new URL(
|
|
15
|
+
"./assets/walros-wordmark-light.png",
|
|
16
|
+
import.meta.url
|
|
17
|
+
).href;
|
|
18
|
+
var walrosWordmarkDarkUrl = new URL(
|
|
19
|
+
"./assets/walros-wordmark-dark.png",
|
|
20
|
+
import.meta.url
|
|
21
|
+
).href;
|
|
22
|
+
var walrosThemeGlitchSoundUrl = new URL(
|
|
23
|
+
"./assets/walros-theme-glitch.mp3",
|
|
24
|
+
import.meta.url
|
|
25
|
+
).href;
|
|
26
|
+
|
|
27
|
+
// src/components/Walros3DPortalTransition.tsx
|
|
28
|
+
import { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
29
|
+
import gsap from "gsap";
|
|
30
|
+
|
|
31
|
+
// src/portalSilhouette.ts
|
|
32
|
+
var walrosPortalPaths = [
|
|
33
|
+
"M 244.00 354.00 C 240.50 377.67, 240.17 413.67, 242.00 434.00 C 243.83 454.33, 249.50 464.50, 255.00 476.00 C 260.50 487.50, 268.50 496.00, 275.00 503.00 C 281.50 510.00, 287.17 513.67, 294.00 518.00 C 300.83 522.33, 306.00 525.67, 316.00 529.00 C 326.00 532.33, 336.33 536.67, 354.00 538.00 C 371.67 539.33, 397.83 540.83, 422.00 537.00 C 446.17 533.17, 474.17 525.33, 499.00 515.00 C 523.83 504.67, 550.00 489.33, 571.00 475.00 C 592.00 460.67, 615.00 436.50, 625.00 429.00 C 635.00 421.50, 623.67 424.00, 631.00 430.00 C 638.33 436.00, 656.67 454.83, 669.00 465.00 C 681.33 475.17, 690.00 482.17, 705.00 491.00 C 720.00 499.83, 743.67 511.50, 759.00 518.00 C 774.33 524.50, 784.00 526.83, 797.00 530.00 C 810.00 533.17, 820.00 535.83, 837.00 537.00 C 854.00 538.17, 881.17 539.00, 899.00 537.00 C 916.83 535.00, 932.00 530.00, 944.00 525.00 C 956.00 520.00, 962.00 516.17, 971.00 507.00 C 980.00 497.83, 991.67 482.83, 998.00 470.00 C 1004.33 457.17, 1007.17 446.33, 1009.00 430.00 C 1010.83 413.67, 1010.83 390.50, 1009.00 372.00 C 1007.17 353.50, 1003.83 337.17, 998.00 319.00 C 992.17 300.83, 983.67 280.17, 974.00 263.00 C 964.33 245.83, 952.00 229.67, 940.00 216.00 C 928.00 202.33, 917.17 192.00, 902.00 181.00 C 886.83 170.00, 866.50 158.17, 849.00 150.00 C 831.50 141.83, 816.67 137.00, 797.00 132.00 C 777.33 127.00, 756.67 122.83, 731.00 120.00 C 705.33 117.17, 673.67 115.33, 643.00 115.00 C 612.33 114.67, 575.67 115.67, 547.00 118.00 C 518.33 120.33, 496.17 123.00, 471.00 129.00 C 445.83 135.00, 418.33 143.50, 396.00 154.00 C 373.67 164.50, 353.50 178.50, 337.00 192.00 C 320.50 205.50, 309.33 218.33, 297.00 235.00 C 284.67 251.67, 271.83 272.17, 263.00 292.00 C 254.17 311.83, 247.50 330.33, 244.00 354.00 Z",
|
|
34
|
+
"M 289.00 536.00 C 283.17 535.50, 284.83 533.00, 284.00 544.00 C 283.17 555.00, 282.67 578.67, 284.00 602.00 C 285.33 625.33, 287.00 651.83, 292.00 684.00 C 297.00 716.17, 306.33 763.50, 314.00 795.00 C 321.67 826.50, 328.67 847.17, 338.00 873.00 C 347.33 898.83, 357.00 923.67, 370.00 950.00 C 383.00 976.33, 399.67 1006.00, 416.00 1031.00 C 432.33 1056.00, 455.33 1084.50, 468.00 1100.00 C 480.67 1115.50, 486.17 1119.33, 492.00 1124.00 C 497.83 1128.67, 500.67 1127.67, 503.00 1128.00 C 505.33 1128.33, 505.50 1127.50, 506.00 1126.00 C 506.50 1124.50, 510.33 1132.00, 506.00 1119.00 C 501.67 1106.00, 488.17 1073.83, 480.00 1048.00 C 471.83 1022.17, 462.67 987.67, 457.00 964.00 C 451.33 940.33, 449.17 927.33, 446.00 906.00 C 442.83 884.67, 439.50 865.00, 438.00 836.00 C 436.50 807.00, 436.50 758.33, 437.00 732.00 C 437.50 705.67, 439.00 696.33, 441.00 678.00 C 443.00 659.67, 444.83 644.00, 449.00 622.00 C 453.17 600.00, 464.50 559.00, 466.00 546.00 C 467.50 533.00, 468.67 542.50, 458.00 544.00 C 447.33 545.50, 418.33 553.17, 402.00 555.00 C 385.67 556.83, 373.83 556.33, 360.00 555.00 C 346.17 553.67, 330.83 550.17, 319.00 547.00 C 307.17 543.83, 294.83 536.50, 289.00 536.00 Z",
|
|
35
|
+
"M 961.00 537.00 C 948.50 539.17, 907.83 552.00, 889.00 555.00 C 870.17 558.00, 864.17 557.00, 848.00 555.00 C 831.83 553.00, 802.83 545.00, 792.00 543.00 C 781.17 541.00, 784.83 542.50, 783.00 543.00 C 781.17 543.50, 778.67 533.83, 781.00 546.00 C 783.33 558.17, 792.67 592.33, 797.00 616.00 C 801.33 639.67, 804.83 668.83, 807.00 688.00 C 809.17 707.17, 809.67 709.00, 810.00 731.00 C 810.33 753.00, 810.50 792.83, 809.00 820.00 C 807.50 847.17, 804.50 870.50, 801.00 894.00 C 797.50 917.50, 794.00 936.17, 788.00 961.00 C 782.00 985.83, 773.50 1016.67, 765.00 1043.00 C 756.50 1069.33, 741.33 1104.83, 737.00 1119.00 C 732.67 1133.17, 736.67 1127.17, 739.00 1128.00 C 741.33 1128.83, 745.83 1127.83, 751.00 1124.00 C 756.17 1120.17, 757.33 1120.50, 770.00 1105.00 C 782.67 1089.50, 811.33 1053.50, 827.00 1031.00 C 842.67 1008.50, 851.17 995.00, 864.00 970.00 C 876.83 945.00, 892.83 910.00, 904.00 881.00 C 915.17 852.00, 923.00 826.67, 931.00 796.00 C 939.00 765.33, 946.67 728.67, 952.00 697.00 C 957.33 665.33, 961.00 631.83, 963.00 606.00 C 965.00 580.17, 964.33 553.50, 964.00 542.00 C 963.67 530.50, 973.50 534.83, 961.00 537.00 Z"
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
// src/components/Walros3DPortalTransition.tsx
|
|
10
39
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
var SILHOUETTE_VIEWBOX = 1254;
|
|
12
40
|
var FOCUS_X = 626;
|
|
13
41
|
var FOCUS_Y = 333;
|
|
42
|
+
var VISIBLE_LEFT = 244;
|
|
43
|
+
var VISIBLE_RIGHT = 1010;
|
|
44
|
+
var VISIBLE_TOP = 115;
|
|
45
|
+
var VISIBLE_BOTTOM = 1128;
|
|
14
46
|
var PORTAL_RADIUS = 190;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (typeof window === "undefined") return null;
|
|
18
|
-
try {
|
|
19
|
-
const storage = mode === "session" ? window.sessionStorage : window.localStorage;
|
|
20
|
-
const testKey = "__walros_portal_test__";
|
|
21
|
-
storage.setItem(testKey, "1");
|
|
22
|
-
storage.removeItem(testKey);
|
|
23
|
-
return storage;
|
|
24
|
-
} catch {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function shouldRunTransition(enabled, storageMode, storageKey) {
|
|
29
|
-
if (!enabled) return false;
|
|
30
|
-
if (storageMode === "always") return true;
|
|
31
|
-
if (typeof window === "undefined") return false;
|
|
32
|
-
const storage = getStorage(storageMode);
|
|
33
|
-
if (!storage) return true;
|
|
34
|
-
try {
|
|
35
|
-
return storage.getItem(storageKey) == null;
|
|
36
|
-
} catch {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function WalrosPortalTransition({
|
|
41
|
-
duration = 900,
|
|
47
|
+
function Walros3DPortalTransition({
|
|
48
|
+
origin,
|
|
42
49
|
onComplete,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
duration = 900,
|
|
51
|
+
backgroundColor = "#000",
|
|
52
|
+
zIndex = 10001,
|
|
53
|
+
lockScroll = true,
|
|
54
|
+
logoUrl = false
|
|
48
55
|
}) {
|
|
49
|
-
const [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const previousOverflowRef = useRef("");
|
|
61
|
-
const uid = useId().replace(/[:]/g, "_");
|
|
62
|
-
const maskId = `walros-portal-mask-${uid}`;
|
|
56
|
+
const [visible, setVisible] = useState(true);
|
|
57
|
+
const [viewport, setViewport] = useState(() => ({
|
|
58
|
+
width: typeof window === "undefined" ? 0 : window.innerWidth,
|
|
59
|
+
height: typeof window === "undefined" ? 0 : window.innerHeight
|
|
60
|
+
}));
|
|
61
|
+
const overlay = useRef(null);
|
|
62
|
+
const portal = useRef(null);
|
|
63
|
+
const logo = useRef(null);
|
|
64
|
+
const completeRef = useRef(onComplete);
|
|
65
|
+
completeRef.current = onComplete;
|
|
66
|
+
const maskId = `walros-3d-portal-${useId().replace(/:/g, "_")}`;
|
|
63
67
|
useEffect(() => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const rect = element.getBoundingClientRect();
|
|
69
|
-
setSize(
|
|
70
|
-
(previous) => previous.w === rect.width && previous.h === rect.height ? previous : { w: rect.width, h: rect.height }
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
measure();
|
|
74
|
-
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(measure) : null;
|
|
75
|
-
observer?.observe(element);
|
|
76
|
-
window.addEventListener("resize", measure);
|
|
77
|
-
return () => {
|
|
78
|
-
observer?.disconnect();
|
|
79
|
-
window.removeEventListener("resize", measure);
|
|
80
|
-
};
|
|
81
|
-
}, [visible]);
|
|
68
|
+
const updateViewport = () => setViewport({ width: window.innerWidth, height: window.innerHeight });
|
|
69
|
+
window.addEventListener("resize", updateViewport);
|
|
70
|
+
return () => window.removeEventListener("resize", updateViewport);
|
|
71
|
+
}, []);
|
|
82
72
|
useLayoutEffect(() => {
|
|
83
|
-
if (!
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
if (!visible || viewport.width <= 0 || viewport.height <= 0 || !overlay.current || !portal.current) return;
|
|
74
|
+
const previousOverflow = document.body.style.overflow;
|
|
75
|
+
if (lockScroll) document.body.style.overflow = "hidden";
|
|
76
|
+
const visibleWidth = VISIBLE_RIGHT - VISIBLE_LEFT;
|
|
77
|
+
const visibleHeight = VISIBLE_BOTTOM - VISIBLE_TOP;
|
|
78
|
+
const visualCenterX = (VISIBLE_LEFT + VISIBLE_RIGHT) / 2;
|
|
79
|
+
const visualCenterY = (VISIBLE_TOP + VISIBLE_BOTTOM) / 2;
|
|
80
|
+
const initialScale = Math.min(origin.width / visibleWidth, origin.height / visibleHeight) * 0.985;
|
|
81
|
+
const initialX = origin.centerX - (visualCenterX - FOCUS_X) * initialScale;
|
|
82
|
+
const initialY = origin.centerY - (visualCenterY - FOCUS_Y) * initialScale;
|
|
83
|
+
const diagonal = Math.hypot(viewport.width, viewport.height) / 2;
|
|
84
|
+
const finalScale = (diagonal + 80) / PORTAL_RADIUS * 1.15;
|
|
85
|
+
const targetX = viewport.width / 2 - (visualCenterX - FOCUS_X) * finalScale;
|
|
86
|
+
const targetY = viewport.height / 2 - (visualCenterY - FOCUS_Y) * finalScale;
|
|
87
|
+
const total = duration / 1e3;
|
|
88
|
+
gsap.set(portal.current, {
|
|
89
|
+
x: initialX,
|
|
90
|
+
y: initialY,
|
|
91
|
+
scale: initialScale,
|
|
92
|
+
svgOrigin: "0 0"
|
|
93
|
+
});
|
|
94
|
+
if (logo.current) {
|
|
95
|
+
gsap.set(logo.current, {
|
|
96
|
+
x: initialX,
|
|
97
|
+
y: initialY,
|
|
98
|
+
scale: initialScale,
|
|
99
|
+
opacity: 1,
|
|
100
|
+
svgOrigin: "0 0"
|
|
101
|
+
});
|
|
86
102
|
}
|
|
87
|
-
|
|
88
|
-
if (completedRef.current || startedRef.current) return;
|
|
89
|
-
if (size.w <= 0 || size.h <= 0) return;
|
|
90
|
-
const overlay = overlayRef.current;
|
|
91
|
-
const maskScale = maskScaleRef.current;
|
|
92
|
-
if (!overlay || !maskScale) return;
|
|
93
|
-
startedRef.current = true;
|
|
94
|
-
previousOverflowRef.current = document.body.style.overflow;
|
|
95
|
-
document.body.style.overflow = "hidden";
|
|
103
|
+
gsap.set(overlay.current, { opacity: 1 });
|
|
96
104
|
const finish = () => {
|
|
97
|
-
if (
|
|
98
|
-
completedRef.current = true;
|
|
99
|
-
document.body.style.overflow = previousOverflowRef.current;
|
|
100
|
-
if (storageMode !== "always") {
|
|
101
|
-
const storage = getStorage(storageMode);
|
|
102
|
-
try {
|
|
103
|
-
storage?.setItem(storageKey, "1");
|
|
104
|
-
} catch {
|
|
105
|
-
}
|
|
106
|
-
}
|
|
105
|
+
if (lockScroll) document.body.style.overflow = previousOverflow;
|
|
107
106
|
setVisible(false);
|
|
108
|
-
|
|
107
|
+
completeRef.current?.();
|
|
109
108
|
};
|
|
110
|
-
const reducedMotion = window.matchMedia(
|
|
111
|
-
|
|
112
|
-
).matches;
|
|
109
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
110
|
+
const timeline = gsap.timeline({ onComplete: finish });
|
|
113
111
|
if (reducedMotion) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
timeline.to(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
rafRef.current = requestAnimationFrame(() => {
|
|
124
|
-
rafRef.current = null;
|
|
125
|
-
const halfDiagonal = Math.sqrt(size.w * size.w + size.h * size.h) / 2;
|
|
126
|
-
const initialPixels2 = Math.min(
|
|
127
|
-
180,
|
|
128
|
-
Math.max(120, size.w * 0.12)
|
|
129
|
-
);
|
|
130
|
-
const initialScale2 = initialPixels2 / SILHOUETTE_VIEWBOX;
|
|
131
|
-
const finalScale = (halfDiagonal + 80) / PORTAL_RADIUS * 1.15;
|
|
132
|
-
gsap.set(maskScale, {
|
|
133
|
-
svgOrigin: "0 0",
|
|
134
|
-
scale: initialScale2
|
|
112
|
+
timeline.to(overlay.current, { opacity: 0, duration: 0.15, ease: "power1.out" });
|
|
113
|
+
} else {
|
|
114
|
+
timeline.to([portal.current, logo.current].filter(Boolean), {
|
|
115
|
+
x: targetX,
|
|
116
|
+
y: targetY,
|
|
117
|
+
scale: finalScale,
|
|
118
|
+
duration: total,
|
|
119
|
+
ease: "power2.in"
|
|
135
120
|
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const timeline = gsap.timeline({ onComplete: finish });
|
|
139
|
-
timelineRef.current = timeline;
|
|
140
|
-
timeline.to(
|
|
141
|
-
maskScale,
|
|
142
|
-
{
|
|
143
|
-
scale: initialScale2 * 1.4,
|
|
144
|
-
duration: totalSeconds * 0.15,
|
|
145
|
-
ease: "power2.out"
|
|
146
|
-
},
|
|
147
|
-
0
|
|
148
|
-
);
|
|
149
|
-
timeline.to(
|
|
150
|
-
maskScale,
|
|
151
|
-
{
|
|
152
|
-
scale: finalScale,
|
|
153
|
-
duration: totalSeconds * 0.85,
|
|
154
|
-
ease: "power2.in"
|
|
155
|
-
},
|
|
156
|
-
totalSeconds * 0.15
|
|
157
|
-
);
|
|
158
|
-
timeline.to(
|
|
159
|
-
overlay,
|
|
160
|
-
{
|
|
121
|
+
if (logo.current) {
|
|
122
|
+
timeline.to(logo.current, {
|
|
161
123
|
opacity: 0,
|
|
162
|
-
duration:
|
|
163
|
-
ease: "
|
|
164
|
-
},
|
|
165
|
-
totalSeconds * 0.9
|
|
166
|
-
);
|
|
167
|
-
});
|
|
168
|
-
}, [
|
|
169
|
-
duration,
|
|
170
|
-
enabled,
|
|
171
|
-
onComplete,
|
|
172
|
-
size,
|
|
173
|
-
storageKey,
|
|
174
|
-
storageMode,
|
|
175
|
-
visible
|
|
176
|
-
]);
|
|
177
|
-
useEffect(() => {
|
|
178
|
-
return () => {
|
|
179
|
-
if (rafRef.current !== null) {
|
|
180
|
-
cancelAnimationFrame(rafRef.current);
|
|
181
|
-
}
|
|
182
|
-
timelineRef.current?.kill();
|
|
183
|
-
if (startedRef.current && !completedRef.current) {
|
|
184
|
-
document.body.style.overflow = previousOverflowRef.current;
|
|
124
|
+
duration: total * 0.18,
|
|
125
|
+
ease: "power1.out"
|
|
126
|
+
}, total * 0.7);
|
|
185
127
|
}
|
|
128
|
+
timeline.to(overlay.current, {
|
|
129
|
+
opacity: 0,
|
|
130
|
+
duration: total * 0.1,
|
|
131
|
+
ease: "power2.out"
|
|
132
|
+
}, total * 0.9);
|
|
133
|
+
}
|
|
134
|
+
return () => {
|
|
135
|
+
timeline.kill();
|
|
136
|
+
if (lockScroll) document.body.style.overflow = previousOverflow;
|
|
186
137
|
};
|
|
187
|
-
}, []);
|
|
188
|
-
if (!
|
|
189
|
-
const { w, h } = size;
|
|
190
|
-
const ready = w > 0 && h > 0;
|
|
191
|
-
const viewportCenterX = w / 2;
|
|
192
|
-
const viewportCenterY = h / 2;
|
|
193
|
-
const initialPixels = Math.min(
|
|
194
|
-
180,
|
|
195
|
-
Math.max(120, w * 0.12)
|
|
196
|
-
);
|
|
197
|
-
const initialScale = initialPixels / SILHOUETTE_VIEWBOX;
|
|
198
|
-
const visualCenter = SILHOUETTE_VIEWBOX / 2;
|
|
199
|
-
const initialOffsetX = (visualCenter - FOCUS_X) * initialScale;
|
|
200
|
-
const initialOffsetY = (visualCenter - FOCUS_Y) * initialScale;
|
|
201
|
-
const portalCenterX = viewportCenterX - initialOffsetX;
|
|
202
|
-
const portalCenterY = viewportCenterY - initialOffsetY;
|
|
138
|
+
}, [duration, lockScroll, origin, viewport, visible]);
|
|
139
|
+
if (!visible) return null;
|
|
203
140
|
return /* @__PURE__ */ jsx(
|
|
204
141
|
"div",
|
|
205
142
|
{
|
|
206
|
-
ref:
|
|
207
|
-
|
|
143
|
+
ref: overlay,
|
|
144
|
+
className: "walros-3d-portal",
|
|
208
145
|
style: {
|
|
209
146
|
position: "fixed",
|
|
210
147
|
inset: 0,
|
|
211
148
|
width: "100vw",
|
|
212
149
|
height: "100dvh",
|
|
213
|
-
zIndex,
|
|
214
|
-
pointerEvents: "none",
|
|
215
150
|
overflow: "hidden",
|
|
216
|
-
|
|
151
|
+
pointerEvents: "none",
|
|
152
|
+
zIndex,
|
|
153
|
+
backgroundColor: viewport.width > 0 && viewport.height > 0 ? "transparent" : backgroundColor
|
|
217
154
|
},
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
{
|
|
221
|
-
width: "
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
inset: 0,
|
|
228
|
-
display: "block"
|
|
229
|
-
},
|
|
230
|
-
children: [
|
|
231
|
-
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
|
|
232
|
-
"mask",
|
|
233
|
-
{
|
|
234
|
-
id: maskId,
|
|
235
|
-
maskUnits: "userSpaceOnUse",
|
|
236
|
-
x: "0",
|
|
237
|
-
y: "0",
|
|
238
|
-
width: w,
|
|
239
|
-
height: h,
|
|
240
|
-
children: [
|
|
241
|
-
/* @__PURE__ */ jsx(
|
|
242
|
-
"rect",
|
|
243
|
-
{
|
|
244
|
-
x: "0",
|
|
245
|
-
y: "0",
|
|
246
|
-
width: w,
|
|
247
|
-
height: h,
|
|
248
|
-
fill: "white"
|
|
249
|
-
}
|
|
250
|
-
),
|
|
251
|
-
/* @__PURE__ */ jsx(
|
|
252
|
-
"g",
|
|
253
|
-
{
|
|
254
|
-
transform: `translate(${portalCenterX} ${portalCenterY})`,
|
|
255
|
-
children: /* @__PURE__ */ jsx(
|
|
256
|
-
"g",
|
|
257
|
-
{
|
|
258
|
-
ref: maskScaleRef,
|
|
259
|
-
transform: `scale(${initialScale})`,
|
|
260
|
-
children: /* @__PURE__ */ jsx(
|
|
261
|
-
"image",
|
|
262
|
-
{
|
|
263
|
-
href: WALROS_PORTAL_SILHOUETTE_URL,
|
|
264
|
-
x: -FOCUS_X,
|
|
265
|
-
y: -FOCUS_Y,
|
|
266
|
-
width: SILHOUETTE_VIEWBOX,
|
|
267
|
-
height: SILHOUETTE_VIEWBOX
|
|
268
|
-
}
|
|
269
|
-
)
|
|
270
|
-
}
|
|
271
|
-
)
|
|
272
|
-
}
|
|
273
|
-
)
|
|
274
|
-
]
|
|
275
|
-
}
|
|
276
|
-
) }),
|
|
277
|
-
/* @__PURE__ */ jsx(
|
|
278
|
-
"rect",
|
|
279
|
-
{
|
|
280
|
-
x: "0",
|
|
281
|
-
y: "0",
|
|
282
|
-
width: w,
|
|
283
|
-
height: h,
|
|
284
|
-
fill: backgroundColor,
|
|
285
|
-
mask: `url(#${maskId})`
|
|
286
|
-
}
|
|
287
|
-
)
|
|
288
|
-
]
|
|
289
|
-
}
|
|
290
|
-
)
|
|
155
|
+
"aria-hidden": "true",
|
|
156
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "100%", height: "100%", viewBox: `0 0 ${viewport.width} ${viewport.height}`, preserveAspectRatio: "none", style: { display: "block" }, children: [
|
|
157
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: "0", y: "0", width: viewport.width, height: viewport.height, children: [
|
|
158
|
+
/* @__PURE__ */ jsx("rect", { width: viewport.width, height: viewport.height, fill: "white" }),
|
|
159
|
+
/* @__PURE__ */ jsx("g", { ref: portal, children: /* @__PURE__ */ jsx("g", { transform: `translate(${-FOCUS_X} ${-FOCUS_Y})`, fill: "black", children: walrosPortalPaths.map((path, index) => /* @__PURE__ */ jsx("path", { d: path }, index)) }) })
|
|
160
|
+
] }) }),
|
|
161
|
+
logoUrl && /* @__PURE__ */ jsx("g", { ref: logo, children: /* @__PURE__ */ jsx("image", { href: logoUrl, x: -FOCUS_X, y: -FOCUS_Y, width: "1254", height: "1254" }) }),
|
|
162
|
+
/* @__PURE__ */ jsx("rect", { width: viewport.width, height: viewport.height, fill: backgroundColor, mask: `url(#${maskId})` })
|
|
163
|
+
] })
|
|
291
164
|
}
|
|
292
165
|
);
|
|
293
166
|
}
|
|
294
167
|
|
|
295
|
-
// src/
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
).
|
|
300
|
-
var walrosLogoChromeUrl = new URL(
|
|
301
|
-
"./assets/walros-logo-chrome.png",
|
|
302
|
-
import.meta.url
|
|
303
|
-
).href;
|
|
304
|
-
var walrosWordmarkLightUrl = new URL(
|
|
305
|
-
"./assets/walros-wordmark-light.png",
|
|
306
|
-
import.meta.url
|
|
307
|
-
).href;
|
|
308
|
-
var walrosWordmarkDarkUrl = new URL(
|
|
309
|
-
"./assets/walros-wordmark-dark.png",
|
|
310
|
-
import.meta.url
|
|
311
|
-
).href;
|
|
312
|
-
var walrosThemeGlitchSoundUrl = new URL(
|
|
313
|
-
"./assets/walros-theme-glitch.mp3",
|
|
314
|
-
import.meta.url
|
|
315
|
-
).href;
|
|
316
|
-
|
|
317
|
-
// src/components/WalrosLogo.tsx
|
|
318
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
319
|
-
function WalrosLogo({
|
|
320
|
-
alt = "WalrOS",
|
|
321
|
-
draggable = false,
|
|
322
|
-
...props
|
|
323
|
-
}) {
|
|
324
|
-
return /* @__PURE__ */ jsx2(
|
|
325
|
-
"img",
|
|
326
|
-
{
|
|
327
|
-
src: walrosLogoChromeUrl,
|
|
328
|
-
alt,
|
|
329
|
-
draggable,
|
|
330
|
-
...props
|
|
331
|
-
}
|
|
168
|
+
// src/components/useOverlayHost.ts
|
|
169
|
+
import { useLayoutEffect as useLayoutEffect2, useState as useState2 } from "react";
|
|
170
|
+
function useOverlayHost(zIndex) {
|
|
171
|
+
const [host] = useState2(
|
|
172
|
+
() => typeof document === "undefined" ? null : document.createElement("div")
|
|
332
173
|
);
|
|
174
|
+
useLayoutEffect2(() => {
|
|
175
|
+
if (!host) return;
|
|
176
|
+
host.dataset.walrosOverlayRoot = "";
|
|
177
|
+
host.style.position = "fixed";
|
|
178
|
+
host.style.inset = "0";
|
|
179
|
+
host.style.pointerEvents = "none";
|
|
180
|
+
document.documentElement.appendChild(host);
|
|
181
|
+
return () => host.remove();
|
|
182
|
+
}, [host]);
|
|
183
|
+
useLayoutEffect2(() => {
|
|
184
|
+
if (host) host.style.zIndex = String(zIndex);
|
|
185
|
+
}, [host, zIndex]);
|
|
186
|
+
return host;
|
|
333
187
|
}
|
|
334
188
|
|
|
335
|
-
// src/components/
|
|
336
|
-
import { jsx as
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
189
|
+
// src/components/WalrosPortalTransition.tsx
|
|
190
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
191
|
+
var IMAGE_SIZE = (width) => Math.min(150, Math.max(90, width * 0.11));
|
|
192
|
+
var IMAGE_WIDTH = 1254;
|
|
193
|
+
var VISIBLE_LEFT2 = 244;
|
|
194
|
+
var VISIBLE_RIGHT2 = 1010;
|
|
195
|
+
var VISIBLE_TOP2 = 115;
|
|
196
|
+
var VISIBLE_BOTTOM2 = 1128;
|
|
197
|
+
function defaultOrigin() {
|
|
198
|
+
if (typeof window === "undefined") return { centerX: 0, centerY: 0, width: 70, height: 90 };
|
|
199
|
+
const size = IMAGE_SIZE(window.innerWidth);
|
|
200
|
+
return {
|
|
201
|
+
centerX: window.innerWidth / 2,
|
|
202
|
+
centerY: window.innerHeight * 0.45 + ((VISIBLE_TOP2 + VISIBLE_BOTTOM2) / 2 - IMAGE_WIDTH / 2) / IMAGE_WIDTH * size,
|
|
203
|
+
width: (VISIBLE_RIGHT2 - VISIBLE_LEFT2) / IMAGE_WIDTH * size,
|
|
204
|
+
height: (VISIBLE_BOTTOM2 - VISIBLE_TOP2) / IMAGE_WIDTH * size
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function getStorage(mode) {
|
|
208
|
+
if (typeof window === "undefined") return null;
|
|
209
|
+
try {
|
|
210
|
+
return mode === "session" ? window.sessionStorage : window.localStorage;
|
|
211
|
+
} catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function shouldRun(enabled, mode, key) {
|
|
216
|
+
if (!enabled) return false;
|
|
217
|
+
if (mode === "always") return true;
|
|
218
|
+
try {
|
|
219
|
+
return getStorage(mode)?.getItem(key) == null;
|
|
220
|
+
} catch {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function WalrosPortalTransition({
|
|
225
|
+
duration = 900,
|
|
226
|
+
onComplete,
|
|
227
|
+
backgroundColor = "#000",
|
|
228
|
+
enabled = true,
|
|
229
|
+
storageMode = "always",
|
|
230
|
+
storageKey = "walros-portal-seen",
|
|
231
|
+
zIndex = 1e4,
|
|
232
|
+
origin,
|
|
233
|
+
logoUrl = walrosLogoChromeUrl
|
|
342
234
|
}) {
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
235
|
+
const [run] = useState3(() => shouldRun(enabled, storageMode, storageKey));
|
|
236
|
+
const [complete, setComplete] = useState3(false);
|
|
237
|
+
const [initialOrigin] = useState3(() => origin ?? defaultOrigin());
|
|
238
|
+
const host = useOverlayHost(zIndex);
|
|
239
|
+
if (!host || !enabled || !run || complete) return null;
|
|
240
|
+
return createPortal(
|
|
241
|
+
/* @__PURE__ */ jsx2(
|
|
242
|
+
Walros3DPortalTransition,
|
|
243
|
+
{
|
|
244
|
+
origin: initialOrigin,
|
|
245
|
+
logoUrl,
|
|
246
|
+
duration,
|
|
247
|
+
backgroundColor,
|
|
248
|
+
zIndex: 1,
|
|
249
|
+
lockScroll: true,
|
|
250
|
+
onComplete: () => {
|
|
251
|
+
if (storageMode !== "always") {
|
|
252
|
+
try {
|
|
253
|
+
getStorage(storageMode)?.setItem(storageKey, "1");
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
setComplete(true);
|
|
258
|
+
onComplete?.();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
),
|
|
262
|
+
host
|
|
352
263
|
);
|
|
353
264
|
}
|
|
354
265
|
|
|
266
|
+
// src/components/WalrosThemeTransition.tsx
|
|
267
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
268
|
+
|
|
355
269
|
// src/components/WalrosThemeGlitch.tsx
|
|
356
|
-
import { Fragment, jsx as
|
|
270
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
357
271
|
var GLITCH_STYLES = `
|
|
358
272
|
.walros-theme-glitch-root {
|
|
359
273
|
position: fixed;
|
|
@@ -371,7 +285,6 @@ var GLITCH_STYLES = `
|
|
|
371
285
|
content: "";
|
|
372
286
|
position: absolute;
|
|
373
287
|
inset: 0;
|
|
374
|
-
mix-blend-mode: screen;
|
|
375
288
|
}
|
|
376
289
|
.walros-theme-glitch-root::before {
|
|
377
290
|
background: rgba(0, 0, 0, .82);
|
|
@@ -501,7 +414,7 @@ function WalrosThemeGlitch({
|
|
|
501
414
|
style
|
|
502
415
|
}) {
|
|
503
416
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
504
|
-
/* @__PURE__ */
|
|
417
|
+
/* @__PURE__ */ jsx3("style", { children: GLITCH_STYLES }),
|
|
505
418
|
active ? /* @__PURE__ */ jsxs2(
|
|
506
419
|
"div",
|
|
507
420
|
{
|
|
@@ -509,22 +422,213 @@ function WalrosThemeGlitch({
|
|
|
509
422
|
style: { zIndex, ...style },
|
|
510
423
|
"aria-hidden": "true",
|
|
511
424
|
children: [
|
|
512
|
-
/* @__PURE__ */
|
|
513
|
-
/* @__PURE__ */
|
|
514
|
-
/* @__PURE__ */
|
|
515
|
-
/* @__PURE__ */
|
|
425
|
+
/* @__PURE__ */ jsx3("span", { className: "walros-theme-glitch-band" }),
|
|
426
|
+
/* @__PURE__ */ jsx3("span", { className: "walros-theme-glitch-band" }),
|
|
427
|
+
/* @__PURE__ */ jsx3("span", { className: "walros-theme-glitch-band" }),
|
|
428
|
+
/* @__PURE__ */ jsx3("span", { className: "walros-theme-glitch-band" })
|
|
516
429
|
]
|
|
517
430
|
}
|
|
518
431
|
) : null
|
|
519
432
|
] });
|
|
520
433
|
}
|
|
521
434
|
|
|
435
|
+
// src/components/WalrosThemeTransition.tsx
|
|
436
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
437
|
+
function WalrosThemeTransition({
|
|
438
|
+
active,
|
|
439
|
+
zIndex = 1e4
|
|
440
|
+
}) {
|
|
441
|
+
const host = useOverlayHost(zIndex);
|
|
442
|
+
if (!host) return null;
|
|
443
|
+
return createPortal2(
|
|
444
|
+
/* @__PURE__ */ jsx4(WalrosThemeGlitch, { active, zIndex: 1 }),
|
|
445
|
+
host
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// src/components/DirectionalCursor.tsx
|
|
450
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
451
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
452
|
+
var DESKTOP_CURSOR_QUERY = "(min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)";
|
|
453
|
+
var CURSOR_STYLES = `
|
|
454
|
+
.directional-cursor { position: fixed; top: 0; left: 0; z-index: 9999; width: 20px; height: 22px; opacity: 0; pointer-events: none; contain: layout style; will-change: transform; transition: opacity 100ms linear; }
|
|
455
|
+
.directional-cursor.is-visible { opacity: 1; }
|
|
456
|
+
.directional-cursor-shape { width: 20px; height: 22px; transform-origin: center center; will-change: transform; }
|
|
457
|
+
.directional-cursor svg { display: block; width: 20px; height: 22px; }
|
|
458
|
+
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
|
|
459
|
+
html.has-directional-cursor, html.has-directional-cursor body, html.has-directional-cursor body * { cursor: none !important; }
|
|
460
|
+
html.has-directional-cursor :is(a, button, [role="button"], [onclick], .clickable, [data-clickable], input[type="button"], input[type="submit"], input[type="reset"], label[for]),
|
|
461
|
+
html.has-directional-cursor :is(a, button, [role="button"], [onclick], .clickable, [data-clickable], input[type="button"], input[type="submit"], input[type="reset"], label[for]) * { cursor: pointer !important; }
|
|
462
|
+
html.has-directional-cursor :is(input, textarea, select, [contenteditable="true"]) { cursor: text !important; }
|
|
463
|
+
}
|
|
464
|
+
`;
|
|
465
|
+
function DirectionalCursor() {
|
|
466
|
+
const positionLayer = useRef2(null);
|
|
467
|
+
const directionLayer = useRef2(null);
|
|
468
|
+
useEffect2(() => {
|
|
469
|
+
const position = positionLayer.current;
|
|
470
|
+
const direction = directionLayer.current;
|
|
471
|
+
if (!position || !direction) return;
|
|
472
|
+
const media = window.matchMedia(DESKTOP_CURSOR_QUERY);
|
|
473
|
+
let active = false;
|
|
474
|
+
let frame = 0;
|
|
475
|
+
let moveFrame = 0;
|
|
476
|
+
let scaleTimer = 0;
|
|
477
|
+
let latestEvent = null;
|
|
478
|
+
let currentX = window.innerWidth / 2;
|
|
479
|
+
let currentY = -60;
|
|
480
|
+
let targetX = currentX;
|
|
481
|
+
let targetY = currentY;
|
|
482
|
+
let currentAngle = 0;
|
|
483
|
+
let targetAngle = 0;
|
|
484
|
+
let hasAngle = false;
|
|
485
|
+
let currentScale = 1;
|
|
486
|
+
let targetScale = 1;
|
|
487
|
+
let lastX = currentX;
|
|
488
|
+
let lastY = 0;
|
|
489
|
+
const render = () => {
|
|
490
|
+
currentX += (targetX - currentX) * 0.4;
|
|
491
|
+
currentY += (targetY - currentY) * 0.4;
|
|
492
|
+
const angleDelta = (targetAngle - currentAngle + 540) % 360 - 180;
|
|
493
|
+
currentAngle += angleDelta * 0.24;
|
|
494
|
+
currentScale += (targetScale - currentScale) * 0.24;
|
|
495
|
+
position.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;
|
|
496
|
+
direction.style.transform = `translate(-50%, -50%) rotate(${currentAngle}deg) scale(${currentScale})`;
|
|
497
|
+
const unsettled = Math.abs(targetX - currentX) > 0.08 || Math.abs(targetY - currentY) > 0.08 || Math.abs(angleDelta) > 0.08 || Math.abs(targetScale - currentScale) > 2e-3;
|
|
498
|
+
frame = unsettled ? window.requestAnimationFrame(render) : 0;
|
|
499
|
+
};
|
|
500
|
+
const requestRender = () => {
|
|
501
|
+
if (!frame) frame = window.requestAnimationFrame(render);
|
|
502
|
+
};
|
|
503
|
+
const processMove = () => {
|
|
504
|
+
moveFrame = 0;
|
|
505
|
+
const event = latestEvent;
|
|
506
|
+
if (!event) return;
|
|
507
|
+
const deltaX = event.clientX - lastX;
|
|
508
|
+
const deltaY = event.clientY - lastY;
|
|
509
|
+
const distance = Math.hypot(deltaX, deltaY);
|
|
510
|
+
targetX = event.clientX;
|
|
511
|
+
targetY = event.clientY;
|
|
512
|
+
position.classList.add("is-visible");
|
|
513
|
+
if (distance > 1.25) {
|
|
514
|
+
const rawAngle = Math.atan2(deltaY, deltaX) * (180 / Math.PI) + 90;
|
|
515
|
+
const normalizedAngle = (rawAngle % 360 + 360) % 360;
|
|
516
|
+
if (!hasAngle) {
|
|
517
|
+
targetAngle = normalizedAngle;
|
|
518
|
+
currentAngle = normalizedAngle;
|
|
519
|
+
hasAngle = true;
|
|
520
|
+
} else {
|
|
521
|
+
targetAngle = normalizedAngle;
|
|
522
|
+
}
|
|
523
|
+
targetScale = 0.92;
|
|
524
|
+
window.clearTimeout(scaleTimer);
|
|
525
|
+
scaleTimer = window.setTimeout(() => {
|
|
526
|
+
targetScale = 1;
|
|
527
|
+
requestRender();
|
|
528
|
+
}, 130);
|
|
529
|
+
}
|
|
530
|
+
lastX = event.clientX;
|
|
531
|
+
lastY = event.clientY;
|
|
532
|
+
requestRender();
|
|
533
|
+
};
|
|
534
|
+
const handleMouseMove = (event) => {
|
|
535
|
+
latestEvent = event;
|
|
536
|
+
if (!moveFrame) moveFrame = window.requestAnimationFrame(processMove);
|
|
537
|
+
};
|
|
538
|
+
const activate = () => {
|
|
539
|
+
if (active) return;
|
|
540
|
+
active = true;
|
|
541
|
+
document.documentElement.classList.add("has-directional-cursor");
|
|
542
|
+
window.addEventListener("mousemove", handleMouseMove, { passive: true });
|
|
543
|
+
};
|
|
544
|
+
const deactivate = () => {
|
|
545
|
+
if (!active) return;
|
|
546
|
+
active = false;
|
|
547
|
+
document.documentElement.classList.remove("has-directional-cursor");
|
|
548
|
+
position.classList.remove("is-visible");
|
|
549
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
550
|
+
window.cancelAnimationFrame(frame);
|
|
551
|
+
window.cancelAnimationFrame(moveFrame);
|
|
552
|
+
window.clearTimeout(scaleTimer);
|
|
553
|
+
frame = 0;
|
|
554
|
+
moveFrame = 0;
|
|
555
|
+
};
|
|
556
|
+
const sync = () => {
|
|
557
|
+
if (media.matches) activate();
|
|
558
|
+
else deactivate();
|
|
559
|
+
};
|
|
560
|
+
media.addEventListener("change", sync);
|
|
561
|
+
sync();
|
|
562
|
+
return () => {
|
|
563
|
+
media.removeEventListener("change", sync);
|
|
564
|
+
deactivate();
|
|
565
|
+
};
|
|
566
|
+
}, []);
|
|
567
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
568
|
+
/* @__PURE__ */ jsx5("style", { children: CURSOR_STYLES }),
|
|
569
|
+
/* @__PURE__ */ jsx5("div", { ref: positionLayer, className: "directional-cursor", "aria-hidden": "true", children: /* @__PURE__ */ jsx5("div", { ref: directionLayer, className: "directional-cursor-shape", children: /* @__PURE__ */ jsxs3("svg", { width: "50", height: "54", viewBox: "0 0 50 54", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
570
|
+
/* @__PURE__ */ jsxs3("g", { filter: "url(#walros-cursor-shadow)", children: [
|
|
571
|
+
/* @__PURE__ */ jsx5("path", { d: "M42.6817 41.1495L27.5103 6.79925C26.7269 5.02557 24.2082 5.02558 23.3927 6.79925L7.59814 41.1495C6.75833 42.9759 8.52712 44.8902 10.4125 44.1954L24.3757 39.0496C24.8829 38.8627 25.4385 38.8627 25.9422 39.0496L39.8121 44.1954C41.6849 44.8902 43.4884 42.9759 42.6817 41.1495Z", fill: "black" }),
|
|
572
|
+
/* @__PURE__ */ jsx5("path", { d: "M43.7146 40.6933L28.5431 6.34306C27.3556 3.65428 23.5772 3.69516 22.3668 6.32755L6.57226 40.6778C5.3134 43.4156 7.97238 46.298 10.803 45.2549L24.7662 40.109C25.0221 40.0147 25.2999 40.0156 25.5494 40.1082L39.4193 45.254C42.2261 46.2953 44.9254 43.4347 43.7146 40.6933Z", stroke: "white", strokeWidth: "2.25825" })
|
|
573
|
+
] }),
|
|
574
|
+
/* @__PURE__ */ jsx5("defs", { children: /* @__PURE__ */ jsxs3("filter", { id: "walros-cursor-shadow", x: "0.602397", y: "0.952444", width: "49.0584", height: "52.428", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [
|
|
575
|
+
/* @__PURE__ */ jsx5("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
|
|
576
|
+
/* @__PURE__ */ jsx5("feColorMatrix", { in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }),
|
|
577
|
+
/* @__PURE__ */ jsx5("feOffset", { dy: "2.25825" }),
|
|
578
|
+
/* @__PURE__ */ jsx5("feGaussianBlur", { stdDeviation: "2.25825" }),
|
|
579
|
+
/* @__PURE__ */ jsx5("feComposite", { in2: "hardAlpha", operator: "out" }),
|
|
580
|
+
/* @__PURE__ */ jsx5("feColorMatrix", { type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0" }),
|
|
581
|
+
/* @__PURE__ */ jsx5("feBlend", { mode: "normal", in2: "BackgroundImageFix", result: "effect1_dropShadow" }),
|
|
582
|
+
/* @__PURE__ */ jsx5("feBlend", { mode: "normal", in: "SourceGraphic", in2: "effect1_dropShadow", result: "shape" })
|
|
583
|
+
] }) })
|
|
584
|
+
] }) }) })
|
|
585
|
+
] });
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// src/components/WalrosLogo.tsx
|
|
589
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
590
|
+
function WalrosLogo({
|
|
591
|
+
alt = "WalrOS",
|
|
592
|
+
draggable = false,
|
|
593
|
+
...props
|
|
594
|
+
}) {
|
|
595
|
+
return /* @__PURE__ */ jsx6(
|
|
596
|
+
"img",
|
|
597
|
+
{
|
|
598
|
+
src: walrosLogoChromeUrl,
|
|
599
|
+
alt,
|
|
600
|
+
draggable,
|
|
601
|
+
...props
|
|
602
|
+
}
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// src/components/WalrosWordmark.tsx
|
|
607
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
608
|
+
function WalrosWordmark({
|
|
609
|
+
variant = "light",
|
|
610
|
+
alt = "WalrOS",
|
|
611
|
+
draggable = false,
|
|
612
|
+
...props
|
|
613
|
+
}) {
|
|
614
|
+
const src = variant === "dark" ? walrosWordmarkDarkUrl : walrosWordmarkLightUrl;
|
|
615
|
+
return /* @__PURE__ */ jsx7(
|
|
616
|
+
"img",
|
|
617
|
+
{
|
|
618
|
+
src,
|
|
619
|
+
alt,
|
|
620
|
+
draggable,
|
|
621
|
+
...props
|
|
622
|
+
}
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
|
|
522
626
|
// src/hooks/useWalrosTheme.ts
|
|
523
627
|
import {
|
|
524
628
|
useCallback,
|
|
525
|
-
useEffect as
|
|
526
|
-
useRef as
|
|
527
|
-
useState as
|
|
629
|
+
useEffect as useEffect3,
|
|
630
|
+
useRef as useRef3,
|
|
631
|
+
useState as useState4
|
|
528
632
|
} from "react";
|
|
529
633
|
var GLITCH_BASE_CLASS = "walros-theme-glitch-page";
|
|
530
634
|
var GLITCH_BODY_CLASS = "walros-theme-glitch-page--body";
|
|
@@ -571,25 +675,25 @@ function useWalrosTheme({
|
|
|
571
675
|
lockScroll,
|
|
572
676
|
onAfterUnlock
|
|
573
677
|
} = {}) {
|
|
574
|
-
const [theme, setThemeState] =
|
|
678
|
+
const [theme, setThemeState] = useState4(
|
|
575
679
|
() => readInitialTheme(storageKey, defaultTheme, useSystemPreference)
|
|
576
680
|
);
|
|
577
|
-
const [mounted, setMounted] =
|
|
578
|
-
const [glitching, setGlitching] =
|
|
579
|
-
const themeRef =
|
|
580
|
-
const glitchingRef =
|
|
581
|
-
const swapTimerRef =
|
|
582
|
-
const cleanupTimerRef =
|
|
583
|
-
const applyThemeRef =
|
|
584
|
-
const modeRef =
|
|
585
|
-
const shakeTargetsRef =
|
|
586
|
-
const lockScrollRef =
|
|
587
|
-
const onAfterUnlockRef =
|
|
588
|
-
const activeTargetsRef =
|
|
589
|
-
const viewportLockRef =
|
|
590
|
-
const soundRef =
|
|
591
|
-
const soundUrlRef =
|
|
592
|
-
const soundVolumeRef =
|
|
681
|
+
const [mounted, setMounted] = useState4(false);
|
|
682
|
+
const [glitching, setGlitching] = useState4(false);
|
|
683
|
+
const themeRef = useRef3(theme);
|
|
684
|
+
const glitchingRef = useRef3(false);
|
|
685
|
+
const swapTimerRef = useRef3(null);
|
|
686
|
+
const cleanupTimerRef = useRef3(null);
|
|
687
|
+
const applyThemeRef = useRef3(applyTheme);
|
|
688
|
+
const modeRef = useRef3(mode);
|
|
689
|
+
const shakeTargetsRef = useRef3(shakeTargets);
|
|
690
|
+
const lockScrollRef = useRef3(lockScroll);
|
|
691
|
+
const onAfterUnlockRef = useRef3(onAfterUnlock);
|
|
692
|
+
const activeTargetsRef = useRef3([]);
|
|
693
|
+
const viewportLockRef = useRef3(null);
|
|
694
|
+
const soundRef = useRef3(null);
|
|
695
|
+
const soundUrlRef = useRef3(soundUrl);
|
|
696
|
+
const soundVolumeRef = useRef3(soundVolume);
|
|
593
697
|
themeRef.current = theme;
|
|
594
698
|
applyThemeRef.current = applyTheme;
|
|
595
699
|
modeRef.current = mode;
|
|
@@ -626,7 +730,7 @@ function useWalrosTheme({
|
|
|
626
730
|
},
|
|
627
731
|
[storageKey]
|
|
628
732
|
);
|
|
629
|
-
|
|
733
|
+
useEffect3(() => {
|
|
630
734
|
const initialTheme = readInitialTheme(
|
|
631
735
|
storageKey,
|
|
632
736
|
defaultTheme,
|
|
@@ -708,6 +812,10 @@ function useWalrosTheme({
|
|
|
708
812
|
activeTargetsRef.current = [];
|
|
709
813
|
}, []);
|
|
710
814
|
const finishGlitch = useCallback(() => {
|
|
815
|
+
if (soundRef.current) {
|
|
816
|
+
soundRef.current.pause();
|
|
817
|
+
soundRef.current.currentTime = 0;
|
|
818
|
+
}
|
|
711
819
|
removeShakeClasses();
|
|
712
820
|
unlockViewport(true);
|
|
713
821
|
glitchingRef.current = false;
|
|
@@ -757,12 +865,13 @@ function useWalrosTheme({
|
|
|
757
865
|
finishGlitch();
|
|
758
866
|
}, effectiveDuration);
|
|
759
867
|
}, [finishGlitch, lockViewport, persistTheme, playThemeSound, swapDelay, totalDuration]);
|
|
760
|
-
|
|
868
|
+
useEffect3(() => {
|
|
761
869
|
return () => {
|
|
762
870
|
clearTimers();
|
|
763
871
|
removeShakeClasses();
|
|
764
872
|
unlockViewport(false);
|
|
765
873
|
soundRef.current?.pause();
|
|
874
|
+
if (soundRef.current) soundRef.current.currentTime = 0;
|
|
766
875
|
soundRef.current = null;
|
|
767
876
|
};
|
|
768
877
|
}, [clearTimers, removeShakeClasses, unlockViewport]);
|
|
@@ -776,9 +885,12 @@ function useWalrosTheme({
|
|
|
776
885
|
};
|
|
777
886
|
}
|
|
778
887
|
export {
|
|
888
|
+
DirectionalCursor,
|
|
889
|
+
Walros3DPortalTransition,
|
|
779
890
|
WalrosLogo,
|
|
780
891
|
WalrosPortalTransition,
|
|
781
892
|
WalrosThemeGlitch,
|
|
893
|
+
WalrosThemeTransition,
|
|
782
894
|
WalrosWordmark,
|
|
783
895
|
useWalrosTheme,
|
|
784
896
|
walrosLogoChromeUrl,
|