javascript

Калькулятор плитки научился ёлочке и плану всей квартиры — что поменялось за месяц

  • суббота, 29 августа 2026 г. в 00:00:07
https://habr.com/ru/articles/1075904/

Прошлый раз я рассказал, как написал свой калькулятор раскладки плитки, потому что замучился считать ванную в столбик. Тот пост был про версию 1.2 — база, прямая/диагональная раскладка, смета, PDF, нумерация плиток. Комменты были классные, фидбек пошёл сразу, и за месяц я выкатил ещё три версии. Самое заметное — ёлочка и общий план квартиры, где все комнаты лежат на одном полотне. Про это и пишу.

## Ёлочка (v1.4.0)

Ёлочка — это когда плитка кладётся под углом друг к другу, как паркет. Спросили в комментах и в личке, так что сделал две вариации:

- «Ёлочка прямая» — плашки под 90° друг к другу, но сам паттерн повёрнут на 45° к стенам. Классическая паркетная раскладка.

- «Ёлочка диагональная» — весь паттерн повёрнут на 45°, плашки параллельны/перпендикулярны стенам.

Важный нюанс: ёлочка имеет смысл только для прямоугольной плитки с соотношением сторон 1:2 и длиннее. Для квадратной плитки опции заблокированы с подсказкой — ёлочку из квадратов не выложишь, это не паркет. А если в процессе сменил размер плитки на квадратную, активная ёлочка автоматически переключается на прямую раскладку с уведомлением. Не оставлять же человека с битой раскладкой.

По геометрии там отдельная история. Добавил старт от угла (anchor) и правило минимальной подрезки (min-cut): стены, где подрезка получается уже заданного порога, подсвечиваются оранжевым, а в панели итогов выводится конкретный список проблемных стен с размерами подрезки. Укладчик сразу видит, где надо сдвинуть раскладку или сменить стартовый угол. Автооптимизатор смещения для ёлочки честно отключается с информационным сообщением — раньше он «оптимизировал» ёлочку в обычную раскладку, и люди думали, что функция сломалась.

Повторное использование обрезков работает и в ёлочке. Это была самая противная часть — сопоставление подрезков и остатков по реальной геометрии с учётом поворота на 45°. Полигоны вписываются с поворотом, пары «из обрезка №» подсвечиваются зелёным на схеме, и это реально уменьшает сумму в смете. Для квадратной раскладки это сделал ещё в 1.1, для ёлочки пришлось переписать геометрию вращения.

Отдельно — обрезка плиток вокруг препятствий. Венткороба, вырезы под трубы: раньше пересекающиеся плашки иногда пропадали со схемы. Теперь они корректно подрезаются и учитываются в раскрое. В PDF и смете новые паттерны подписываются «Ёлочка». На всякий случай накатал полный комплект юнит-тестов на модуль herringbone — ёлочка легко ломается на граничных случаях.

## Общий план квартиры (v1.5.0)

Самое крупное за месяц. Раньше калькулятор считал одну комнату. Хочешь ванную и туалет — открывай два проекта по отдельности, считай в уме. Теперь все комнаты проекта лежат на едином полотне в общей системе координат и в едином реальном масштабе.

В шапке переключатель режимов «План» ⇄ «Комната». Выбор сохраняется в persist, так что при возврате не теряется. На плане комнаты можно таскать мышью/пальцем — снаппинг углов и рёбер предвычисляется, чтобы не дёргалось. Если зажать Alt, снаппинг отключается, для тонкой подгонки.

Валидация пересечений на drop: касание границ разрешено (комнаты могут примыкать), а вот пересечение площадей — нет, с возвратом и тост-уведомлением. Если комнату отредактировали контуром стены так, что она стала пересекать соседнюю, — красный контур и предупреждение. Не дать человеку сохранить невозможный план.

У каждой выбранной комнаты на плане всплывает мини-тулбар: переименование, дублирование, 10-секундное отменяемое удаление (Undo) и мгновенный переход внутрь комнаты. Новая комната по кнопке «+ Комната» появляется справа от крайнего помещения. Мелочь, но искать, куда делся новый прямоугольник, не нужно.

Формат снапшота уехал на v3. Старые снапшоты v2 автоматически раскладываются в ряд (зазор 500 мм, перенос строки после 10 м) при открытии — обратной совместимости ради. Добавил резервное поле layoutGroupId на будущее.

## Что было на стыке (v1.3.0)

Эта версия вышла за день до прошлой публикации, так что упомяну здесь, чтобы картина была цельной. Мультипроектность: до 50 проектов в локальном хранилище, переключатель в шапке с подсветкой активного, безопасное открытие проекта по ссылке в изолированном режиме с возможностью сохранить в «Мои проекты». Старт раскладки от выбранного угла (целая плитка на видном месте) и правило минимальной подрезки с фиолетовым маркером стартового угла. И онбординг-тур для новичков — 4 шага, кнопка «?» для повтора. Кстати, именно с туром в 1.1 была забавная засада: модалка «что нового» отмечала «уже всё видел» при первом заходе, и тур решал, что юзер не новичок. В инкогнито случайно заметил — тесты зелёные, а по факту не работало.

## Техническое

Стек не менялся: React, TypeScript, Vite, рисование на Konva (canvas, не SVG — на паре сотен плиток SVG откровенно тупит). Zustand, всё в localStorage, бэкенда нет. Версия снапшота v3, миграция старых проектов на v4 для мультипроектности прошла без потери данных.

Ёлочка считается на тех же примитивах, что и прямая раскладка, просто с поворотом матрицы на 45°. Вращение полигонов — отдельный модуль, покрытый тестами, потому что поворот на 45° легко ломает точность Float-координат на больших площадях.

## Итог

За месяц калькулятор вырос из «считалки для одной ванной» в инструмент для раскладки всей квартиры, с паркетной ёлочкой и честной экономией на обрезках. Ссылка та же: tilely.ru — бесплатный, без регистрации, ставится как приложение на телефон.

Сломается что или нужна фича — пишите в комменты, починю. Следующий кандидат по фидбеку — развёртки стен, но руки доходят не всегда, если честно.