/
hamster75
/
Life
Обзор
Документация
Войти
/
hamster75
/
Life
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
6
CI/CD
Аналитика
Безопасность
master
js/help.js
236 строк
17 KB
Dmitry Smirnov
ready for release
13 июн 2026, 16:41
13 июн 2026, 16:41
40d5d46
Код
Авторство
О чём код?
import { VERSION } from './version.js'; const TEMPLATE = ` <div id="help-modal"> <button id="help-close" aria-label="Закрыть">×</button> <div id="help-body"> <div class="tab-panel active" data-panel="controls"> <!-- ── Мобильная версия инструкции ── --> <div class="help-mobile-only"> <h1>Управление</h1> <div class="help-version">${VERSION}</div> <div class="help-academy-ref"> Правила игры, история, интерактивные эксперименты — <button class="help-academy-btn-any help-academy-btn">🎓 Открыть Академию</button> </div> <h2>Навигация</h2> <p>Два пальца — масштаб (pinch), а также перемещение поля</p> <h2>Режимы</h2> <p><strong>Двойной тап</strong> по полю переключает режимы:<br> <strong>нейтрал</strong> — можно безопасно нажимать на поле;<br> <strong>рисование</strong> — тап или мазок рисует живые клетки.</p> <p>Текущий режим отображается в строке статуса снизу экрана.</p> <p><strong>Во время симуляции</strong> двойной тап вписывает всё поле в экран (аналог кнопки <kbd>V</kbd> на десктопе).</p> <h2>Формации</h2> <p>Выберите формацию в палитре, переключитесь в режим <strong>рисование</strong>, тапните по полю — формация разместится.</p> <p>Кнопки в верхней части палитры — ключевые для работы с формацией (из палитры и из библиотеки):</p> <div class="ctrl-table"> <span class="ctrl-key ctrl-btn-lbl">↻ Повернуть</span> <span class="ctrl-desc">Поворот активной формации на 90° по часовой стрелке</span> <span class="ctrl-key ctrl-btn-lbl">↔ Отразить</span> <span class="ctrl-desc">Горизонтальное отражение формации</span> <span class="ctrl-key ctrl-btn-lbl">✕ Снять</span> <span class="ctrl-desc">Снять активную формацию, вернуться к рисованию кистью</span> <span class="ctrl-key ctrl-btn-lbl">⌫ Ластик</span> <span class="ctrl-desc">Переключить ластик — убирает живые клетки вместо рисования</span> </div> <p class="ctrl-note">Ластик работает в обоих режимах — нейтральном и рисовании. Повторный тап по кнопке выключает ластик.</p> <p class="ctrl-note">Редактирование доступно в режимах «стоп» и «пауза» — во время симуляции поле заблокировано.</p> <h2>Алгоритм</h2> <p>Алгоритм вычисления симуляции выбирается в настройках <strong>⚙</strong>.</p> <h2>Настройки</h2> <p>Кнопка <strong>⚙</strong> открывает настройки. Если что-то пошло не так — <em>Сбросить настройки</em> возвращает все размеры, тему и положение окон к исходному состоянию.</p> </div> <!-- ── Десктопная версия инструкции ── --> <div class="help-desktop-only"> <h1>Управление</h1> <div class="help-version">${VERSION}</div> <div class="help-academy-ref"> Правила игры, история, интерактивные эксперименты — <button class="help-academy-btn-any help-academy-btn">🎓 Открыть Академию</button> </div> <h2>Навигация</h2> <div class="ctrl-table"> <span class="ctrl-key"><kbd>Колёсико</kbd></span> <span class="ctrl-desc">Зум относительно курсора — приближение и отдаление поля</span> <span class="ctrl-key"><kbd>Пробел</kbd> + <kbd>ЛКМ</kbd></span> <span class="ctrl-desc">Удерживай пробел и тяни мышью — перемещение поля</span> <span class="ctrl-key"><kbd>ЛКМ</kbd> (во время симуляции)</span> <span class="ctrl-desc">Пока симуляция запущена, пробел не нужен — тяни мышью напрямую</span> <span class="ctrl-key"><kbd>СКМ</kbd></span> <span class="ctrl-desc">Средняя кнопка мыши — перемещение поля (альтернатива пробелу)</span> </div> <h2>Рисование</h2> <div class="ctrl-table"> <span class="ctrl-key"><kbd>ЛКМ</kbd></span> <span class="ctrl-desc">Тоггл клетки; при зажатой кнопке и движении — рисование вдоль пути</span> <span class="ctrl-key"><kbd>E</kbd> / <kbd>D</kbd></span> <span class="ctrl-desc"><kbd>E</kbd> — режим ластика (убивает клетки в радиусе кисти); <kbd>D</kbd> — режим кисти (рисует живые)</span> <span class="ctrl-key"><kbd>S</kbd></span> <span class="ctrl-desc">Переключение формы кисти: круглая ○ или квадратная □</span> <span class="ctrl-key"><kbd>[</kbd> / <kbd>]</kbd></span> <span class="ctrl-desc">Уменьшить / увеличить радиус кисти; диаметр от 1 до 15 клеток. Текущий размер виден в статусной строке</span> </div> <p class="ctrl-note">Редактирование доступно в режимах «стоп» и «пауза» — во время симуляции поле заблокировано.</p> <h2>Паттерны</h2> <div class="ctrl-table"> <span class="ctrl-key"><kbd>ЛКМ</kbd></span> <span class="ctrl-desc">Поставить выбранный паттерн на поле. Использует XOR: повторное наложение той же формации точно поверх неё удаляет её</span> <span class="ctrl-key"><kbd>R</kbd></span> <span class="ctrl-desc">Повернуть активный паттерн на 90° по часовой стрелке (можно нажимать несколько раз)</span> <span class="ctrl-key"><kbd>F</kbd></span> <span class="ctrl-desc">Зеркально отразить паттерн горизонтально. Работает совместно с поворотом: четыре поворота × два отражения = восемь ориентаций</span> <span class="ctrl-key"><kbd>Esc</kbd></span> <span class="ctrl-desc">Снять паттерн с курсора, вернуться в режим рисования</span> </div> <h2>Слой меток (десктоп)</h2> <div class="ctrl-table"> <span class="ctrl-key"><kbd>1</kbd> / <kbd>2</kbd> / <kbd>3</kbd></span> <span class="ctrl-desc">Переключиться на слой меток — цвет 1 (красный), 2 (синий), 3 (жёлтый). Все инструменты (кисть, ластик, штамп, выделение) работают на слое меток, не трогая основное поле</span> <span class="ctrl-key"><kbd>0</kbd></span> <span class="ctrl-desc">Вернуться на основной слой. Метки остаются на экране — симуляция их не видит и не изменяет</span> <span class="ctrl-key"><kbd>\</kbd></span> <span class="ctrl-desc">Показать / скрыть слой меток целиком (toggle)</span> </div> <h2>Выделение (десктоп)</h2> <div class="ctrl-table"> <span class="ctrl-key"><kbd>M</kbd></span> <span class="ctrl-desc">Включить / выключить режим выделения. В этом режиме ЛКМ рисует прямоугольник выделения. Клик внутри готового прямоугольника — перетащить выделенные клетки</span> <span class="ctrl-key"><kbd>Ctrl</kbd>+<kbd>C</kbd></span> <span class="ctrl-desc">Скопировать клетки внутри прямоугольника в буфер</span> <span class="ctrl-key"><kbd>Ctrl</kbd>+<kbd>X</kbd></span> <span class="ctrl-desc">Вырезать — скопировать и удалить клетки из прямоугольника</span> <span class="ctrl-key"><kbd>Ctrl</kbd>+<kbd>V</kbd></span> <span class="ctrl-desc">Вставить из буфера — переходит в режим штампа, клетки «висят» на курсоре до щелчка</span> <span class="ctrl-key"><kbd>Del</kbd></span> <span class="ctrl-desc">Удалить все клетки внутри прямоугольника выделения</span> <span class="ctrl-key"><kbd>R</kbd> / <kbd>F</kbd></span> <span class="ctrl-desc">Повернуть / отразить клетки внутри выделения на месте (в режиме выделения; вне выделения — применяется к паттерну на курсоре)</span> </div> <h2>Прочие клавиши</h2> <div class="ctrl-table"> <span class="ctrl-key"><kbd>V</kbd></span> <span class="ctrl-desc">Вписать все клетки в экран — камера масштабируется и центрируется по паттерну</span> <span class="ctrl-key"><kbd>.</kbd></span> <span class="ctrl-desc">Шаг вперёд на одно поколение (работает при остановленной симуляции)</span> <span class="ctrl-key"><kbd>+</kbd> / <kbd>-</kbd></span> <span class="ctrl-desc">Увеличить / уменьшить масштаб</span> <span class="ctrl-key"><kbd>H</kbd></span> <span class="ctrl-desc">Показать / скрыть быструю справку по клавишам прямо на холсте</span> </div> <h2>Кнопки</h2> <div class="ctrl-table"> <span class="ctrl-key ctrl-btn-lbl">▶ Play</span> <span class="ctrl-desc">Запустить симуляцию</span> <span class="ctrl-key ctrl-btn-lbl">⏸ Pause</span> <span class="ctrl-desc">Приостановить — счётчик поколений сохраняется, поле можно редактировать</span> <span class="ctrl-key ctrl-btn-lbl">⏹ Stop</span> <span class="ctrl-desc">Остановить — поле откатывается к снимку, сделанному при последнем Play</span> <span class="ctrl-key ctrl-btn-lbl">↺ Reset</span> <span class="ctrl-desc">Вернуть поле к состоянию перед запуском</span> <span class="ctrl-key ctrl-btn-lbl">⊘ Clear</span> <span class="ctrl-desc">Очистить всё поле</span> </div> <p class="ctrl-note"><strong>Pause vs Stop:</strong> Pause ставит симуляцию на паузу — при следующем Play она продолжится с того же поколения. Stop откатывает поле к снимку, сделанному при нажатии Play, — удобно, чтобы начать тот же опыт заново.</p> <h2>Алгоритмы</h2> <div class="algo-list"> <div class="algo-item"> <div class="algo-name">Sparse (packed)</div> <div class="algo-desc">Хранит только живые клетки в хэш-таблице; ключи — числа с bit-packing (±33 млн клеток). В 3–5× быстрее строковых ключей. Лучший выбор для большинства задач.</div> </div> <div class="algo-item"> <div class="algo-name">Sparse (BigInt)</div> <div class="algo-desc">То же, но ключи — BigInt: произвольный диапазон координат. В 3–10× медленнее packed-варианта. Нужен только при координатах за ±33 млн клеток.</div> </div> <div class="algo-item"> <div class="algo-name">Classic</div> <div class="algo-desc">Два Uint8Array с двойной буферизацией. Перебирает всё поле каждый тик — отличная локальность памяти, хорош для плотных паттернов. Поле ограничено по размеру.</div> </div> <div class="algo-item"> <div class="algo-name">HashLife</div> <div class="algo-desc">Квад-дерево + мемоизация. Одинаковые подпаттерны вычисляются один раз и кэшируются. На периодических структурах (глайдеры, пушки, осцилляторы) на порядки быстрее остальных. Хуже на хаотичных полях.</div> </div> </div> <h2>Настройки</h2> <p>Кнопка <strong>⚙</strong> в панели меню открывает настройки интерфейса:</p> <div class="ctrl-table"> <span class="ctrl-key ctrl-btn-lbl">Масштаб интерфейса</span> <span class="ctrl-desc">Увеличивает или уменьшает все шрифты: кнопки, заголовки, тексты модальных окон и подписи на палитре (80 % — 130 %)</span> <span class="ctrl-key ctrl-btn-lbl">Плашка палитры</span> <span class="ctrl-desc">Ширина карточки в плавающей палитре; минимальная ширина окна палитры подстраивается автоматически</span> <span class="ctrl-key ctrl-btn-lbl">Плашка библиотеки</span> <span class="ctrl-desc">Минимальная ширина карточки в сетке библиотеки формаций</span> <span class="ctrl-key ctrl-btn-lbl">Плашка поиска</span> <span class="ctrl-desc">Минимальная ширина плашки результата в суп-поиске</span> </div> <p>Настройки сохраняются в браузере автоматически. Кнопка <em>Сбросить настройки</em> возвращает всё к значениям по умолчанию.</p> </div> </div> </div> <div id="help-footer"> Исходный код: <a href="https://gitverse.ru/hamster75/Life" target="_blank" rel="noopener">gitverse.ru/hamster75/Life</a> </div> </div>`; export class HelpModal { constructor({ onOpenAcademy } = {}) { this._onOpenAcademy = onOpenAcademy; this._open = false; this._create(); } _create() { this._overlay = document.createElement('div'); this._overlay.id = 'help-overlay'; this._overlay.innerHTML = TEMPLATE; document.body.appendChild(this._overlay); document.getElementById('help-close').addEventListener('click', () => this.close()); this._overlay.addEventListener('click', e => { if (e.target === this._overlay) this.close(); }); document.addEventListener('keydown', e => { if (e.key === 'Escape' && this._open) this.close(); }); this._overlay.querySelectorAll('.help-academy-btn-any').forEach(btn => { btn.addEventListener('click', () => { this.close(); this._onOpenAcademy?.(); }); }); } open() { if (this._open) return; this._overlay.classList.add('visible'); this._open = true; } close() { if (!this._open) return; this._overlay.classList.remove('visible'); this._open = false; } }