Есть ли более эффективный способ создания сетки в Canvas? - PullRequest
0 голосов
/ 04 апреля 2020

Я создаю сетку поверх изображения, используя холст, и таким образом я создал то, что у меня есть в моем jsfiddle ниже.

http://jsfiddle.net/3bufekmh/1/

, как вы можете видеть из примера я использую огромное количество:

canvas.add(new fabric.Rect({});

для создания системы, подобной сетке. Я чувствую, что должно быть проще с меньшим количеством кода?

Ответы [ 2 ]

3 голосов
/ 04 апреля 2020

Есть несколько способов справиться с этим - возможно, это приемлемое решение. На самом деле это зависит от того, насколько гибкой вы хотите, чтобы сетка была ...

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 coordinate 
function drawSquare(x, y) {
  canvas.add(new fabric.Rect({
    left: x,
    top: y,
    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 [i, row] of grid.entries()) {
  for (const [j, cell] of row.entries()) {
    // draw a square if the cell value is 1 (true)
    cell && drawSquare(j * size + offset.left, i * size + offset.top);
  }
}
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,
    top: y,
    width: config.size,
    height: config.size,
    fill: 'rgba(0,0,0,0)',
    originX: 'left',
    originY: 'top',
    centeredRotation: true,
    stroke: 'black',
    strokeWidth: 1
  }));
}


for (const [i, row] of config.grid.entries()) {
  for (const [j, cell] of row.toString(2).padStart(19, '0').split('').entries()) {
    +cell && drawSquare(
      j * config.size + config.offset.left,
      i * config.size + config.offset.top);
  }
}
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 s = 25;

[0x7C01F, 0x7E1FF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x7FFFF, 0x3FFF].forEach(
  (r, i) => r.toString(2).padStart(19, 0).split('').forEach(
    (c, j) => +c && canvas.add(new fabric.Rect({
      left: j * s + 50,
      top: i * s + 49,
      width: s,
      height: s,
      fill: 'rgba(0,0,0,0)',
      centeredRotation: true,
      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>
0 голосов
/ 04 апреля 2020

Вы можете создать массив с позициями и просто l oop над ним

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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...