Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

Как добавить координатную сетку с динамическим добавлением ячеек по вертикали?

#javascript #css #angularjs


Есть поле с блоками, которые можно перемещать и менять их размер http://jsfiddle.net/qqzvjvfx/24/
Используются angular-gridster.js и flexbox.

Пример кода:

  
  • {{ block.title }}
Angular Controller: angular.module('someApp', ['gridster']).controller('someCtrl', function ($scope, $http) { $scope.gridsterOpts = { resizable: { enabled: true }, columns: 4, rows: 16, minRows: 4, margins: [0,0], floating: false }; $scope.sorted_blocks = [{ id: 1, sizeX: 1, sizeY: 1, image: 'http://i.imgur.com/NI1Xm16.jpg', title: 'title1', row: 1, col: 2 }, { id: 2, sizeX: 2, sizeY: 1, image: 'http://i.imgur.com/x6qmeUY.jpg', title: 'title2', row: 0, col: 0 }]; }); Css: .panel { display: flex; flex-flow: column wrap; height: 100%; } .panel .panel-content { flex-grow: 1; } .image-responsive { background-size: contain; background-repeat: no-repeat; } Нужно добавить сетку на поле, по котором перемещаются блоки, например, как в inkscape или вот такую. Предположим, поле имеет 4 колонки и от 4 до 16 строк. Отображаем 4 вертикальных линий и от 4 до 16 горизонтальных (зависит от размера отображаемой области). Причем если, например, блок имеет размер 1х1, то при любом размере окна этот блок должен четко занимать 1 клетку в сетке, если 3х2 - то три клетки по горизонтали, и 2 по вертикали соответственно. С другими размерами блоков аналогично. Пытаюсь сделать через таблицы: http://jsfiddle.net/qqzvjvfx/18/ Но как учесть то, что поле может увеличиваться по вертикали? Т.е. у него добавляются строки, соответственно, у таблицы для сетки тоже должны добавляться строки. Сейчас же таблица просто растягивается по вертикали. Через background-image - если я правильно понимаю, мне нужно использовать background-size: cover. Но по вертикали поле может увеличиваться, соответственно, необходимо добавлять фон по высоте, а не растягивать. Здесь я добавил вместо таблицы div, как мне прикрутить правильно фон к этому диву, чтобы по горизонтали фон масштабировался (растягивался) в зависимости от ширины этого div (и соответственно ширины поля, на котором перемещаются блоки), а по вертикали повторялся? Также пытался найти какой-то встроенный функционал в angular-gridster.js, ведь он подсвечивает области в момент перетаскивания блока, однако поиски пока не увенчались успехом. Уточнение: На сетке необходимо также выделить некую область рамкой Размер области заранее известен - в ячейках, а не в px. Поэтому исходя из этого пока использование таблиц удобнее по идее. Обновление: Вариант с таблицей и динамическим обновлением количества строк http://jsfiddle.net/qqzvjvfx/26/ - отслеживаю изменения в блоках, но блок меняет свою позицию в момент отпускания, а высота поля увеличивается "на всякий случай" заранее, т.е. отслеживать необходимо не ресайз/перемещение блоков, а ресайз общего контейнера гридстера. обновление 2: http://jsfiddle.net/sfn57eyh/1/ видно, что проблема построения сетки в том, что необходимо знать текущее количество ячеек контейнера по высоте, т.к. оно может меняться. в данном примере из-за этого высота ячеек сетки дергается.


Ответы

Ответ 1



Один из вариантов: задать повторяющийся фон из квадратов для главного элемента. Но, так как размер сетки может меняться, то изображение для фона должно уметь масштабироваться и для этого подходит svg Например такое (rect2.svg) Теперь единственное нужно прописать его в качестве фона, и задать размер - равный размеру ячейки в гридстере. Осталось только определить размер ячейки грида. Например это можно сделать с помощью своей директивы .directive('mygr', function () { return { require: 'gridster', link: function (scope, elem, attr, ctrl) { //ctrl - контроллер гридстера. var w = scope.$watch(function () { return ctrl.curRowHeight }, function (n) {// ждем пока поменяется(будет вычислена) высота строки elem.css('background-size',ctrl.curColWidth + 'px ' + ctrl.curRowHeight + 'px');//выставляем background-size w();// перестаем наблюдать }); } } }); и применяем ее
Пример, все вместе Важно: возможны проблемы с округлением или отрисовкой, поэтому при некоторых условиях. Кроме того возможны проблемы с производительностью из-за использования svg - если размер контейнера большой, а размер сетки - маленький.

Ответ 2



Сетку для гридстера можно добавить при помощи задания css опций background для основного контейнера. При этом требуется учесть, что если размер ячейки формировать непосредственно исходя из размера контейнера, то он выйдет не целочисленным и итемы на гридстере будут размещаться не по краям ячеек. Поэтому приходится ограничивать ширину гридстера числами, кратными максимальному количеству ячеек, а опираться на ширину div'а-обёртки. Текстуру фона при этом можно создавать динамически при помощи canvas, либо использовать svg фон. В зависимости от того, как кэшируются оба решения можно выбрать одно из них в плане производительности. В решении используется canvas, результат отрисовки которого попадает в background: var canvas = document.createElement('canvas'); canvas.width = sizeX; canvas.height = sizeX; var context=canvas.getContext("2d"); context.beginPath(); context.rect(0, 0, sizeX, sizeX); context.fillStyle = 'white'; context.fill(); context.lineWidth = 1; context.strokeStyle = 'gray'; context.stroke(); $('[gridster="gridsterOpts"]').css( "background-image", "url('"+canvas.toDataURL('image/jpeg')+"')");

Комментариев нет:

Отправить комментарий