使用isPointInStroke更改线条的颜色

时间:2019-07-05 11:55:04

标签: canvas html5-canvas

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

我不知道我哪里错了。有人可以解决此问题吗? 链接到有效的demo 这是我尝试过的,

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();
};

1 个答案:

答案 0 :(得分:1)

这是一个使用两个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小提琴: https://jsfiddle.net/OCBiermann/orc7qdys/