There is a field with blocks that can be moved and resized by http://jsfiddle.net/qqzvjvfx/24/ Angular-gridster.js and flexbox .

Code example:

  <div ng-app="someApp" ng-controller="someCtrl"> <div gridster="gridsterOpts"> <ul> <li class="" gridster-item="block" ng-repeat="block in sorted_blocks"> <div class="panel panel-default"> <div class="panel-heading">{{ block.title }}</div> <div class="panel-content image-responsive" ng-style="{'background-image':'url(' + block.image + ')'}"></div> </div> </li> </ul> </div> </div> 

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; } 

It is necessary to add a grid to the field on which the blocks move, for example, as in inkscape or just this .

Suppose a field has 4 columns and from 4 to 16 lines. We display 4 vertical lines and from 4 to 16 horizontal (depending on the size of the displayed area). And if, for example, a block has a size of 1x1, then for any window size this block should clearly occupy 1 cell in the grid, if 3x2, then three cells horizontally, and 2 vertically, respectively. With other block sizes similarly.

I am trying to do it through the tables: http://jsfiddle.net/qqzvjvfx/18/ But how to take into account the fact that the field can increase vertically? Those. rows are added to it, respectively, rows should also be added to the grid table. Now the table is simply stretched vertically.

Through background-image - if I understand correctly, I need to use background-size: cover . But vertically the field can increase, respectively, it is necessary to add a background height, and not stretch. Here I added a div instead of the table, how can I screw the background to this diva correctly so that the background horizontally scales (stretched) depending on the width of this div (and the width of the field on which the blocks move) and repeated vertically?

I also tried to find some built-in functionality in angular-gridster.js , because it highlights the areas at the moment of dragging the block, but the searches have not yet been crowned with success.

Specification: On the grid, you must also select a certain area of ​​the frame. frame example The size of the region is known in advance — in cells, not in px. Therefore, based on this, the use of tables is more convenient in theory.

Update: A variant with a table and a dynamic update of the number of lines http://jsfiddle.net/qqzvjvfx/26/ - I track changes in blocks, but the block changes its position at the moment of release, and the field height increases "just in case" in advance, t. e. it is necessary to track not resize / relocation of blocks, but resize of the common gridster container.

Update 2: http://jsfiddle.net/sfn57eyh/1/ that the problem of building a grid is that it is necessary to know the current number of container cells in height, since it may change. in this example, because of this, the height of the grid cells is twitching.

  • one
    then the easiest way is to draw a single cell in some svg, so that it scales and make it background with repeat-x, repeat-y or something like that - Grundy
  • one
    about: after all, it highlights the area at the time of dragging the block - it just shows one div and only at the time of dragging - Grundy
  • one
    for the variant with the table, subscribe to change the position of the element and change the table in the handler: increase, decrease the number of rows - columns. - Grundy
  • one
    Too fiddling with this component, even the source code of the rules. As a result, it turned out to be easier to re-create the functionality with the help of standard components. If you want stretchability, normal mesh, nesting, etc., you will soon find out that the necessary crutches will take more time. - FLCL
  • 2
    Of course, because the gridster doesn’t occupy a width not a multiple of the number of cells, but this can be corrected by limiting the width of the gridder to multiples of jsfiddle.net/sfn57eyh/7 , fewer cells - less quanta - FLCL

2 answers 2

One option: set a repeating background of squares for the main element.

But, since the size of the grid can vary, the image for the background must be able to scale and svg is suitable for this

For example this (rect2.svg)

 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="100pt" height="100pt" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"> <rect x="0" y="0" width="100" height="100" fill="#ffffff" style="stroke: #000000; stroke-width: 1"></rect> </svg> 

Now the only thing you need to register it as a background, and set the size - equal to the size of the cell in the grid. It remains only to determine the grid cell size.
For example, this can be done with its directive

 .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();// перестаем наблюдать }); } } }); 

and apply it

 <div gridster="gridsterOpts" mygr=""> 

Example all together

Important: there may be problems with rounding or drawing, so under some conditions. In addition, there may be performance problems due to the use of svg - if the size of the container is large and the size of the grid is small.

  • In your decision not on the edges of the grid, you can put the items, probably the opera engine draws rectangles with rounding. - FLCL
  • @FLCL, yes, there it depends on the size of the cell, and possibly on the rounding that the gridster himself is conducting - Grundy
  • If you can solve this problem without a caste as an external container, then you could even create a pull-request to develop, pushto for this component is the first problem - FLCL
  • @FLCL, then maybe I did the svg myself, not really. Plus, I looked at the values ​​that are set for it - there are 5 points after the comma :-) for this example, maybe this is also a problem. By the way, you also have no external container - Grundy
  • With external id - d400, that's why it works - FLCL

The grid for the gridster can be added using the css background options for the main container. It is necessary to take into account that if the cell size is formed directly on the basis of the size of the container, then it will come out not integer and the items on the grid will not be located at the edges of the cells. Therefore, it is necessary to limit the width of the gridster to numbers that are multiples of the maximum number of cells, and rely on the width of the wrapper div'a. The texture of the background can be created dynamically using canvas, or use the svg background. Depending on how both solutions are cached, you can choose one of them in terms of performance.

The solution uses canvas , the result of which drawing falls into the 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')+"')");