【问题标题】:How do I draw a box around multiple shapes in html5 canvas如何在 html5 画布中围绕多个形状绘制一个框
【发布时间】:2018-10-14 11:46:06
【问题描述】:

我试图在画布中围绕多个形状绘制一个框,以说明这些形状像一个组一样相关。 尝试如下:

var ctx = c.getContext("2d"),
radius = 10,
rect = c.getBoundingClientRect(),

ctx.fillText("Draw something here..", 10, 10);
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(250, 300, radius, 0, 6.28);
ctx.fill();
ctx.fillStyle = "yellow";
ctx.beginPath();
ctx.arc(200, 100, radius, 0, 10.28);
ctx.fill();
ctx.fillStyle = "brown";
ctx.beginPath();
ctx.arc(350, 210, radius, 0, 10.28);
ctx.fill();

var x = (250+200+350)/3;
var y = (300+100+210)/3;

var radius = Math.sqrt((x1*x1)+(y1*y1));
var _minX = x - radius;
var _minY = y - radius;
var _maxX = x + radius;
var _maxY = y + radius;

ctx.rect(_minX,_minY,(_maxX-_minX+2),(_maxY-_minY+2));
ctx.stroke();

但它没有正确绘制。 How to get bounding box coordinates for canvas content? 此链接仅说明路径,不适用于现有形状。 下面是我想要绘制的图像:

【问题讨论】:

  • 究竟是什么问题似乎有效?
  • 不 - 那个图像是我想要的,而不是我得到的结果
  • 您的代码没有反映您想要绘制的形状,因此很难为您的情况提供合适的解决方案。但基本上,您必须将所有形状的 BBox 存储在一个数组中,然后简单地获取所有这些 BBox 的 min_x、max_x、min_y、max_y。这将是您的 group-rect 的四个角。
  • 如何获得每个形状的 BBox?对于所有这些形状,我只有 x,y
  • 您能帮我解决问题或提供任何参考吗?

标签: javascript html5-canvas


【解决方案1】:

【讨论】:

  • 我可以查看那个库 :) 但在这里我需要在不使用任何库的情况下解决这个问题。
【解决方案2】:

此代码尚未准备好用于生产,也不是最佳解决方案,但它适用于“大多数情况”。

我正在使用 imageData 来检查非白色像素。 (如果不是 0 - RGBA 像素 ==> 对象),它会缩小可能的 Rectangle 范围。如果您不希望文本出现在 Rectangle 中,您还需要对其进行调整。

可以/应该优化此代码。

编辑: 现在我只检查是否设置了 Alpha 值。以及一些随机对象的创建来测试多个结果

信息:对象被剪裁/剪切,因为它们超出了画布大小。

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var colors = ["red", "blue", "green", "black"];

ctx.fillText("Draw something here..", 0, 10);

/** CREATEING SOME RANDOM OBJECTS (JUST FOR TEST) **/
createRandomObjects();

function createRandomIntMax(max){
	return parseInt(Math.random() * 1000 * max) % max + 1;
}

function  createRandomObjects(){
	var objectsToDraw = createRandomIntMax(20);
	for(var idx = 0; idx < objectsToDraw; idx++){
		ctx.fillStyle = colors[createRandomIntMax(colors.length)];
		ctx.beginPath();
		ctx.arc(createRandomIntMax(c.width), createRandomIntMax(c.height), createRandomIntMax(30), 0, 2 * Math.PI);
		ctx.fill();
	}
}


/** GETTING IMAGE DATA **/
var myImageData = ctx.getImageData(0, 0, c.width, c.height);

/** FINDING BORDERS **/
findBorders(myImageData.data);

function findBorders(imageData) {

    var result = {
        left: c.width,
        top: c.height,
        right: -1,
        bottom: -1
    }

    var idx = 0;
    var lineLow = -1;
    var lineHigh = -1;
    var currentLine = 0;
    var currentPoint, helper;
    while (idx < imageData.length) {
        currentPoint = imageData[idx + 3]; 

        /** CHECKING FOR OBJECT **/
        if (currentPoint != 0) {

            helper = parseInt(idx % (c.width * 4)) / 4;
            if (lineLow < 0) {
                lineLow = helper;
                lineHigh = helper;
            } else {
                lineHigh = helper;
            }
        }

        if (idx !== 0 && (idx % (c.width * 4)) === 0) {
            currentLine = idx / (c.width * 4);
            // Updating the Border Points
            if (lineLow > -1) {
                result.left = Math.min(lineLow, result.left);
                result.top = Math.min(currentLine, result.top);
                result.right = Math.max(lineHigh, result.right);
                result.bottom = Math.max(currentLine, result.bottom);
            }

            lineLow = -1;
            lineHigh = -1;
        }

        idx += 4;
    }

    ctx.rect(result.left, result.top, result.right - result.left, result.bottom - result.top);
    ctx.stroke()

}
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【讨论】:

  • 不迭代 ImageData 将是优化此代码的第一个也是最有效的方法。
  • 没错,没错,...但这是我能想到的最快解决方案。 (没有速度快) ;-)
  • 是的,OP 将不得不重建他们绘制形状的方式,我们没有足够的时间去咀嚼以便给他们一个令人满意的解决方案。
  • 感谢您的解决方案。但我不能使用这个解决方案,因为我只想为屏幕中的选定对象而不是所有对象绘制外框
  • 对象的类型是什么?圆圈,矩形,......?如何绘制/创建形状?
【解决方案3】:

使用 getBoundingClientRect() 获取确切的边界

【讨论】:

  • getBoundingClientRect() 哪个元素?尝试用于画布。不确定所选形状的逻辑:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
相关资源
最近更新 更多