How to get bounding box coordinates for canvas con

2019-08-19 03:11发布

I have a canvas with a map. In that canvas the user is able to draw (in red) and the final result will be:

enter image description here

After the user as painted whatever he wants I need to calculate the bounding box coordinates of all the content so I could ultimately have:

enter image description here

Now I can loop through every pixel of the canvas and calculate the bounding box based on every non-empty pixel but this is quite a heavy operation. Any idea of a better logic to achieve the intended results?

1条回答
干净又极端
2楼-- · 2019-08-19 03:39

You can track what is being drawn and the diameter of the points. Then min/max that for the boundary.

One way to do this is to track position and radius (brush) or boundary (irregular shape) of what is being drawn, then merge that with current min/max bound to update the new bound if needed in effect "pushing" the bounds to always match the interior.

Example

var ctx = c.getContext("2d"),
    div = document.querySelector("div > div"),

    // keep track of min/max for each axis
    minX = Number.MAX_SAFE_INTEGER,
    minY = Number.MAX_SAFE_INTEGER,
    maxX = Number.MIN_SAFE_INTEGER,
    maxY = Number.MIN_SAFE_INTEGER,
    
    // brush/draw stuff for demo
    radius = 10,
    rect = c.getBoundingClientRect(),
    isDown = false;

ctx.fillText("Draw something here..", 10, 10);
ctx.fillStyle = "red";
c.onmousedown = function() {isDown = true};
window.onmouseup = function() {isDown = false};
window.onmousemove = function(e) {
  if (isDown) {
    var x = e.clientX - rect.left;
    var y = e.clientY - rect.top;
    
    // When something is drawn, calculate its impact (position and radius)
    var _minX = x - radius;
    var _minY = y - radius;
    var _maxX = x + radius;
    var _maxY = y + radius;
    
    // calc new min/max boundary
    if (_minX < minX) minX = _minX > 0 ? _minX : 0;
    if (_minY < minY) minY = _minY > 0 ? _minY : 0;
    if (_maxX > maxX) maxX = _maxX < c.width  ? _maxX : c.width;
    if (_maxY > maxY) maxY = _maxY < c.height ? _maxY : c.height;
    
    // show new bounds
    showBounds();
    
    // draw something
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, 6.28);
    ctx.fill();
  }
};

function showBounds() {
  // for demo, using bounds for display purposes (inclusive bound)
  div.style.cssText = 
    "left:" + minX + "px;top:" + minY + 
    "px;width:" + (maxX-minX-1) + "px;height:" + (maxY-minY-1) +
    "px;border:1px solid blue";
}
div {position:relative}
div > div {position:absolute;pointer-events:none}
<div>
  <canvas id=c width=600 height=600></canvas>
  <div></div>
</div>

查看更多
登录 后发表回答