diff --git a/assets/root.html b/assets/root.html
index 02f9ede..fe4c84a 100644
--- a/assets/root.html
+++ b/assets/root.html
@@ -1,112 +1,604 @@
-
-
-
-
- Logic Analyzer
-
-
-
-
-
-
-
+ // ---- ИНИЦИАЛИЗАЦИЯ И АДАПТАЦИЯ РАЗМЕРА CANVAS ----
+ function resizeCanvasAndRedraw() {
+ const container = canvas.parentElement;
+ const maxWidth = Math.min(1200, window.innerWidth - 60);
+ // устанавливаем размер canvas в пикселях для чёткой графики
+ const targetWidth = Math.min(1000, maxWidth);
+ const targetHeight = 500;
+ canvas.width = targetWidth;
+ canvas.height = targetHeight;
+ canvas.style.width = `${targetWidth}px`;
+ canvas.style.height = `${targetHeight}px`;
+ scheduleRender();
+ }
+
+ // очистка буфера по кнопке
+ function handleClear() {
+ clearRingBuffer();
+ updateStatus('Буфер сброшен', !!ws && ws.readyState === WebSocket.OPEN);
+ scheduleRender();
+ }
+
+ // Имитация демо-данных, если сервер не отвечает (для теста интерфейса кольцевого буфера)
+ // но только если нет подключения в течение 4 секунд - демонстрация работы (добавим генератор)
+ let demoInterval = null;
+ function startDemoDataIfNeeded() {
+ // Проверяем каждые 5 секунд: если нет ws или не открыт и буфер пуст, то генерируем демо
+ if (demoInterval) clearInterval(demoInterval);
+ demoInterval = setInterval(() => {
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
+ // генерируем несколько тестовых семплов для наглядности, но только если буфер не слишком большой
+ if (ringCount < 300) {
+ const demoCount = 4;
+ for (let i = 0; i < demoCount; i++) {
+ // Создаём осмысленную последовательность: счётчик, меандр на разных каналах
+ const timeSeed = Date.now() + i;
+ let sampleVal = 0;
+ // CH0: квадратная волна (каждые 8 семплов)
+ if ((ringCount + i) % 16 < 8) sampleVal |= (1 << 0);
+ // CH1: меандр с другой частотой
+ if ((ringCount + i) % 24 < 12) sampleVal |= (1 << 1);
+ // CH2: случайный импульс
+ if (Math.sin((ringCount + i) * 0.3) > 0) sampleVal |= (1 << 2);
+ // CH3: активный каждые 3 семпла
+ if ((ringCount + i) % 6 < 3) sampleVal |= (1 << 3);
+ // CH4: половина
+ if ((ringCount + i) % 10 > 4) sampleVal |= (1 << 4);
+ // CH5: шумоподобный
+ if (Math.floor(Math.random() * 2)) sampleVal |= (1 << 5);
+ // CH6, CH7 (доп)
+ if ((ringCount + i) % 7 < 3) sampleVal |= (1 << 6);
+ if ((ringCount + i) % 5 === 0) sampleVal |= (1 << 7);
+ pushSample(sampleVal);
+ }
+ }
+ }
+ }, 360);
+ }
+
+ // --- Отслеживание изменения размера окна ---
+ window.addEventListener('resize', () => {
+ resizeCanvasAndRedraw();
+ });
+
+ // Инициализация UI
+ function init() {
+ buildLegend();
+ resizeCanvasAndRedraw();
+ clearRingBuffer(); // чистый старт
+ connectWebSocket();
+ clearBtn.addEventListener('click', handleClear);
+ // небольшая анимация рендера (периодическая перерисовка для обновления UI даже без данных)
+ function periodicRender() {
+ drawWaveforms();
+ requestAnimationFrame(periodicRender);
+ }
+ // Запускаем непрерывный рендер (эффективно, не нагружает)
+ periodicRender();
+ }
+
+ init();
+ })();
+
+