javascript - HTML画布悬停文本

javascript - HTML画布悬停文本,第1张

我有一个HTML画布,其中包含所有不同大小的所有不同形状,它是通过解析外部文件中的信息构建的。我想知道如何制作它,以便将鼠标悬停在每个形状上将显示其唯一的名称。我找到了有关如何在鼠标悬停上为整个画布显示文本的资源,但我需要每个单独的形状来显示唯一的文本。谢谢!

最佳答案:

2 个答案:

答案 0 :(得分:6)

您可以使用context.isPointInPath来测试您的鼠标是否悬停在其中一个形状上。

  1. 创建一个表示外部文件中每个形状的javascript对象。

    var triangle={
        name:'triangle',
        color:'skyblue',
        points:[{x:100,y:100},{x:150,y:150},{x:50,y:150}]
    };
    
  2. 创建一个函数,该函数接受一个shape-object并从该shape-object创建一个Path:

    function defineShape(s){
        ctx.beginPath();
        ctx.moveTo(s[0].x,s[0].y);
        for(var i=1;i<s.length;i  ){
            ctx.lineTo(s[i].x,s[i].y);
        }
        ctx.closePath();
    }
    
  3. 使用context.isPointInPath测试鼠标是否在最近定义的路径内(来自步骤2)。

    // define the path to be tested
    defineShape(triangle);
    
    // test if the mouse is inside that shape
    if(context.isPointInPath(mouseX,mouseY){
        // the mouse is inside the shape
    }
    
  4. 以下是示例代码和演示:

    &#13; &#13;
    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(); }
    window.onresize=function(e){ reOffset(); }
    
    ctx.font='14px verdana';
    
    var shapes=[];
    
    var triangle1={
      name:'triangle1',
      color:'skyblue',
      drawcolor:'skyblue',
      points:[{x:100,y:100},{x:150,y:150},{x:50,y:150}]
    };
    
    var triangle2={
      name:'triangle2',
      color:'palegreen',
      drawcolor:'palegreen',
      points:[{x:220,y:100},{x:270,y:150},{x:170,y:150}]
    };
    
    shapes.push(triangle1,triangle2);
    
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    
    drawAll();
    
    function drawAll(){
      for(var i=0;i<shapes.length;i  ){
        var s=shapes[i];
        defineShape(s.points);
        ctx.fillStyle=s.drawcolor;
        ctx.fill();
        ctx.stroke();
        if(s.color!==s.drawcolor){
          ctx.fillStyle='black';
          ctx.fillText(s.name,s.points[0].x,s.points[0].y);
        }
      }
    }
    
    
    function defineShape(s){
      ctx.beginPath();
      ctx.moveTo(s[0].x,s[0].y);
      for(var i=1;i<s.length;i  ){
        ctx.lineTo(s[i].x,s[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);
    
      // clear the canvas
      ctx.clearRect(0,0,cw,ch);
    
      for(var i=0;i<shapes.length;i  ){
        var s=shapes[i];
    
        // define the shape path we want to test against the mouse position
        defineShape(s.points);
        // is the mouse insied the defined shape?
        if(ctx.isPointInPath(mouseX,mouseY)){
          // if yes, fill the shape in red
          s.drawcolor='red';
        }else{
          // if no, fill the shape with blue
          s.drawcolor=s.color;
        }
    
      }
    
      drawAll();
    }
    &#13;
    body{ background-color: ivory; }
    #canvas{border:1px solid red; margin:0 auto; }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>Hover the mouse over the shape.</h4>
    <canvas id="canvas" width=300 height=300></canvas>
    &#13; &#13; &#13;

    答案 1 :(得分:2)

    您是否愿意使用库,或者您是否附加到纯粹的原生画布实现?使用纯粹的原生画布,这可能会非常烦人,因为您不仅要获得指针的鼠标坐标,还要跟踪每个对象的位置,并检查鼠标是否每次都在该位置鼠标移动。我对该功能进行了一次编码,只需几个矩形就足以让人烦恼。

    另一方面,如果您使用KineticJS进行画布绘制(或者可能是其他人; KineticJS只是我使用的那个),那么所有烦恼都会为您处理。您创建并添加到画布的对象可以使用KineticJS库将事件处理程序附加到它们上,并且它只比在任何其他HTML元素上对鼠标悬停事件做出反应要困难得多。此链接显示了如何执行此操作。

    http://www.html5canvastutorials.com/kineticjs/html5-canvas-listen-or-dont-listen-to-events-with-kineticjs/

    本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复