Библиотека для укладки изображений (или любых других прямоугольных тайлов, допускающих масштабирование) на JavaScript.
Демо: http://denull.github.io/Paver.JS
По принципу работы библиотека ближе всего к тому, как Google выкладывает результаты поиска картинок: изображения укладываются последовательно горизонтально, масштабируясь под общую высоту ряда, пока ряд (при условии, что он растянут до заданной ширины) не станет ниже определенной высоты maxRowHeight
.
Это позволяет аккуратно выкладывать фотографии различных пропорций, не прибегая к значительной обрезке.
Однако, с моей точки зрения, такой алгоритм (а ля Google.Images) можно улучшить: прежде чем класть новое фото в ряду справа от предыдущего, Paver.JS пытается разместить его под ним, создавая вертикальную «стопку» внутри ряда. Это помогает уменьшить дискриминацию вертикальных фото в исходном алгоритме: если горизонтальные (ландшафтные) фотографии выкладывать не объединяя в «стопки», они оказываются раза в два больше по площади, чем портретные.
Формирование вертикальных «стопок» ограничивается двумя параметрами: минимальная ширина стопки minStackWidth
(так как добавление в неё новых фото делает её уже) и минимальная высота отдельной фотографии minTileHeight
(так как вся стопка будет масштабирована к искомой высоте формируемого ряда).
Наконец, у библиотеки есть ещё более «умный» режим, основанный на площади тайлов, и в котором высота ряда не является фиксированной, а подбирается, исходя из четырех параметров: minRowHeight
и maxRowHeight
ограничивают диапазон возможных значений высоты, optimizeSteps
задают число шагов между ними, preferredArea
-- оптимальная площадь каждого тайла после укладки. Для каждого ряда будет произведено optimizeSteps
попыток уложить фотографии (варьируя высоту ряда) и будет выбран тот вариант, при котором среднее отклонение площади тайла от оптимальной будет минимально. Например, для ряда с вертикальными фото может быть выбрана высота побольше, с горизонтальными -- поменьше.
Для использования библиотеки необходимо подключить paver.js.
Создание укладчика:
Paver(dataSource, width, opts);
dataSource
-- источник данных. Либо обычный массив с объектами, из которых нужно сделать тайлы, либо объект с двумя методами: count()
-- получить количество элементов и get(i)
-- получить i-й элемент.
Каждый объект, описывающий данные тайла, должен содержать поля width
и height
с размерами исходного фото. В качестве альтернативы среди опций может быть передана функция getRatio
, принимающая данные тайла и его индекс и возвращающая его пропорции (отношение ширины к высоте).
width
-- ширина контейнера в пикселях.
opts
-- объект с опциями. Список всех возможных опций (все необязательные):
preferredArea
-- оптимальная площадь тайлов. При указании используется более медленный алгоритм, перебирающий несколько (а именноoptimizeSteps
) высот каждого ряда отminRowHeight
доmaxRowHeight
и выбирающий из них наиболее оптимальную.getPreferredArea
-- функция, принимающая два параметра (данные тайла и его номер) и возвращающая его искомую площадь. Позволяет попытаться сделать некоторые фотографии больше других, если это возможно.optimizeSteps
-- число итераций при переборе высоты ряда. Используется только если указана искомая площадьpreferredArea
.minRowHeight
-- минимальная высота ряда при переборе. Используется только если указана искомая площадьpreferredArea
.maxRowHeight
-- максимальная высота ряда при переборе. Если не указана искомая площадьpreferredArea
, считается целевой высотой ряда (все ряды будут почти такой высоты или чуть ниже).minStackWidth
-- минимальная ширина стопки. Ограничивает стопки от того, чтобы они становились слишком вытянутыми вертикально (слишком узкими). Фото не будет добавлено в стопку, если это сделает её ширину меньше минимального значения.minTileHeight
-- минимальная высота тайла. Ограничивает стопки от того, чтобы фотографии в них становились слишком низкими. Фото не будет добавлено в стопку, если это сделает его высоту меньше минимального значения.maxRatio
-- максимальное отношение ширины к высоте тайла. Если на вход передано фото с пропорциями выше этого значения (слишком широкое), то его ширина будет обрезана.minRatio
-- минимальное отношение ширины к высоте тайла. Если на вход передано фото с пропорциями ниже этого значения (слишком высокое), то его высота будет обрезана.margin
-- ширина отступов между тайлами (по вертикали и по горизонтали).noStacks
-- если установлено вtrue
, то вертикальные стопки в рядах формироваться не будут.renderTile
-- функция, которая будет использована для отрисовки каждого тайла. В качестве параметров ей будут переданы данные тайла (из исходного массиваdataSource
) и объектpath
с полямиrow
,stack
иtile
-- индексом ряда (0 -- верхний), стопки в ряду (0 -- самая левая) и тайла в стопке (0 -- верхний). Функция должна вернуть HTML-элемент, соответствующий тайлу.getRatio
-- функция, возвращающая пропорции переданного в неё тайла. Первыми аргументом передаются данные из массиваdataSource
, вторым -- индекс в этом массиве. Вернуть следует одно число, отношение ширины тайла к высоте.defaultSize
-- размеры тайла по умолчанию (если у тайла отсутствуют поляwidth
иheight
). Объект с полямиwidth
иheight
.
У объекта, возвращенного в результате вызова функции Paver(dataSource, width, opts)
есть три метода:
build(fromRow)
-- выполнить укладку заново с рядаfromRow
(пока не поддерживается).rebuild()
-- выполнить укладку заново.render(element)
-- отрисовать результат укладки в элементеelement
.
Все три метода возвращают тот же объект.
Обратите внимание, что при вызове Paver(dataSource, width, opts)
(а также build(fromRow)
и rebuild()
) производится только укладка, но не создание визуальных элементов -- для этого необходимо вызвать метод render(element)
, который в свою очередь будет вызывать переданную в качестве опции функцию renderTile(tile, path)
:
Paver(dataSource, width, opts).render(element);