如何在 HTML5 Canvas 中获取绘制弧的宽度和高度?
Posted
技术标签:
【中文标题】如何在 HTML5 Canvas 中获取绘制弧的宽度和高度?【英文标题】:How to get width & height of drawn arc(s) in HTML5 Canvas? 【发布时间】:2015-08-05 07:28:02 【问题描述】:Here我已经使用Konvajs库绘制了一些弧,但是在绘制对象后我无法获得它们的宽度和高度,我该怎么做? 快速阅读代码:
function drawSurface(idnumber, radius, x, y, startAngleParam, endAngleParam)
var borderbold = 5;
var surface;
if (typeof startAngleParam !== 'undefined')
surface = new Konva.Shape(
x: x,
y: y,
fill: '#ccc',
stroke: "#ccc",
strokeWidth: 8,
id: idnumber,
opacity: 1,
drawFunc: function (context)
var startAngle = startAngleParam * Math.PI;
var endAngle = (startAngleParam + 0.5 + endAngleParam) * Math.PI;
var counterClockwise = false;
context.beginPath();
context.arc(0, 0, radius, startAngle, endAngle, counterClockwise);
context.setAttr("lineWidth", borderbold);
context.stroke();
context.fillStrokeShape(this);
);
else
surface = new Konva.Circle(
x: x,
y: y,
radius: radius,
fill: '#ccc',
strokeWidth: 3,
id: idnumber,
opacity: 1
);
return surface;
请用代码示例支持您的回答。
【问题讨论】:
【参考方案1】:这是从this answer 中采用并移植到 javascript 的另一种方法:
const PI = Math.PI;
const HALF_PI = Math.PI / 2;
const TWO_PI = Math.PI * 2;
const DEG_TO_RAD = Math.PI / 180;
const RAD_TO_DEG = 180 / Math.PI;
const getQuadrant = (_angle) =>
const angle = _angle % (TWO_PI);
if (angle > 0.0 && angle < HALF_PI) return 0;
if (angle >= HALF_PI && angle < PI) return 1;
if (angle >= PI && angle < PI + HALF_PI) return 2;
return 3;
;
// https://***.com/a/35977476/461048
const getArcBoundingBox = (ini, end, radius, margin = 0) =>
const iniQuad = getQuadrant(ini);
const endQuad = getQuadrant(end);
const ix = Math.cos(ini) * radius;
const iy = Math.sin(ini) * radius;
const ex = Math.cos(end) * radius;
const ey = Math.sin(end) * radius;
const minX = Math.min(ix, ex);
const minY = Math.min(iy, ey);
const maxX = Math.max(ix, ex);
const maxY = Math.max(iy, ey);
const r = radius;
const xMax = [[maxX, r, r, r], [maxX, maxX, r, r], [maxX, maxX, maxX, r], [maxX, maxX, maxX, maxX]];
const yMax = [[maxY, maxY, maxY, maxY], [r, maxY, r, r], [r, maxY, maxY, r], [r, maxY, maxY, maxY]];
const xMin = [[minX, -r, minX, minX], [minX, minX, minX, minX], [-r, -r, minX, -r], [-r, -r, minX, minX]];
const yMin = [[minY, -r, -r, minY], [minY, minY, -r, minY], [minY, minY, minY, minY], [-r, -r, -r, minY]];
const x1 = xMin[endQuad][iniQuad];
const y1 = yMin[endQuad][iniQuad];
const x2 = xMax[endQuad][iniQuad];
const y2 = yMax[endQuad][iniQuad];
const x = x1 - margin;
const y = y1 - margin;
const w = x2 - x1 + margin * 2;
const h = y2 - y1 + margin * 2;
return x, y, w, h ;
;
jsfiddle:https://jsfiddle.net/brunoimbrizi/y3to5s6n/45/
【讨论】:
【参考方案2】:找到弧的边界框,然后根据边界框计算宽度和高度。
在几何上,仅有 5 个可能的边界框角是:
圆弧中心点, 圆弧上的点(如果有)在 0 度(0 弧度), 圆弧上的点(如果有)90 度(PI/2 弧度), 圆弧上的点(如果有)在 180 度(PI 弧度), 圆弧上的点(如果有)270 度(PI*3/2 弧度),从这些可能的边界框点中,找到最小 X、最小 Y、最大 X 和最大 Y。[minX,minY] 将是边界框的左上角。 [maxX,maxY] 将是边界框的右下角。
您的弧宽将为 maxX-minX,高度为 maxY-minY。
这是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var PI=Math.PI;
var cx=150;
var cy=150;
var radius=75;
var startAngle=-PI/4;
var endAngle=PI/3;
ctx.beginPath();
ctx.moveTo(cx,cy);
ctx.arc(cx,cy,radius,startAngle,endAngle);
ctx.closePath();
ctx.fillStyle='skyblue';
ctx.fill();
ctx.strokeStyle='lightgray';
ctx.lineWidth=3;
ctx.stroke();
var bb=arcBounds(cx,cy,radius,startAngle,endAngle);
ctx.strokeStyle='red';
ctx.lineWidth=1;
ctx.strokeRect(bb.x,bb.y,bb.width,bb.height);
function arcBounds(cx,cy,radius,startAngle,endAngle)
var minX=1000000;
var minY=1000000;
var maxX=-1000000;
var maxY=-1000000;
var possibleBoundingPoints=[]
// centerpoint
possibleBoundingPoints.push(x:cx,y:cy);
// starting angle
possibleBoundingPoints.push(arcpoint(cx,cy,radius,startAngle));
// ending angle
possibleBoundingPoints.push(arcpoint(cx,cy,radius,endAngle));
// 0 radians
if(0>=startAngle && 0<=endAngle)
possibleBoundingPoints.push(arcpoint(cx,cy,radius,0));
// PI/2 radians
var angle=PI/2;
if(angle>=startAngle && angle<=endAngle)
possibleBoundingPoints.push(arcpoint(cx,cy,radius,angle));
// PI radians
var angle=PI;
if(angle>=startAngle && angle<=endAngle)
possibleBoundingPoints.push(arcpoint(cx,cy,radius,angle));
// PI*3/2 radians
var angle=PI*3/2;
if(angle>=startAngle && angle<=endAngle)
possibleBoundingPoints.push(arcpoint(cx,cy,radius,angle));
for(var i=0;i<possibleBoundingPoints.length;i++)
var pt=possibleBoundingPoints[i];
if(pt.x<minX)minX=pt.x;
if(pt.y<minY)minY=pt.y;
if(pt.x>maxX)maxX=pt.x;
if(pt.y>maxY)maxY=pt.y;
return( x:minX, y:minY, width:maxX-minX, height:maxY-minY );
function arcpoint(cx,cy,radius,angle)
var x=cx+radius*Math.cos(angle);
var y=cy+radius*Math.sin(angle);
return(x:x,y:y);
body background-color: ivory;
#canvasborder:1px solid blue;
<canvas id="canvas" width=300 height=300></canvas>
【讨论】:
您的解释非常详细而且很棒,我真的很感谢您的努力,我尝试将您的代码应用到我的弧上并调整所有参数,但边界框显示在不同的虽然位置不同的宽度和高度!! @MahdiAlkhatib 某些角度无法正常工作:jsfiddle.net/ybpqmve0以上是关于如何在 HTML5 Canvas 中获取绘制弧的宽度和高度?的主要内容,如果未能解决你的问题,请参考以下文章