HTML canvas:如何创建填充网格的多边形

时间:2018-08-25 10:13:36

标签: html5 canvas

我要构建HTML 5数据中心平面图,我想创建一个充满网格的多边形。该网格一定不能是图片模式,因为我希望能够缩放或旋转平面图而没有像素化。 我希望能够创建这种输出:

enter image description here

我该怎么做?

1 个答案:

答案 0 :(得分:1)

有多种方式,例如

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>