Перейти к содержанию

Доступное управление и передача редактора

В предыдущих уроках мы построили модель, SVG, ввод, историю, сохранение и экспорт. Теперь рассмотрим редактор как цельный инструмент. Пользователь должен понимать, что выбрано, какое действие завершено и как продолжить после ошибки. Другой разработчик должен отличать подготовленные возможности от проверенных. К концу урока составим маршрут работы и передачу проекта без обещания ещё не подтверждённой готовности.

Полный проект «Схема» доступен в архиве исходников. Это законченный снимок учебного приложения, а не набор выполненных сборок каждого урока. Во время написания код не запускался и тесты не выполнялись. Ниже описаны сценарии для будущей технической проверки, а не отчёт об их прохождении.

Два пути к одному действию

Нажатие на рисунок и перетаскивание — только один способ работы. Список слоёв содержит настоящие HTML-кнопки. Панель свойств имеет подписанные поля и кнопку применения. Отдельные кнопки двигают выбранный объект на десять единиц. Благодаря этому основной набор изменений доступен без точного попадания указателем в небольшую фигуру.

Важна общая реализация команд. Клавиатурные кнопки используют moveShape(), форма и указатель заканчиваются принятием того же проверяемого документа. Если доступная панель начнёт жить по отдельным правилам геометрии, она быстро разойдётся с полотном. Доступность здесь возникает из архитектуры действий, а не только из добавленных атрибутов.

SVG имеет роль изображения и текстовое название. Само по себе это не превращает каждую фигуру в удобный объект для экранного диктора. В нашей версии семантический путь к объектам проходит через список. Для редактора сложных графов потребовались бы более подробные названия связей, структура групп и проверка реальными вспомогательными технологиями.

Названия и состояние элементов

Кнопки слоёв показывают подпись или тип и идентификатор. Выбранное состояние передаётся через aria-pressed. Поля размещены внутри подписанных элементов формы, а недоступная панель отключается через fieldset.disabled. Пользователь не должен отправить свойства, когда фигура не выбрана или выполняется перемещение.

Важно различать отсутствие возможности и ошибку. Если история пуста, «Отменить» отключено — это нормальное состояние. Если импорт повреждён, выводим сообщение и сохраняем рабочий документ. Если локальное хранилище недоступно, предлагаем скачать JSON. Один универсальный текст «Что-то пошло не так» не помогает решить эти разные задачи.

В CSS предусмотрен видимый фокус. Проверять его нужно при реальной работе клавиатурой: цветовая обводка, хорошо заметная на белом фоне, может быть слабой рядом с окрашенной кнопкой. Также нужно оценить порядок переходов после перестройки списка. Наш способ пересоздания элементов прост, но может потребовать улучшения сохранения фокуса при росте интерфейса.

Сообщения о результате

Область status сообщает о завершении перемещения, применении свойств, импорте и ошибках. Для неё используется ненавязчивое живое объявление. Мы не объявляем координаты на каждом pointermove: десятки сообщений подряд сделали бы редактор трудным для прослушивания. Во время движения меняется изображение, а сообщение появляется на границе операции.

Сообщение автосохранения может заменить текст предыдущего действия через 400 миллисекунд. Это допустимая простая версия, но при дальнейшем развитии полезно разделить подтверждение команды и состояние хранения. Иначе важное объяснение легко исчезнет из общей строки. Необходимо также решить, какие сообщения должны оставаться видимыми до исправления ошибки.

function commit(doc, message) {
  history.commit(doc);
  redraw();
  saveLater();
  if (message) announce(message);
}

Это общий путь завершённого изменения. Он показывает, где согласуются данные, интерфейс и запись. Внутри отдельных кнопок не приходится снова придумывать порядок действий. При расширении редактора полезно сохранять этот единый путь, а специализированные сообщения передавать аргументом.

Учебный маршрут пользователя

Начните с открытия примера. Выберите «Редактор» в списке, поменяйте подпись и примените форму. Сдвиньте объект кнопкой вправо, отмените и повторите. Затем выполните перетаскивание, прервите его Escape и убедитесь, что исходное положение восстановлено. После этого приблизьте сцену и верните весь лист.

Далее скачайте JSON, измените рисунок и импортируйте прежний файл. Ожидается замена модели с возможностью отмены. Выгрузите SVG и PNG: оба должны показывать полный лист без текущего выделения. Этот маршрут проходит через несколько подсистем, поэтому полезнее простого просмотра начальной сцены. Он остаётся планом проверки до фактического выполнения.

Ситуация Ожидаемое продолжение
Указатель отменён браузером Возврат исходного положения и включение управления
Неверные свойства Прежний документ и сообщение
Повреждённый JSON Прежний документ и возможность выбрать другой файл
Ошибка localStorage Работа в памяти и скачивание JSON
Не удалось получить PNG Сообщение без фиктивного успеха

Для проверки сенсорного ввода нужен реальный браузер и устройство либо обоснованная эмуляция. Наличие Pointer Events в коде не подтверждает, что все жесты удобны на телефоне. Аналогично наличие aria-live не доказывает качество озвучивания. Эти факты нельзя выводить только из чтения исходников.

Перед передачей полезно также описать данные, которые приложение не отправляет. В этой версии схема читается и сохраняется локально, серверной синхронизации нет. Но сам способ размещения редактора может добавить аналитику или сторонние ресурсы, поэтому вывод о приватности относится к конкретному набору файлов. Разработчик, который включит загрузку документов на сервер, должен заново объяснить пользователю этот переход и срок хранения.

Передача проекта

README перечисляет файлы, формат документа, пределы и способ локального открытия через HTTP-сервер. Модули разделены по смыслу: модель не зависит от DOM, рендерер создаёт изображение, файловый модуль отвечает за чтение и экспорт, main.mjs связывает интерфейс. Следующему разработчику проще найти место изменения, чем в одном длинном обработчике страницы.

Явно запишите ограничения: только прямоугольники и эллипсы, не более 200 фигур, история до сорока снимков, JSON до одного мебибайта. Нет соединительных линий, свободных путей, совместного редактирования, внешних картинок и автоматического переноса подписей. Эти функции можно добавить, но каждое расширение должно пройти через модель, ввод, историю и оба пути экспорта.

Например, добавление стрелки между объектами потребует устойчивых ссылок на идентификаторы и правила удаления связанной фигуры. Просто нарисовать линию в SVG недостаточно. Подобные изменения полезно начинать с договора данных, как мы сделали в первом уроке. Серия дала основу редактора, которую можно расширять последовательно, а техническую проверку, измерения и публикацию проводить отдельными осознанными этапами.

Оглавление серии