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

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

Написал своё в итоге, дальше расскажу что вышло, скрины ниже, там понятнее чем я объясню.

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

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

React, TypeScript, Vite, рисование на Konva — canvas, не SVG, SVG на паре сотен плиток тупит откровенно, я это на своей же ванной и поймал когда деталей стало много и всё зависло на секунду при клике. Zustand, всё в localStorage, бэкенда нет вообще. С PDF кстати отдельно намучался — margin криво стоял, печаталось какое‑то about:blank в углу листа, минут двадцать искал в чём дело, потом дошло что это @page надо было в ноль обнулить.

Обрезки — вот это отдельная история и, наверное, самая муторная. Смысл в том что от плитки отрезали кусок под один угол, а остаток может подойти для другого угла в другом месте комнаты. Движок такие пары ищет сам. Первая версия сравнивала по площади просто — есть площадь у обрезка, есть у детали, больше значит подходит, и это оказалось ерундой полной, потому что длинная узкая полоска по площади «подходила» под широкую и короткую деталь, натурально из рейки лопату вырезать предлагало на схеме. Два вечера на это ушло, там поворот на 90 градусов не учитывался, элементарно же, а я не сообразил сразу. На моей ванной в итоге всего две плитки так сэкономились, минус почти полторы тысячи — не то чтобы прорыв, но и не зря возился.

Да, и уголок 3 на 50 см ещё предлагало вырезать один раз, математика сходится а на объекте отвалится сразу же при резке, тут порог добавил — 5 см и 150 квадратных сантиметров минимум, цифры на глаз взял если честно, не от расчёта какого‑то.

Нумерация плиток — чтобы не гадать какой обрезок куда, тоже добавил, в PDF таблица теперь отдельная идёт с планом.

Целый угол у двери и у зеркала — это мне в комментах подсказали вообще, сам бы наверное не додумался, я думал что у меня и так есть центрирование, ну оно и правда было, просто крутить надо было циферки руками долго. Тыкаешь теперь в угол на схеме и сетка сама пересчитывается оттуда. Для диагонали там отдельно повозиться пришлось с координатами швов повёрнутыми, не буду туда лезть, скучно объяснять если честно.

Минимальная подрезка 5 см по умолчанию стоит, чтобы не было сантиметровых огрызков у стен — где не получается пишет «узкая подрезка 2.3 см у стены 3» и красит стену, оранжевым на самом деле, не красным.

Профилировал на телефоне кстати — один жест тащить угол комнаты, пятьдесят с чем‑то пересчётов вызывал, это уже сильно потом заметил когда всё тормозить начало на слабом телефоне у друга. Разделил на live/commit, ну и listening={false} на декоративных слоях. Было 26 мс, стало полтора — а потом этот же флаг сломал перетаскивание коробов, повесил его не туда, на тело препятствия, а у Group своей хит‑области нет, короб просто перестал существовать для мыши. Минут двадцать тупил почему не двигается, потом вспомнил.

Тур на driver.js — библиотека крошечная, кстати — но тур этот неделю никто не видел, потому что модалка «что нового» при первом заходе отмечала «уже всё видел» и тур решал что это не новичок. Тесты зелёные, а по факту не работало — нашёл случайно, в инкогнито зашёл проверить и увидел.

Планы — развёртки стен, ёлочка, несколько проектов сразу, руки не всегда доходят если честно.

На круг у меня на своей ванной вышло 16 341 ₽ — плитка, клей, затирка, крестики (у меня СВП, зажимы с клиньями). Не пятнадцать процентов от головы, а честная цифра из калькулятора.

Вот сам калькулятор: tilely.ru — бесплатный, без регистрации. Сломается что — пишите в комменты, починю.