optimization and stylizing
This commit is contained in:
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user