Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas - Context Sensitive Menu

I'm drawing a number of rectangles on an HTML5 canvas and want to be able to right click on the boxes and get a context sensitive menu displayed. The menu should be specific to the type of box being clicked on and be totally user specified, i.e. it should not include Reload, Save As, Print etc...

Can any one give me any pointers?

Thanks, Paul

like image 623
PaulN Avatar asked Jun 13 '13 14:06

PaulN


1 Answers

You can addEventListener for context menu to handle right-mouse requests:

// listen for contextmenu requests
canvas.addEventListener('contextmenu', handleContextmenu, false);  

Then in the handler, you check each of your rects for hits:

    function handleContextmenu(e){

      // get mouse position relative to the canvas
      var x=parseInt(e.clientX-offsetX);
      var y=parseInt(e.clientY-offsetY);


      // check each rect for hits
      for(var i=0;i<rects.length;i++){
          var rect=rects[i];
          var rectRight=rect.x+rect.width;
          var rectBottom=rect.y+rect.height;

          // if this rect is hit, display an alert
          if(x>=rect.x && x<=rectRight && y>=rect.y && y<=rectBottom  ){
              alert("Context menu request on the "+rect.color+" rectangle.");
          }
      }

      // prevents the usual context from popping up
      e.preventDefault()
      return(false); 
    }

Here is working code (no jsFiddle because no right-clicking in X-Domain iframes):

<!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 canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    var rects=[];

    rects.push({x:50,y:50,width:50,height:50,color:"red"});
    rects.push({x:150,y:100,width:75,height:75,color:"blue"});

    ctx.clearRect(0,0,canvas.width,canvas.height);
    for(var i=0;i<rects.length;i++){
        var rect=rects[i];
        ctx.beginPath();
        ctx.fillStyle=rect.color;
        ctx.rect(rect.x,rect.y,rect.width,rect.height);
        ctx.fill();
    }

    // listen for contextmenu requests
    canvas.addEventListener('contextmenu', handleMouseDown, false);  

    function handleMouseDown(e){

      // get mouse position relative to the canvas
      var x=parseInt(e.clientX-offsetX);
      var y=parseInt(e.clientY-offsetY);


      // check each rect for hits
      for(var i=0;i<rects.length;i++){
          var rect=rects[i];
          var rectRight=rect.x+rect.width;
          var rectBottom=rect.y+rect.height;

          // check each rect for hits
          if(x>=rect.x && x<=rectRight && y>=rect.y && y<=rectBottom  ){
              alert("Context menu request on the "+rect.color+" rectangle.");
          }
      }

      // prevents the usual context from popping up
      e.preventDefault()
      return(false); 
    }

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
like image 77
markE Avatar answered Oct 18 '22 17:10

markE