В проекте генерации уличных табличек нужен был простой и быстрый механизм ввода улицы и номера дома. И хотелось сразу видеть примерный внешний вид будущей таблички. Но так как все макеты вариативны, то есть размер таблички зависит от содержания, решение этой задачи пришло не сразу. И если разная ширина знака это решаемая задача, то разные стили в одной строке стали камнем преткновения.
Чего хочется?
Когда подбираешь товар по опциям, хочется, чтобы список предложений сразу обновлялся. Когда выбираешь «темную тему», хочется, чтобы интерфейс сразу обновился. Когда добавляешь гигабайты в тариф, хочется, чтобы сразу было видно окончательную сумму.
Когда генерируешь дизайн, всегда хочется видеть окончательный вариант, и желательно после каждого изменения данных, и желательно поскорее, а ещё со всеми деталями. Веб-интерфейс располагает к этому: есть события, можно программировать любые действия. И генератор этих табличек не должен быть исключением. Конечно, какая-то задержка по времени возможна, ведь главное тут было — схожесть превью с окончательным вариантом. Поэтому и произошла вся нижеследующая история.
Текст — в инпуты?
Сначала было решение, которое лежало на поверхности — сделать на html+css форму в виде готовой таблички уличного указателя. Пользователь сразу бы вводил текст в макет. Плюсы этого метода очевидны: макет предстает перед нами в готовом виде. Конечно, какие-то отклонения от конечного результата будут, но мы же всегда может поставить *.
Я заверстал знак со всеми деталями: скругления, тени, размеры. Одним словом — увлекся. Сделал методы пересчёта ширины макета при длинном названии, сделал события из PDF для переноса строк и слов. И всё было бы отлично, но...
В макете у таблички с номером дома сам номер дома может состоять из двух частей: до и после дроби. И та часть, которая после дроби, набирается меньшим по размеру шрифтом. А ещё есть буквы у номеров домов — и у них размер ещё меньше! И как это реализовать в инпуте?
Наверняка нашлись бы решения на html+css, но не хотелось тратить на это время, потому что сразу бы возникал вопрос поддержки всех браузеров для разных устройств. Но нам нужен простой инструмент, которым можно пользоваться с любого устройства.
PDF — в превью?
Следующим решением было такое же очевидное — показывать превью готового файла pdf на странице сайта. Пользователь выбирает макет, вводит текст в отдельные инпуты, а в нижней части экрана отображается готовый макет. Плюсы тоже очевидны: результат, так сказать, налицо — весь готовый макет.
Тут же нам помогла js-библиотека, которая отображает PDF-файл в окошке iframe с некоторыми настройками. И тут тоже начались проблемы: разные браузеры по-разному отображают интерфейс: полосы прокрутки, заголовок и кнопки управления файлом. Но это всё было бы ничего. Главная засада была в том, что размер макетов менялся и вписывался совершенно непредсказуемо: отображалась часть документа или он был слишком маленьким.
Самые большие отклонения были в Сафари, а это основной браузер у всех маководов. И от этого решения пришлось отказаться.
В какой-то момент была даже мысль показывать 2 варианта превью: для одних табличек — html+css, а для других — превью pdf-файла:
PDF — в растр!
Окончательное решение оказалось совершенно неожиданным. Я нашёл js-библиотеку, которая превращает PDF-файл в канвас. А канвас — это уже растр, который точно вписывается на сайт со всеми стилями. Работает она медленнее, но зато результат удовлетворял всем требованиям. Так как таблички — это достаточно простые макеты, скорость генерации должна быть не большой. Так и оказалось.
Для пользователей с мониторами повышенной плотности я генерировал растр нужного качества. Поэтому даже на ретина-дисплеях файлы превью выглядят отлично.
Итоги
Такой сложный путь «от инпутов до растра» из PDF случился, потому что это были первые мои вариативные макеты. Теперь есть несколько отработанных вариантов показа превью, из которых можно выбрать подходящий для будущих табличек или знаков.