{"id":20625529,"url":"https://github.com/denull/paver.js","last_synced_at":"2025-07-15T13:04:11.227Z","repository":{"id":19111888,"uuid":"22340703","full_name":"denull/Paver.JS","owner":"denull","description":"Image layout library for JavaScript","archived":false,"fork":false,"pushed_at":"2017-03-05T19:06:10.000Z","size":135,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"gh-pages","last_synced_at":"2025-04-15T15:08:22.003Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/denull.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-07-28T11:47:25.000Z","updated_at":"2017-07-26T10:39:37.000Z","dependencies_parsed_at":"2022-08-25T14:10:23.027Z","dependency_job_id":null,"html_url":"https://github.com/denull/Paver.JS","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/denull/Paver.JS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denull%2FPaver.JS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denull%2FPaver.JS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denull%2FPaver.JS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denull%2FPaver.JS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denull","download_url":"https://codeload.github.com/denull/Paver.JS/tar.gz/refs/heads/gh-pages","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denull%2FPaver.JS/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265437598,"owners_count":23765124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T13:09:56.185Z","updated_at":"2025-07-15T13:04:11.191Z","avatar_url":"https://github.com/denull.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Paver.JS\n========\n\nБиблиотека для укладки изображений (или любых других прямоугольных тайлов, допускающих масштабирование) на JavaScript.\n\nДемо: http://denull.github.io/Paver.JS\n\n# Предназначение и суть работы\n\nПо принципу работы библиотека ближе всего к тому, как Google выкладывает результаты поиска картинок: изображения укладываются последовательно горизонтально, масштабируясь под общую высоту ряда, пока ряд (при условии, что он растянут до заданной ширины) не станет ниже определенной высоты *`maxRowHeight`*.\n\nЭто позволяет аккуратно выкладывать фотографии различных пропорций, не прибегая к значительной обрезке.\n\nОднако, с моей точки зрения, такой алгоритм (а ля Google.Images) можно улучшить: прежде чем класть новое фото в ряду справа от предыдущего, Paver.JS пытается разместить его под ним, создавая вертикальную «стопку» внутри ряда. Это помогает уменьшить дискриминацию вертикальных фото в исходном алгоритме: если горизонтальные (ландшафтные) фотографии выкладывать не объединяя в «стопки», они оказываются раза в два больше по площади, чем портретные.\n\nФормирование вертикальных «стопок» ограничивается двумя параметрами: минимальная ширина стопки *`minStackWidth`* (так как добавление в неё новых фото делает её уже) и минимальная высота отдельной фотографии *`minTileHeight`* (так как вся стопка будет масштабирована к искомой высоте формируемого ряда).\n\nНаконец, у библиотеки есть ещё более «умный» режим, основанный на площади тайлов, и в котором высота ряда не является фиксированной, а подбирается, исходя из четырех параметров: *`minRowHeight`* и *`maxRowHeight`* ограничивают диапазон возможных значений высоты, *`optimizeSteps`* задают число шагов между ними, *`preferredArea`* -- оптимальная площадь каждого тайла после укладки. Для каждого ряда будет произведено *`optimizeSteps`* попыток уложить фотографии (варьируя высоту ряда) и будет выбран тот вариант, при котором среднее отклонение площади тайла от оптимальной будет минимально. Например, для ряда с вертикальными фото может быть выбрана высота побольше, с горизонтальными -- поменьше.\n\n# Использование\n\nДля использования библиотеки необходимо подключить *paver.js*.\n\nСоздание укладчика:\n\n````js\nPaver(dataSource, width, opts);\n````\n\n*`dataSource`* -- источник данных. Либо обычный массив с объектами, из которых нужно сделать тайлы, либо объект с двумя методами: *`count()`* -- получить количество элементов и *`get(i)`* -- получить i-й элемент.\n\nКаждый объект, описывающий данные тайла, должен содержать поля *`width`* и *`height`* с размерами исходного фото. В качестве альтернативы среди опций может быть передана функция *`getRatio`*, принимающая данные тайла и его индекс и возвращающая его пропорции (отношение ширины к высоте).\n\n*`width`* -- ширина контейнера в пикселях.\n\n*`opts`* -- объект с опциями. Список всех возможных опций (все необязательные):\n\n* *`preferredArea`* -- оптимальная площадь тайлов. При указании используется более медленный алгоритм, перебирающий несколько (а именно *`optimizeSteps`*) высот каждого ряда от *`minRowHeight`* до *`maxRowHeight`* и выбирающий из них наиболее оптимальную.\n* *`getPreferredArea`* -- функция, принимающая два параметра (данные тайла и его номер) и возвращающая его искомую площадь. Позволяет попытаться сделать некоторые фотографии больше других, если это возможно.\n* *`optimizeSteps`* -- число итераций при переборе высоты ряда. Используется только если указана искомая площадь *`preferredArea`*.\n* *`minRowHeight`* -- минимальная высота ряда при переборе. Используется только если указана искомая площадь *`preferredArea`*.\n* *`maxRowHeight`* -- максимальная высота ряда при переборе. Если не указана искомая площадь *`preferredArea`*, считается целевой высотой ряда (все ряды будут почти такой высоты или чуть ниже).\n* *`minStackWidth`* -- минимальная ширина стопки. Ограничивает стопки от того, чтобы они становились слишком вытянутыми вертикально (слишком узкими). Фото не будет добавлено в стопку, если это сделает её ширину меньше минимального значения.\n* *`minTileHeight`* -- минимальная высота тайла. Ограничивает стопки от того, чтобы фотографии в них становились слишком низкими. Фото не будет добавлено в стопку, если это сделает его высоту меньше минимального значения.\n* *`maxRatio`* -- максимальное отношение ширины к высоте тайла. Если на вход передано фото с пропорциями выше этого значения (слишком широкое), то его ширина будет обрезана.\n* *`minRatio`* -- минимальное отношение ширины к высоте тайла. Если на вход передано фото с пропорциями ниже этого значения (слишком высокое), то его высота будет обрезана.\n* *`margin`* -- ширина отступов между тайлами (по вертикали и по горизонтали).\n* *`noStacks`* -- если установлено в *`true`*, то вертикальные стопки в рядах формироваться не будут.\n* *`renderTile`* -- функция, которая будет использована для отрисовки каждого тайла. В качестве параметров ей будут переданы данные тайла (из исходного массива *`dataSource`*) и объект *`path`* с полями *`row`*, *`stack`* и *`tile`* -- индексом ряда (0 -- верхний), стопки в ряду (0 -- самая левая) и тайла в стопке (0 -- верхний). Функция должна вернуть HTML-элемент, соответствующий тайлу.\n* *`getRatio`* -- функция, возвращающая пропорции переданного в неё тайла. Первыми аргументом передаются данные из массива *`dataSource`*, вторым -- индекс в этом массиве. Вернуть следует одно число, отношение ширины тайла к высоте.\n* *`defaultSize`* -- размеры тайла по умолчанию (если у тайла отсутствуют поля *`width`* и *`height`*). Объект с полями *`width`* и *`height`*.\n\nУ объекта, возвращенного в результате вызова функции *`Paver(dataSource, width, opts)`* есть три метода:\n* *`build(fromRow)`* -- выполнить укладку заново с ряда *`fromRow`* (пока не поддерживается).\n* *`rebuild()`* -- выполнить укладку заново.\n* *`render(element)`* -- отрисовать результат укладки в элементе *`element`*.\n\nВсе три метода возвращают тот же объект.\n\nОбратите внимание, что при вызове *`Paver(dataSource, width, opts)`* (а также *`build(fromRow)`* и *`rebuild()`*) производится только укладка, но не создание визуальных элементов -- для этого необходимо вызвать метод *`render(element)`*, который в свою очередь будет вызывать переданную в качестве опции функцию *`renderTile(tile, path)`*:\n\n````js\nPaver(dataSource, width, opts).render(element);\n````\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenull%2Fpaver.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenull%2Fpaver.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenull%2Fpaver.js/lists"}