I try to develop HTML 5 Canvas has context menu. When click for every image in Canvas, it will show context menu for each image. At there, I has only one canvas
One idea is to create your own custom context menu using an unordered list.
Override the default context menu by listening for contextmenu
events on the canvas.
canvas.addEventListener('contextmenu', handleContextMenu, false);
When the context mouse button is clicked inside a particular image drawn on your canvas you can rebuild the UL with list items individualized for the image that was clicked.
Set the UL's position:absolute
, left
, top
to position your context menu over the mouse position on the canvas.
You can hide the UL when its not needed.
Listen for click events on the UL's list items to respond to a users context menu selection.
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(); }
window.onresize=function(e){ reOffset(); }
var $menu=$('#contextMenu');
var rects=[];
rects.push({x:50,y:50,width:50,height:50,color:"red",contextMenu:['One red','Two red']});
rects.push({x:150,y:100,width:75,height:75,color:"blue",contextMenu:['One blue','Two blue']});
ctx.clearRect(0,0,cw,ch);
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();
}
$('#contextMenu').on('click','li',function(e){
// hide the context menu
showContextMenu();
alert('Context selection: '+$(this).text());
});
// hide the context menu
showContextMenu();
canvas.addEventListener('mousedown', handleMouseDown, false);
canvas.addEventListener('contextmenu', handleContextMenu, false);
function handleMouseDown(e){
// hide the context menu
showContextMenu();
}
function handleContextMenu(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get mouse position relative to the canvas
var x=parseInt(e.clientX-offsetX);
var y=parseInt(e.clientY-offsetY);
// hide the context menu
showContextMenu();
// 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 ){
showContextMenu(rect,x,y);
}
}
return(false);
}
function showContextMenu(r,x,y){
if(!r){$menu.hide(); return;}
$menu.show();
var m=r.contextMenu;
$menu.empty();
$menu.css({left:x,top:y});
for(var i=0;i<m.length;i++){
$('<li>', { text:m[i], 'data-fn':i, }).appendTo($menu[0]);
}
}
body{ background-color: ivory; padding:0; }
#canvas{border:1px solid red;}
#canvasContainer{position:relative;}
#canvas,#contextMenu{position:absolute;}
#contextMenu{
border:1px solid green;
background:white;
list-style:none;
padding:3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Right click on rect for context menu.</h4>
<div id=canvasContainer>
<canvas id="canvas" width=300 height=300></canvas>
<ul id=contextMenu><li>Test</li></ul>
</div>