I am making a html game and want to add onscreen buttons.
To do this I think I need to know what pixel the mouse is at when I click.
If anyone knows how to do that or has another way to make buttons LMK.
I am making a html game and want to add onscreen buttons.
To do this I think I need to know what pixel the mouse is at when I click.
If anyone knows how to do that or has another way to make buttons LMK.
Here are the basics of finding a mouse position:
Get a reference to the DOM element on which you want to listen for mouse events.
var canvas=document.getElementById("canvas");
The browser reports mouse coordinates relative to the top-left of the window rather than relative to your canvas element, so you need to account for the difference between the window & canvas positions. Use .getBoundingClientRect
to fetch the offset of the canvas element within the window.
// save the canvas offset in global variables
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
Tell the browser you want to be told when the user does something with the mouse by subscribing to mouse events. You can do this using .onmousedown, .onmousemove, .onmouseup & .onmouseout
and giving the browser functions to execute when these events occur.
// listen for mousedown events, call handleMousedown() when they occur
// listen for mousemove events, call handleMousemove() when they occur
// listen for mouseup events, call handleMouseup() when they occur
// listen for mouseout events, call handleMouseout() when they occur
canvas.onmousedown=handleMousedown;
canvas.onmousemove=handleMousemove;
canvas.onmouseup=handleMouseup;
canvas.onmouseout=handleMouseup;
Respond to mouse events by coding mouse handler functions. The browser will automatically send an mouseevent
argument when it executes the handler. That mouseevent contains clientX & clientY
properties which are the X,Y coordinates relative to the top-left corner of the visible client area. To get the mouse position inside the canvas you must subtract BBoffsetX & BBoffsetY
which were calculated in step#2.
// this function is called every time the user presses the mouse down.
// "e" is the mouseevent argument the browser automatically sends
function handleMousedown(e){
// calculate the mouse position RELATIVE TO THE CANVAS
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// you have the mouse position so now do your button stuff
}
A refinement if the window will be scrolled...If the page content is larger than will fit in the browser display area, the browser will add scrollbars to let the user scroll to view all the page content. When the window scrolls, your offsets calculated in step#2 will become invalid so they must be recalculated. You can subscribe to the window.onscroll
event and recalculate the offsets when scrolling occurs.
// listen for events that invalidate the canvas offsets
window.onscroll=function(e){ setBB(); }
window.onresize=function(e){ setBB(); }
// recalculate the offsets
function setBB(){
BB=canvas.getBoundingClientRect();
BBoffsetX=BB.left;
BBoffsetY=BB.top;
}
About your custom buttons
Here's a simple button system...
...You're welcome to start with it...
var $clicked=$('#clicked');
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 clickedButton;
var buttons=[];
buttons.push(makeButton(1,20,20,50,20,'One','skyblue','gray','black',
function(){ $clicked.text('You clicked: '+this.id+' with label: '+this.label); },
function(){ $clicked.text('You released: '+this.id+' with label: '+this.label); }
));
buttons.push(makeButton(2,20,50,50,20,'Two','lightgreen','gray','black',
function(){ $clicked.text('You clicked: '+this.id+' with label: '+this.label); },
function(){ $clicked.text('You released: '+this.id+' with label: '+this.label); }
));
//
drawAll();
//
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mouseup(function(e){handleMouseUpOut(e);});
$("#canvas").mouseout(function(e){handleMouseUpOut(e);});
function makeButton(id,x,y,w,h,label,fill,stroke,labelcolor,clickFn,releaseFn){
return({
id:id,
x:x, y:y, w:w, h:h,
fill:fill, stroke:stroke, labelcolor:labelcolor,
label:label,
click:clickFn,
release:releaseFn
});
}
function drawAll(){
for(var i=0;i<buttons.length;i++){
drawButton(buttons[i],false);
}
}
function drawButton(b,isDown){
ctx.clearRect(b.x-1,b.y-1,b.w+2,b.h+2);
ctx.fillStyle=b.fill;
ctx.fillRect(b.x,b.y,b.w,b.h);
ctx.strokeStyle=b.stroke;
ctx.strokeRect(b.x,b.y,b.w,b.h);
ctx.textAlign='center';
ctx.textBaseline='middle';
ctx.fillStyle=b.labelcolor;
ctx.fillText(b.label,b.x+b.w/2,b.y+b.h/2);
if(isDown){
ctx.beginPath();
ctx.moveTo(b.x,b.y+b.h);
ctx.lineTo(b.x,b.y);
ctx.lineTo(b.x+b.w,b.y);
ctx.strokeStyle='black';
ctx.stroke();
}
}
function findButton(mx,my){
for(var i=0;i<buttons.length;i++){
var b=buttons[i];
if(mx>b.x && mx<b.x+b.w && my>b.y && my<b.y+b.h){
return(buttons[i]);
}
}
return(null);
}
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// check if a button was clicked under the mouse
var b=findButton(mouseX,mouseY);
if(b){
clickedButton=b;
drawButton(b,true);
b.click();
}
}
function handleMouseUpOut(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// release any clicked button
if(clickedButton){
drawButton(clickedButton,false);
clickedButton.release();
clickedButton=null;
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4 id=clicked>Click a button.</h4>
<canvas id="canvas" width=300 height=300></canvas>