如何获取画布内容的边界框坐标?

时间:2017-10-02 14:57:24

标签: html5 html5-canvas

我有一张带有地图的画布。在该画布中,用户可以绘制(红色),最终结果将是:

enter image description here

在用户绘制任何他想要的东西后,我需要计算所有内容的边界框坐标,这样我才能最终拥有:

enter image description here

现在我可以遍历画布的每个像素并根据每个非空像素计算边界框,但这是一个非常繁重的操作。是否有更好的逻辑来实现预期的结果?

1 个答案:

答案 0 :(得分:1)

您可以跟踪绘制的内容和点的直径。然后是边界的最小/最大值。

执行此操作的一种方法是跟踪正在绘制的内容的位置和半径(画笔)或边界(不规则形状),然后将其与当前最小/最大绑定合并以更新新绑定(如果需要,实际上“推”)总是匹配内部的界限。

示例

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>