生成网格并使用div元素填充空单元格

时间:2017-05-02 08:27:52

标签: javascript grid lodash

我希望按尺寸6x5生成一些网格,默认情况下整体意味着30个单元格虽然它可以拥有更少的单元格,因为所有单元格都应该是可拖动和可调整大小的。

现在我有一些关于默认网格的内容

_.map(items, (item, i) => {
    return {x: i * 1 % 6, y: Math.floor(i / 6) * 2, w: 1, h: 1, i: i.toString()};
});

它使用div元素填充网格上的30个单元格,但如果网格已经预定义了一些自定义单元格,那么需要检查哪些单元格为空并且相应地设置坐标x,y和w,h哪里有空闲不与现有细胞发生碰撞的空间。

它不应该是网格的任何复杂,它计划工作简单,因为我认为通过保持数组中的信息有类似于该模式的东西,但也许有更好的解决方案如何组织它。

[
[xxxxxx],
[xxxxxx],
[xxxxxx],
[xxxxxx],
[xxxxxx]
]

正如我写的那样,如果数据库返回网格的信息,它可能看起来像这样,例如,

let db = {
0: {x:1,y:0,w:2:h1},
1: {x:4,y:0,w:1:h1},
2: {x:3,y:2,w:2:h2},
}

分别对网格看起来像

的信息
[
[x00x1x],
[xxxxxx],
[xxx22x],
[xxx22x],
[xxxxxx]
]

之后需要用空div个元素重新填充空单元格。但是上面指定的功能没有检查并导致问题

1 个答案:

答案 0 :(得分:2)

如果我理解你的目标,你想根据坐标和宽度/高度的数组生成一个带有填充单元格的网格,这样写(你的问题中有拼写错误,所以我在这里重写了它):

let db = {
  0: { x: 1, y: 0, w: 2, h: 1 },
  1: { x: 4, y: 0, w: 1, h: 1 },
  2: { x: 3, y: 2, w: 2, h: 2 },
}

为了方便,它将以这种方式表示:

x00x1x
xxxxxx
xxx22x
xxx22x
xxxxxx

由于您在问题上使用了ES6语法和lodash,我也会在提议的答案中使用它,但我想提一下,这需要在没有lodash的情况下进行更改,并且可能无法在某些系统上运行实验性功能在这里使用。

建议的方法:



let db = {
    0: { x:1, y:0, w:2, h:1 },
    1: { x:4, y:0, w:1, h:1 },
    2: { x:3, y:2, w:2, h:2 },
};

// Generate the default grid
const emptyGrid = (rows, cols) => 
[...Array(rows).keys()].map((e, row) =>
	[...Array(cols).keys()].map((e, col) =>
  	({ x: col, y: row, w: 0, h: 0 })));

// Generate array of cell coordinates to fill from width and height
const cellCoords = cell => {
    let coords = [];
    for (let i = cell.w - 1; i >= 0; i--)
        for (let j = cell.h - 1; j >= 0; j--)
            coords = [...coords, {x: cell.x + i, y: cell.y + j}];
    return coords;
};

// Generate a grid of rows by cols, filled with optional cells data
const generateGrid = (rows, cols, cells) => {
  cells = cells || [];
	return _.reduce(cells, (grid, cell, index) =>  {
        cellCoords(cell).forEach(({x, y}) =>
        	grid[y][x] = {...grid[y][x], ...cell, i: index});
        return grid;
    }, emptyGrid(rows, cols));
}

// Here are some utilities for the snippet exemple
const displayGrid = (grid, target) => {
		grid = _.map(grid, row => _.reduce(row, (s, c) => s + (c.i ? c.i.toString() : 'x'), ''));
    document.getElementById(target).innerHTML = grid.join('<br/>');
}

displayGrid(generateGrid(5, 6), 'output')
displayGrid(generateGrid(5, 6, db), 'output-prefilled')
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Empty Grid:
<div id="output" style="margin:10px"></div>

Prefilled Grid:
<div id="output-prefilled" style="margin:10px"></div>
&#13;
&#13;
&#13;