optimization and stylizing

This commit is contained in:
2026-04-26 18:49:50 +07:00
parent f22b04df33
commit 2664f00741
3 changed files with 264 additions and 63 deletions
+29 -13
View File
@@ -59,7 +59,6 @@ export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
const container = containerRef.current;
if (!container || hasTransferred.current) return;
// Создаем canvas вручную, чтобы обойти баг React DOM reuse
const canvas = document.createElement("canvas");
canvas.className =
"absolute inset-0 w-full h-full block transition-opacity duration-1000 opacity-0 z-0";
@@ -67,7 +66,17 @@ export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
try {
const isMobile = checkIsMobile();
const pixelScale = Math.min(window.devicePixelRatio || 1, 2.0);
// --- ДЕТЕКТОР СЛАБОГО ЖЕЛЕЗА И ДАУНСЭМПЛИНГ ---
const cores = navigator.hardwareConcurrency || 4;
const memory = (navigator as any).deviceMemory || 8;
const isWeakHardware = cores <= 4 || memory <= 4;
const isLowQuality = isMobile || isWeakHardware;
// На слабом ПК и телефонах рендерим 75% от разрешения экрана
const pixelScale = isLowQuality ? 0.75 : 1.0;
// ----------------------------------------------
const logicalWidth = container.clientWidth;
const logicalHeight = container.clientHeight;
@@ -82,7 +91,7 @@ export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
const offscreen = canvas.transferControlToOffscreen();
hasTransferred.current = true;
const eyeScale = isMobile ? 0.6 : 0.8;
const eyeScale = isMobile ? 0.8 : 1.5; // Оставили твои размеры
worker.postMessage(
{
@@ -98,24 +107,27 @@ export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
isVpnOn: isSecure,
isDarkMode,
fontSize: isMobile ? 12 : 16,
isLowQuality, // Передаем флаг в воркер
},
},
[offscreen],
);
// Плавное появление
setTimeout(() => {
canvas.classList.remove("opacity-0");
canvas.classList.add("opacity-100");
}, 150);
worker.onmessage = (e) => {
if (e.data.type === "READY") {
canvas.classList.remove("opacity-0");
canvas.classList.add("opacity-100");
}
};
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
const { width, height } = entry.contentRect;
if (width === 0 || height === 0) continue;
const pScale = Math.min(window.devicePixelRatio || 1, 2.0);
const isMob = width <= 768;
const lowQual = isMob || isWeakHardware;
const pScale = lowQual ? 0.75 : 1.0;
workerRef.current?.postMessage({
type: "RESIZE",
@@ -124,9 +136,10 @@ export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
logicalHeight: height,
pixelScale: pScale,
eyeY: getEyeY(),
eyeScale: isMob ? 0.6 : 0.8,
eyeScale: isMob ? 0.8 : 1.5,
isMobile: isMob,
fontSize: isMob ? 12 : 16,
isLowQuality: lowQual,
},
});
}
@@ -150,15 +163,18 @@ export const NetrunnerMatrix: React.FC<NetrunnerMatrixProps> = ({
}
}, [mounted, checkIsMobile, getEyeY]);
// === 2. РЕАКЦИЯ НА ТЕМУ ===
// === 2. РЕАКЦИЯ НА ТЕМУ И VPN (ВОЗВРАЩАЕМ!) ===
useEffect(() => {
if (workerRef.current && mounted) {
workerRef.current.postMessage({
type: "THEME",
payload: { isVpnOn: isSecure, isDarkMode },
payload: {
isVpnOn: isSecure,
isDarkMode: isDarkMode,
},
});
}
}, [isSecure, isDarkMode, mounted]);
}, [isSecure, isDarkMode, mounted]); // Теперь React сообщит воркеру об изменениях
// === 3. ИНТЕРАКТИВНОСТЬ (МЫШЬ, КЛИКИ, ГИРОСКОП) ===
useEffect(() => {