首页 > 解决方案 > 事件发生时获取 HTML5 画布图形 (Arc) 的尺寸

问题描述

我的问题是:我应该如何做逻辑和数学部分,以便计算每个弧的位置,当一个事件发出时:“点击”,“鼠标悬停”等。

需要考虑的要点:

. 行宽

. 它们是圆线。

. 弧长百分比。

. 哪个元素是第一个,ej:z-index 位置。

我的源代码

在此处输入图像描述

感谢您的时间。

标签: javascripttypescriptmathcanvashtml5-canvas

解决方案


有一种方便的isPointInStroke()方法,仅此而已。

要考虑 z-index,只需按您绘制的相反顺序检查:

const ctx = canvas.getContext('2d');
const centerX = canvas.width/2;
const centerY = canvas.height/2;
const rad = Math.min(centerX, centerY) * 0.75;
const pathes = [
  {
    a: Math.PI/4,
    color: 'white'
  },
  {
    a: Math.PI/1.5,
    color: 'cyan'
  },
  {
    a: Math.PI,
    color: 'violet'
  },
  {
    a: Math.PI*2,
    color: 'gray'
  }
];
pathes.forEach(obj => {
  const p = new Path2D();
  p.arc(centerX, centerY, rad, -Math.PI/2, obj.a-Math.PI/2);
  obj.path = p;
});

ctx.lineWidth = 12;
ctx.lineCap = 'round';

function draw() {
  ctx.clearRect(0,0,canvas.width,canvas.height);
  // since we sorted first => higher z-index
  for(let i = pathes.length-1; i>=0; i--) {
    let p = pathes[i];
    ctx.strokeStyle = p.hovered ? 'green' : p.color;
    ctx.stroke(p.path);
  };
}
function checkHovering(evt) {
  const rect = canvas.getBoundingClientRect();
  const x = evt.clientX - rect.left;
  const y = evt.clientY - rect.top;
  let found = false;
  pathes.forEach(obj => {
    if(found) {
      obj.hovered = false;
    }
    else {
      found = obj.hovered = ctx.isPointInStroke(obj.path, x, y);
    }
  });
  draw();
}

draw();
canvas.onmousemove = canvas.onclick = checkHovering;

 
canvas{background: lightgray}
<canvas id="canvas"></canvas>

如果你需要 IE 支持,这个 polyfill应该可以。


推荐阅读