简体   繁体   中英

Render grid on HTML5 Canvas

I am trying to render a grid on a HTML5 canvas, but I want anything that the user draws on the canvas to be placed behind the grid. I tried to recreate this by having 2 canvas: one with the grid, and the other the one that the user draws on. The one with the grid is placing on top of the canvas the user draws on, and the canvas should be transparent but it's not showing anything the user draws. If I place the canvas the user draws on at the top, then you can see what the user draws, but the drawing is in front of the grid, and i want the drawing behind the grid.

You can view what I have tried here: http://codepen.io/vishiswoz/pen/grqMyG

 function buildGrids(gridPixelSize, color, gap, div) { var canvas = $('#' + div + '').get(0); var ctx = canvas.getContext("2d"); //ctx.fillStyle="rgba(255, 255, 255, 0)"; //ctx.fillRect(0, 0, 500, 300); ctx.lineWidth = 0.5; ctx.strokeStyle = color; // horizontal grid lines for (var i = 0; i <= canvas.height; i = i + gridPixelSize) { ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(canvas.width, i); if (i % parseInt(gap) == 0) { ctx.lineWidth = 0.5; } else { ctx.lineWidth = 0.5; } ctx.closePath(); ctx.stroke(); } // vertical grid lines for (var j = 0; j <= canvas.width; j = j + gridPixelSize) { ctx.beginPath(); ctx.moveTo(j, 0); ctx.lineTo(j, canvas.height); if (j % parseInt(gap) == 0) { ctx.lineWidth = 0.5; } else { ctx.lineWidth = 0.5; } ctx.closePath(); ctx.stroke(); } for(var ii = 0; ii <=canvas.width; ii+=2) { for(var jj=0; jj <=canvas.height; jj+=2) { ctx.clearRect(ii,jj,1,1); } } } buildGrids(5, "grey", 2, "test"); var el = document.getElementById('c'); var ctx = el.getContext('2d'); ctx.strokeStyle = "black"; var isDrawing; el.onmousedown = function(e) { isDrawing = true; ctx.lineWidth = 10; ctx.lineJoin = ctx.lineCap = 'round'; ctx.moveTo(e.clientX, e.clientY); }; el.onmousemove = function(e) { if (isDrawing) { ctx.lineTo(e.clientX, e.clientY); ctx.stroke(); } }; el.onmouseup = function() { isDrawing = false; }; 
 canvas { position: absolute; top: 0; left: 0; } #c { } 
 <canvas id="c" width="500" height="300"></canvas> <canvas id="test" width="500" height="300"></canvas> 

Thanks in advance.

Drawing on a bottom canvas covered by a top grid canvas

在此处输入图片说明

Just listen for mouse events on the top grid-canvas but draw on the drawing canvas.

var gridCanvas=document.getElementById('test');

gridCanvas.onmousedown = function(e) {
  isDrawing = true;
  ctx.lineWidth = 10;
  ctx.lineJoin = ctx.lineCap = 'round';
  ctx.moveTo(e.clientX, e.clientY);
};

A couple of other issues

  • A matter of style: On mousemove, draw a complete line segment rather than just continuing an "open" path. You can do this by remembering the lastX,lastY and drawing a segment between that last point and the current mouse position.
  • If the mouse goes out of the canvas you should end the drawing operation. Otherwise you will end up with a "sticky" drawing where the user can't easily stop the drawing.

Here's your code slightly refactored to include the above ideas:

 var gridCanvas = document.getElementById('grid'); var el = document.getElementById('drawing'); function reOffset(){ var BB=el.getBoundingClientRect(); offsetX=BB.left; offsetY=BB.top; } var offsetX,offsetY; reOffset(); window.onscroll=function(e){ reOffset(); } window.onresize=function(e){ reOffset(); } buildGrids(5, "grey", 2, "test"); var ctx = el.getContext('2d'); ctx.strokeStyle = "orange"; var isDrawing,lastX,lastY; gridCanvas.onmousedown = function(e) { lastX=e.clientX; lastY=e.clientY; ctx.lineWidth = 10; ctx.lineJoin = ctx.lineCap = 'round'; isDrawing = true; }; gridCanvas.onmousemove = function(e) { if (isDrawing) { ctx.beginPath(); ctx.moveTo(lastX,lastY); ctx.lineTo(e.clientX, e.clientY); ctx.stroke(); lastX=e.clientX; lastY=e.clientY; } }; gridCanvas.onmouseup = function() { isDrawing = false; };gridCanvas.onmouseout = function() { isDrawing = false; }; function buildGrids(gridPixelSize, color, gap, div) { var ctx = gridCanvas.getContext("2d"); //ctx.fillStyle="rgba(255, 255, 255, 0)"; //ctx.fillRect(0, 0, 500, 300); ctx.lineWidth = 0.5; ctx.strokeStyle = color; // horizontal grid lines for (var i = 0; i <= gridCanvas.height; i = i + gridPixelSize) { ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(gridCanvas.width, i); if (i % parseInt(gap) == 0) { ctx.lineWidth = 0.5; } else { ctx.lineWidth = 0.5; } ctx.closePath(); ctx.stroke(); } // vertical grid lines for (var j = 0; j <= gridCanvas.width; j = j + gridPixelSize) { ctx.beginPath(); ctx.moveTo(j, 0); ctx.lineTo(j, gridCanvas.height); if (j % parseInt(gap) == 0) { ctx.lineWidth = 0.5; } else { ctx.lineWidth = 0.5; } ctx.closePath(); ctx.stroke(); } for(var ii = 0; ii <=gridCanvas.width; ii+=2) { for(var jj=0; jj <=gridCanvas.height; jj+=2) { ctx.clearRect(ii,jj,1,1); } } } 
 body{ background-color: ivory; } canvas{border:1px solid red;} canvas{ position: absolute; top: 0; left: 0;} 
 <canvas id="drawing" width="500" height="300"></canvas> <canvas id="grid" width="500" height="300"></canvas> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM