HTML画布悬停文本

Mik*_*ike 1 html javascript html5 canvas

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

mar*_*rkE 6

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

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

    var triangle={
        name:'triangle',
        color:'skyblue',
        points:[{x:100,y:100},{x:150,y:150},{x:50,y:150}]
    };
    
    Run Code Online (Sandbox Code Playgroud)
  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();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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
    }
    
    Run Code Online (Sandbox Code Playgroud)

这是示例代码和演示:

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();
}
Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)