当前位置: 首页 > 知识库问答 >
问题:

如何在绘制的画布组件中添加鼠标事件

辛盛
2023-03-14

我想在画布上绘制200个或更多(高度流动)对象
并将鼠标添加到每个事件上,鼠标单击事件

像这样的源代码...
(valiable k是增加的)



对于(k=0;k

    Shape(ctx, x1,y1,x2,y2,x3,y3,x4,y4,k);


}

    function Shape(ctx, x1,y1,x2,y2,x3,y3,x4,y4, k){
        ctx.strokeStyle = "black";
        ctx.fillStyle = "red";    
        ctx.globalAlpha = 1.0; 
        ctx.moveTo(x1,y1);
        ctx.lineTo(x2,y2); 
        ctx.lineTo(x3,y3); 
        ctx.lineTo(x4,y4); 
        ctx.lineTo(x1,y1);
        ctx.lineWidth = 0.5;
        ctx.fill();
        ctx.stroke();
        ctx.fillText(k,(x2+x3)/2,(y2+y3)/2);    
    }

    ....
     ....

我的希望是...
如果鼠标放在形状上,显示有效k
如果鼠标点击形状,转到其他带有有效k参数的url

但是,我不想使用图像。


请帮帮我。


谢谢。

共有3个答案

梁丘权
2023-03-14

由于您的形状不规则,因此很难从数学上进行命中测试。

幸运的是,上下文具有isPointInPath方法,该方法将测试提供的mouseX/mouseY是否在最后定义的路径内。

要对不规则形状进行命中测试,请执行以下操作:

  • 保留足够的信息以重新定义对象中的每条路径
  • 将每个形状对象添加到阵列
  • 在mousemove事件处理程序中
  • 遍历数组
  • 重新定义每个形状(一次1个)。注:重新定义是指没有笔划/填充的图纸
  • 使用上下文。isPointInPath(mouseX,mouseY)点击测试鼠标是否在最后定义的形状内

下面是示例代码和演示:http://jsfiddle.net/m1erickson/o5xp21t2/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    ctx.strokeStyle = "black";
    ctx.fillStyle = "red";    
    ctx.globalAlpha = 1.0; 
    ctx.lineWidth = 0.5;
    ctx.font="14px verdana";

    var centerX=150;
    var centerY=150;
    var radius=120;
    var arg=1;
    var start=0;
    var end=Math.PI/8;
    var shapes=[];

    for(var k=0;k<10;k++){
        start+=Math.PI/8;
        end+=Math.PI/8;
        x1 = centerX-radius*Math.sin(-arg*start)*0.9;
        y1 = centerY-radius*Math.cos(-arg*start)*0.9;
        x2 = centerX-radius*Math.sin(-arg*start)*0.95;
        y2 = centerY-radius*Math.cos(-arg*start)*0.95;
        x3 = centerX-radius*Math.sin(-arg*end)*0.95;
        y3 = centerY-radius*Math.cos(-arg*end)*0.95;
        x4 = centerX-radius*Math.sin(-arg*end)*0.9;
        y4 = centerY-radius*Math.cos(-arg*end)*0.9; 
        var s={x1:x1,y1:y1,x2:x2,y2:y2,x3:x3,y3:y3,x4:x4,y4:y4,k:k};
        shapes.push(s);
        Shape(s,k,true);
    }

    $results=$("#results");

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

    function handleMouseMove(e){
      e.preventDefault();
      e.stopPropagation();

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

      for(var k=0;k<shapes.length;k++){
          Shape(shapes[k],k,false);
          if(ctx.isPointInPath(mouseX,mouseY)){
              $results.text("Last mouseover: "+k);
          }
      }
    }

    function Shape(s, k, draw){
        ctx.fillStyle="red";
        ctx.beginPath();
        ctx.moveTo(s.x1,s.y1);
        ctx.lineTo(s.x2,s.y2); 
        ctx.lineTo(s.x3,s.y3); 
        ctx.lineTo(s.x4,s.y4); 
        ctx.lineTo(s.x1,s.y1);
        if(draw){
            ctx.fill();
            ctx.stroke();
            ctx.fillStyle="blue";
            ctx.fillText(k,(s.x2+s.x3)/2,(s.y2+s.y3)/2);    
        }
    }

}); // end $(function(){});
</script>
</head>
<body>
    <p id=results>Hover mouse over shapes.</p>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
詹甫
2023-03-14

画布像位图一样绘制。所有更改都是对像素进行的,不会保留线条或路径的痕迹。如果您想查看单击是在特定路径上还是在特定路径内,则需要实现自己的命中测试。如果绘制的形状可以相互重叠,则需要自己处理顺序。这是可行的,但你得靠自己。

另一种解决方法是使用SVG。因为SVG是对象,所以浏览器将为您跟踪它们。您只需将onclick添加到SVG元素,就像添加到HTML元素一样。

最简单的解决方案是使用d3这样的库:http://d3js.org/

顾亦
2023-03-14

如果将形状的坐标保持在一个数组中,则可以通过它们循环并检查是否与鼠标坐标发生冲突。

 类似资料:
  • 我想在画布上画200个对象 并将鼠标添加到每个事件上,鼠标单击事件 像这样的源代码 (有效k增加) 对于(k=0;k <我的希望是 如果鼠标悬停在形状上,则显示有效的k 如果鼠标单击形状,则转到其他url,并使用有效的k参数 请帮助我<谢谢

  • 我在画布上处理鼠标事件时遇到问题。我想用鼠标来绘制它,我已经想出了这些事件处理程序,但当我开始绘制时,它们什么都不做。 你能帮我告诉我遗漏了什么或者如何重写它以便它开始工作吗?

  • 我是WPF的新手。 我想在Canvas上的鼠标移动事件上画一个圆圈。我已经编写了在画布上拖动它的逻辑。但是我想在鼠标点击我的画布时创建一个圆圈,它应该根据鼠标在画布上的移动来调整大小。 我怎样才能做到这一点? 这是我的代码

  • 我编写了这段代码,可以在JavaFX画布上绘制。它可以很好地工作,但我不知道如何重新绘制画布(比如在Swing中),以便在新画布上重新开始绘制。这是我的代码,非常感谢你的帮助!马里奥

  • 现在我有一个应用程序,可以让用户单击按钮浏览用作画布背景的图片。我想这样做,如果用户单击画布上的某个地方,则在该点放置一个节点。我假设我需要获取鼠标坐标。有没有一个简单的方法可以调用将节点放置在鼠标单击位置,或者我必须在这个链接中选择路线:WPF-使用鼠标事件在画布上绘图?提前谢谢。 编辑:添加了我尝试制作椭圆的代码。不过它不起作用,而且我不确定如何使用鼠标点击椭圆的坐标。我知道对于一行来说,它只

  • 所以我有这个anchorpane,我希望为第二个鼠标键添加一个鼠标listner。我尝试了以下方法,但我一直得到一个错误,有人知道问题是什么吗? 为了记录在案,我也尝试过这样做: 绑定不匹配:MouseButton类型不能有效替代EventHandler类型的有界参数