An open API service indexing awesome lists of open source software.

https://github.com/denull/paver.js

Image layout library for JavaScript
https://github.com/denull/paver.js

Last synced: 11 months ago
JSON representation

Image layout library for JavaScript

Awesome Lists containing this project

README

          

Paver.JS
========

Библиотека для укладки изображений (или любых других прямоугольных тайлов, допускающих масштабирование) на JavaScript.

Демо: http://denull.github.io/Paver.JS

# Предназначение и суть работы

По принципу работы библиотека ближе всего к тому, как Google выкладывает результаты поиска картинок: изображения укладываются последовательно горизонтально, масштабируясь под общую высоту ряда, пока ряд (при условии, что он растянут до заданной ширины) не станет ниже определенной высоты *`maxRowHeight`*.

Это позволяет аккуратно выкладывать фотографии различных пропорций, не прибегая к значительной обрезке.

Однако, с моей точки зрения, такой алгоритм (а ля Google.Images) можно улучшить: прежде чем класть новое фото в ряду справа от предыдущего, Paver.JS пытается разместить его под ним, создавая вертикальную «стопку» внутри ряда. Это помогает уменьшить дискриминацию вертикальных фото в исходном алгоритме: если горизонтальные (ландшафтные) фотографии выкладывать не объединяя в «стопки», они оказываются раза в два больше по площади, чем портретные.

Формирование вертикальных «стопок» ограничивается двумя параметрами: минимальная ширина стопки *`minStackWidth`* (так как добавление в неё новых фото делает её уже) и минимальная высота отдельной фотографии *`minTileHeight`* (так как вся стопка будет масштабирована к искомой высоте формируемого ряда).

Наконец, у библиотеки есть ещё более «умный» режим, основанный на площади тайлов, и в котором высота ряда не является фиксированной, а подбирается, исходя из четырех параметров: *`minRowHeight`* и *`maxRowHeight`* ограничивают диапазон возможных значений высоты, *`optimizeSteps`* задают число шагов между ними, *`preferredArea`* -- оптимальная площадь каждого тайла после укладки. Для каждого ряда будет произведено *`optimizeSteps`* попыток уложить фотографии (варьируя высоту ряда) и будет выбран тот вариант, при котором среднее отклонение площади тайла от оптимальной будет минимально. Например, для ряда с вертикальными фото может быть выбрана высота побольше, с горизонтальными -- поменьше.

# Использование

Для использования библиотеки необходимо подключить *paver.js*.

Создание укладчика:

````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)`*:

````js
Paver(dataSource, width, opts).render(element);
````