HTML canvas: как создать многоугольник, заполненный сеткой - PullRequest
0 голосов
/ 25 августа 2018

Я приказываю построить план этажа центра данных HTML 5, я хотел бы создать многоугольник, заполненный сеткой. Эта сетка не должна быть рисунком, так как я хотел бы иметь возможность масштабировать или поворачивать план этажа без пикселизации. Я хотел бы иметь возможность создать такой вывод:

enter image description here

Как я могу это сделать?

1 Ответ

0 голосов
/ 25 августа 2018

Есть несколько способов, например

var ctx = c.getContext('2d');
drawShape();
ctx.stroke();
ctx.save(); // so we can remove the clipping
ctx.clip();
drawGrid();
ctx.restore(); // remove the clipping

function drawShape() {
  ctx.beginPath();
  var pts = [
    20, 20,
    80, 20,
    90, 50,
    120, 90,
    30, 80,
    20,20
  ];
  for(var i=0;i<pts.length;i+=2){
    ctx.lineTo(pts[i], pts[i+1]);
  }
}
function drawGrid() {
  ctx.beginPath();
  for(var x=-.5; x<c.width; x+=20) {
    ctx.moveTo(x, 0);
    ctx.lineTo(x, c.height);
  }
  for(var y=-.5; y<c.height; y+=20) {
    ctx.moveTo(0, y);
    ctx.lineTo(c.width, y);
  }
  ctx.stroke();
}
    
<canvas id="c"></canvas>

var ctx = c.getContext('2d');
drawGrid();
ctx.globalCompositeOperation = 'destination-in';
drawShape();
ctx.fill();
ctx.globalCompositeOperation = 'source-over';
ctx.stroke();

function drawShape() {
  ctx.beginPath();
  var pts = [
    20, 20,
    80, 20,
    90, 50,
    120, 90,
    30, 80,
    20,20
  ];
  for(var i=0;i<pts.length;i+=2){
    ctx.lineTo(pts[i], pts[i+1]);
  }
}
function drawGrid() {
  ctx.beginPath();
  for(var x=-.5; x<c.width; x+=20) {
    ctx.moveTo(x, 0);
    ctx.lineTo(x, c.height);
  }
  for(var y=-.5; y<c.height; y+=20) {
    ctx.moveTo(0, y);
    ctx.lineTo(c.width, y);
  }
  ctx.stroke();
}
    
<canvas id="c"></canvas>

Но в вашем случае, обычная сетка, может быть лучше использовать шаблон.

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

var ctx = c.getContext('2d');
var pat_ctx = document.createElement('canvas').getContext('2d');
var cell_size = 20;

// just a basic drawing example
// first we generate the grid as a pattern
ctx.fillStyle = generatePattern(cell_size, cell_size);
drawShape();
ctx.stroke();
// we move the pattern by half a cell because we actually drawn only a cross
ctx.translate(-cell_size / 2, -cell_size / 2);
ctx.fill();


// make the grid follow the mouse
// without having to redraw ourself the grid
onmousemove = function(e) {
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, c.width, c.height);
  drawShape();
  ctx.stroke();
  // move the grid
  ctx.translate(e.clientX - cell_size / 2, e.clientY - -cell_size / 2);
  ctx.fill();
}
// click to zoom (+shift to zoom out)
onclick = function(e) {
  if (e.shiftKey) cell_size--;
  else cell_size++;
  ctx.fillStyle = generatePattern(cell_size, cell_size);
  onmousemove(e);
}
// dimply draws a cross
function generatePattern(w, h) {
  var canvas = pat_ctx.canvas;
  canvas.width = w;
  canvas.height = h;
  pat_ctx.moveTo(w / 2, 0);
  pat_ctx.lineTo(w / 2, h);
  pat_ctx.moveTo(0, h / 2);
  pat_ctx.lineTo(w, h / 2);
  pat_ctx.stroke();
  return pat_ctx.createPattern(canvas, 'repeat');
}

function drawShape() {
  ctx.beginPath();
  var pts = [
    20, 20,
    80, 20,
    90, 50,
    120, 90,
    30, 80,
    20, 20
  ];
  for (var i = 0; i < pts.length; i += 2) {
    ctx.lineTo(pts[i], pts[i + 1]);
  }
}
<canvas id="c"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...