Canvas 使用isPointInStroke更改线条的颜色

Canvas 使用isPointInStroke更改线条的颜色,canvas,html5-canvas,Canvas,Html5 Canvas,我用画布画了两条线,我有一个鼠标按下事件,在画布上听, 单击该行时,该行的颜色应更改。我已经实施了这种方法 使用画布的isPointInStroke方法,但问题是所有绘制的线都高亮显示 我不知道我错在哪里。有人能解决这个问题吗? 链接到工作 这是我尝试过的 const c = document.getElementById('c'); var ctx = c.getContext("2d"); var onLine = false;

我用画布画了两条线,我有一个鼠标按下事件,在画布上听, 单击该行时,该行的颜色应更改。我已经实施了这种方法 使用画布的isPointInStroke方法,但问题是所有绘制的线都高亮显示

我不知道我错在哪里。有人能解决这个问题吗? 链接到工作 这是我尝试过的

const c = document.getElementById('c');
var ctx = c.getContext("2d");
var onLine = false;                                // state (for demo)
ctx.moveTo(10, 10);                               // store a line on path
ctx.lineTo(220, 0);
ctx.moveTo(50, 20);                               // store a line on path
ctx.lineTo(200, 100);
ctx.lineWidth = 16;   
// line width
render();                                          // initial render

function render() {
  ctx.clearRect(0,0,300,150);
  ctx.strokeStyle = onLine ? "red" : "green";      // color based on state
  ctx.stroke();                                // stroke path
}

c.onmousedown = function(e) {
  const rect = c.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  onLine = ctx.isPointInStroke(x, y);
  render();
};

下面是一个解决方案,它使用两个Path2D对象来表示正在绘制的线。这使得使用
ctx.isPointInStroke(path,x,y)
而不是
ctx.isPointInStroke(x,y)
更容易检测给定行内的点击

请注意,此解决方案并不假定单击是互斥的。因此,如果线条确实重叠(在本例中不重叠),则如果单击重叠区域,两条线条的颜色都会发生变化

另外,请注意,只有在单击线条时才会切换颜色。如果未单击,线条的颜色将保持不变

const c = document.getElementById('c');
const START_COLOR = "green";
var ctx = c.getContext("2d");

/*Path2D objects representing the two lines */
var pathA = new Path2D();
var pathB = new Path2D();

/*Build the paths */
pathA.moveTo(10, 10);                               // store a line on path A
pathA.lineTo(220, 0);

pathB.moveTo(50, 20);                               // store a line on path B
pathB.lineTo(200, 100);

ctx.strokeStyle = START_COLOR;  

/*Booleans tracking the click state of each line */
var clickedA = false;
var clickedB = false;

/*Both lines initially set to the start color */
var colorA = START_COLOR;
var colorB = START_COLOR;

ctx.lineWidth = 16;                                 // line width


render();                                          // initial render





function render() {

  ctx.clearRect(0,0, 150, 300);

  /*Check if A was clicked, and toggle its color by setting context strokeStyle*/
  if (clickedA === true)
  {
        colorA = (colorA == "red" ? "green" : "red");  
  }

  /*Set correct color for A and draw it to canvas */
  ctx.strokeStyle = colorA;         
  ctx.stroke(pathA);


  /*Check if B was clicked, and toggle its color */
  if (clickedB === true)
  {
    colorB = (colorB == "red" ? "green" : "red");  
  }     

  /*Set correct color for B and draw it to canvas */      
  ctx.strokeStyle = colorB;   
  ctx.stroke(pathB);

  /*Reset values of clickedA and clickedB to false */
  clickedA = false;
  clickedB = false;
}

c.onmousedown = function(e) {
  const rect = c.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  /*Here we use the other version of isPointInStroke which has path2D 
    as first param to detect click within either stroke */
  clickedA = ctx.isPointInStroke(pathA, x, y);           

  /*Check for click within path B for a click in pathB */
  clickedB = ctx.isPointInStroke(pathB, x, y);


  render();
}
参见JS fiddle:

您需要分别定义每个路径。Path2D构造函数在这里可能会有很大帮助。是的,当然。我会贴一张照片。好的,我更新了。新的链接是,并且还发布了一个js fiddle的链接。