在 Canvas 中是否有更有效的创建网格的方法?
Is there a more efficient way of creating a Grid in Canvas?
我正在使用 canvas 在图像上创建一个网格,这样我创建了我下面的 jsfiddle 中的内容。
http://jsfiddle.net/3bufekmh/1/
正如您从示例中看到的那样,我使用了大量的:
canvas.add(new fabric.Rect({});
实现类似网格的系统。我觉得应该有一种代码更少的更简单的方法?
有几种方法可以解决这个问题 - 也许这是一个可以接受的解决方案。
这真的取决于您希望网格有多灵活...
const canvas = new fabric.Canvas('c', {
selection: false
});
// size of squares
const size = 25;
// starting offsets
const offset = {
left: 49,
top: 50,
};
// where "1" represents a square and "0" a gap
const grid = [
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
// draws a square at the given grid coordinate
function drawSquare(x, y) {
canvas.add(new fabric.Rect({
left: x * size + offset.left,
top: y * size + offset.top,
width: size,
height: size,
fill: 'rgba(0,0,0,0)',
originX: 'left',
originY: 'top',
centeredRotation: true,
stroke: 'black',
strokeWidth: 1
}));
}
// loop over our grid rows and cells...
for (const [y, row] of grid.entries()) {
for (const [x, cell] of row.entries()) {
// draw a square if the cell value is 1 (true)
cell && drawSquare(x, y);
}
}
canvas {
border: 1px solid #ccc;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="550" height="250"></canvas>
如果您想要超级简洁并拥有一个“不易编辑”的网格,那么您可以将行存储为数字 - 然后仅使用它们的位作为标志...尽管它可能也不太可读。例如
const canvas = new fabric.Canvas('c', {
selection: false
});
const config = {
grid: [0x7C01F, 0x7E1FF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x3FFF],
size: 25,
offset: {
top: 49,
left: 50
}
};
function drawSquare(x, y) {
canvas.add(new fabric.Rect({
left: x * config.size + config.offset.left,
top: y * config.size + config.offset.top,
width: config.size,
height: config.size,
fill: 'rgba(0,0,0,0)',
originX: 'left',
originY: 'top',
centeredRotation: true,
stroke: 'black',
strokeWidth: 1
}));
}
function h2b(h) {
return h.toString(2).padStart(19, '0').split('').entries();
}
for (const [y, row] of config.grid.entries()) {
for (const [x, cell] of h2b(row)) {
+cell && drawSquare(x, y);
}
}
canvas {
border: 1px solid #ccc;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="550" height="250"></canvas>
..如果你想要超级简洁并且你根本不关心可读性或可维护性!
const g = new fabric.Canvas('c', {
selection: false
});
[0x7C01F, 0x7E1FF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x3FFF].forEach(
(r, i) => r.toString(2).padStart(19, 0).split('').forEach(
(c, j) => +c && g.add(new fabric.Rect({
left: j * 25 + 50,
top: i * 25 + 49,
width: 25,
height: 25,
fill: 'rgba(0,0,0,0)',
stroke: 'black'
}))));
canvas {
border: 1px solid #ccc;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="550" height="250"></canvas>
您可以创建一个包含这些位置的数组,然后循环遍历它
var canvas = new fabric.Canvas('c', {
selection: false
});
// Set grid options
const gridData = [
[49, 50],
[74, 50],
[99, 50],
[124, 50],
[149, 50],
[399, 50],
[424, 50],
[449, 50],
[474, 50],
[499, 50]
];
// create grid
gridData.forEach(gridItem => {
canvas.add(new fabric.Rect({
left: gridItem[0],
top: gridItem[1],
width: 25,
height: 25,
fill: 'rgba(0,0,0,0)',
originX: 'left',
originY: 'top',
centeredRotation: true,
stroke: 'black',
strokeWidth: 1
}));
});
jsfiddle 上的完整示例 http://jsfiddle.net/dpdesignz/op2z7yrk/12/
我正在使用 canvas 在图像上创建一个网格,这样我创建了我下面的 jsfiddle 中的内容。
http://jsfiddle.net/3bufekmh/1/
正如您从示例中看到的那样,我使用了大量的:
canvas.add(new fabric.Rect({});
实现类似网格的系统。我觉得应该有一种代码更少的更简单的方法?
有几种方法可以解决这个问题 - 也许这是一个可以接受的解决方案。 这真的取决于您希望网格有多灵活...
const canvas = new fabric.Canvas('c', {
selection: false
});
// size of squares
const size = 25;
// starting offsets
const offset = {
left: 49,
top: 50,
};
// where "1" represents a square and "0" a gap
const grid = [
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];
// draws a square at the given grid coordinate
function drawSquare(x, y) {
canvas.add(new fabric.Rect({
left: x * size + offset.left,
top: y * size + offset.top,
width: size,
height: size,
fill: 'rgba(0,0,0,0)',
originX: 'left',
originY: 'top',
centeredRotation: true,
stroke: 'black',
strokeWidth: 1
}));
}
// loop over our grid rows and cells...
for (const [y, row] of grid.entries()) {
for (const [x, cell] of row.entries()) {
// draw a square if the cell value is 1 (true)
cell && drawSquare(x, y);
}
}
canvas {
border: 1px solid #ccc;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="550" height="250"></canvas>
如果您想要超级简洁并拥有一个“不易编辑”的网格,那么您可以将行存储为数字 - 然后仅使用它们的位作为标志...尽管它可能也不太可读。例如
const canvas = new fabric.Canvas('c', {
selection: false
});
const config = {
grid: [0x7C01F, 0x7E1FF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x3FFF],
size: 25,
offset: {
top: 49,
left: 50
}
};
function drawSquare(x, y) {
canvas.add(new fabric.Rect({
left: x * config.size + config.offset.left,
top: y * config.size + config.offset.top,
width: config.size,
height: config.size,
fill: 'rgba(0,0,0,0)',
originX: 'left',
originY: 'top',
centeredRotation: true,
stroke: 'black',
strokeWidth: 1
}));
}
function h2b(h) {
return h.toString(2).padStart(19, '0').split('').entries();
}
for (const [y, row] of config.grid.entries()) {
for (const [x, cell] of h2b(row)) {
+cell && drawSquare(x, y);
}
}
canvas {
border: 1px solid #ccc;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="550" height="250"></canvas>
..如果你想要超级简洁并且你根本不关心可读性或可维护性!
const g = new fabric.Canvas('c', {
selection: false
});
[0x7C01F, 0x7E1FF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x3FFF].forEach(
(r, i) => r.toString(2).padStart(19, 0).split('').forEach(
(c, j) => +c && g.add(new fabric.Rect({
left: j * 25 + 50,
top: i * 25 + 49,
width: 25,
height: 25,
fill: 'rgba(0,0,0,0)',
stroke: 'black'
}))));
canvas {
border: 1px solid #ccc;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="550" height="250"></canvas>
您可以创建一个包含这些位置的数组,然后循环遍历它
var canvas = new fabric.Canvas('c', {
selection: false
});
// Set grid options
const gridData = [
[49, 50],
[74, 50],
[99, 50],
[124, 50],
[149, 50],
[399, 50],
[424, 50],
[449, 50],
[474, 50],
[499, 50]
];
// create grid
gridData.forEach(gridItem => {
canvas.add(new fabric.Rect({
left: gridItem[0],
top: gridItem[1],
width: 25,
height: 25,
fill: 'rgba(0,0,0,0)',
originX: 'left',
originY: 'top',
centeredRotation: true,
stroke: 'black',
strokeWidth: 1
}));
});
jsfiddle 上的完整示例 http://jsfiddle.net/dpdesignz/op2z7yrk/12/