在鼠标悬停时使用jQuery在HTML5画布上更改自定义形状的颜色?

时间:2022-06-28 20:32:00

I have this code for a map I am trying to make using HTML5 Canvas and jQuery. I have some of the shapes already made and the color filled in. What I don't know how to do is to make the color of the custom shapes change when the mouse is hovering over them. Any solutions?

我有一个地图的代码,我试图使用HTML5 Canvas和jQuery。我已经制作了一些形状并填充了颜色。我不知道该怎么做是当鼠标悬停在自定义形状上时使其颜色发生变化。有解决方案吗

<canvas id="canvas" width="700" height="485">
</canvas>

<script>
$(document).ready(function() {

     var tech = canvas.getContext( '2d' );
     tech.beginPath();
     tech.moveTo(250, 280);
     tech.lineTo(240, 280);
     tech.lineTo(240, 315);
     tech.lineTo(277, 315);
     tech.lineTo(277, 287);
     tech.lineTo(250, 287);
     tech.closePath();
     tech.stroke();
     tech.fillStyle = "rgba(0, 0, 255, 0.3)";
     tech.fill();

     union = canvas.getContext( '2d' );
     union.beginPath();
     union.moveTo(400, 195);
     union.lineTo(386, 195);
     union.lineTo(386, 198);
     union.lineTo(364, 198);
     union.lineTo(364, 215);
     union.lineTo(386, 215);
     union.lineTo(386, 207);
     union.lineTo(400, 207);
     union.closePath();
     union.stroke();
     union.fillStyle = "rgba(0, 0, 255, 0.3)";
     union.fill();

     cntr = canvas.getContext( '2d' );
     cntr.beginPath();
     cntr.moveTo(340, 196);
     cntr.lineTo(320, 196);
     cntr.lineTo(320, 222);
     cntr.lineTo(340, 222);
     cntr.closePath();
     cntr.stroke();
     cntr.fillStyle = "rgba(0, 0, 255, 0.3)";
     cntr.fill();

     picho = canvas.getContext( '2d' );
     picho.beginPath();
     picho.moveTo(300, 240);
     picho.lineTo(285, 240);
     picho.lineTo(285, 250);
     picho.lineTo(300, 250);
     picho.closePath();
     picho.stroke();
     picho.fillStyle = "rgba(0, 0, 255, 0.3)";
     picho.fill();
});
    </script>

1 个解决方案

#1


You can use math to hit-test circular and rectangular shapes, but to test irregular shapes (such as yours) it's better to use context.isPointInPath.

您可以使用数学来测试圆形和矩形形状,但是为了测试不规则形状(例如您的形状),最好使用context.isPointInPath。

isPointInPath works by testing if a specified [x,y] is inside the most recently defined path. That's means to test your irregular shape(s) you must first redefine each path and then test that redefined path with isPointInPath

isPointInPath的工作原理是测试指定的[x,y]是否在最近定义的路径中。这意味着测试你的不规则形状你必须首先重新定义每个路径,然后使用isPointInPath测试重新定义的路径

"Redefine" means re-executing a particular path's code from beginPath to closePath. But there's no need to stroke or fill that defined path.

“重新定义”表示从beginPath到closePath重新执行特定路径的代码。但是没有必要划线或填充定义的路径。

Here's example code and a demo:

这是示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }

var isDown=false;
var startX,startY;

var paths=[];
paths.push([
  {x:400,y:95},
  {x:386,y:95},
  {x:386,y:98},
  {x:364,y:98},
  {x:364,y:115},
  {x:386,y:115},
  {x:386,y:107},
  {x:400,y:107}
]);

ctx.fillStyle='skyblue';

draw();

$("#canvas").mousemove(function(e){handleMouseMove(e);});

function draw(highlight){
  ctx.clearRect(0,0,cw,ch);
  for(var i=0;i<paths.length;i++){
    var path=paths[i];
    define(path);
    ctx.stroke();
    if(i==highlight){
      ctx.fill();
    }
  }
}

function define(p){
  ctx.beginPath();
  ctx.moveTo(p[0].x,p[0].y);
  for(var i=0; i<p.length;i++){
    ctx.lineTo(p[i].x,p[i].y);
  }
  ctx.closePath();
}

function handleMouseMove(e){

  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  var highlight=-1;
  for(var i=0;i<paths.length;i++){
    var path=paths[i];
    define(path);
    if(ctx.isPointInPath(mouseX,mouseY)){
      highlight=i;
    }
  }
  draw(highlight);

}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move the mouse over the shape to highlight the shape</h4>
<canvas id="canvas" width=450 height=450></canvas>

#1


You can use math to hit-test circular and rectangular shapes, but to test irregular shapes (such as yours) it's better to use context.isPointInPath.

您可以使用数学来测试圆形和矩形形状,但是为了测试不规则形状(例如您的形状),最好使用context.isPointInPath。

isPointInPath works by testing if a specified [x,y] is inside the most recently defined path. That's means to test your irregular shape(s) you must first redefine each path and then test that redefined path with isPointInPath

isPointInPath的工作原理是测试指定的[x,y]是否在最近定义的路径中。这意味着测试你的不规则形状你必须首先重新定义每个路径,然后使用isPointInPath测试重新定义的路径

"Redefine" means re-executing a particular path's code from beginPath to closePath. But there's no need to stroke or fill that defined path.

“重新定义”表示从beginPath到closePath重新执行特定路径的代码。但是没有必要划线或填充定义的路径。

Here's example code and a demo:

这是示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }

var isDown=false;
var startX,startY;

var paths=[];
paths.push([
  {x:400,y:95},
  {x:386,y:95},
  {x:386,y:98},
  {x:364,y:98},
  {x:364,y:115},
  {x:386,y:115},
  {x:386,y:107},
  {x:400,y:107}
]);

ctx.fillStyle='skyblue';

draw();

$("#canvas").mousemove(function(e){handleMouseMove(e);});

function draw(highlight){
  ctx.clearRect(0,0,cw,ch);
  for(var i=0;i<paths.length;i++){
    var path=paths[i];
    define(path);
    ctx.stroke();
    if(i==highlight){
      ctx.fill();
    }
  }
}

function define(p){
  ctx.beginPath();
  ctx.moveTo(p[0].x,p[0].y);
  for(var i=0; i<p.length;i++){
    ctx.lineTo(p[i].x,p[i].y);
  }
  ctx.closePath();
}

function handleMouseMove(e){

  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  var highlight=-1;
  for(var i=0;i<paths.length;i++){
    var path=paths[i];
    define(path);
    if(ctx.isPointInPath(mouseX,mouseY)){
      highlight=i;
    }
  }
  draw(highlight);

}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move the mouse over the shape to highlight the shape</h4>
<canvas id="canvas" width=450 height=450></canvas>