First off i'm new to javascript and still learning its basics, i'm trying to determine in which box i clicked(canvas). My boxes are a list of dictionaries that look like this if we use console.log to visualize them, let's call that list labels
:
[
{"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141"},
{"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141"},
{"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145"},
{"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145"}
]
Here we can see we have 4 rectangles and their coordinates. The function i used to get mouse clicks is :
canvas.addEventListener("contextmenu", getPosition, false);
function getPosition(event) {
event.preventDefault();
var x = event.x;
var y = event.y;
var canvas = document.getElementById("canvas");
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
console.log("x:" + x + " y:" + y);
}
The part where i'm struggling is to find out if where i clicked are inside any of the boxes and if the click is inside one i want the id.
What i tried:
I tried adding this after the console.log
in the previous code snippet:
for (i = 0,i < labels.length; i++) {
if (x>labels[i].xMin) and (x<labels[i].xMax) and (y>labels[i].yMin) and (y<labels[i].yMax) {
log.console(labels[i].id)
}
}
but it didn't work
The rects in Labels are all very far to the right, so probably you need to add the scroll position to the mouse position.
Made a working example (open the console to see the result): https://jsfiddle.net/dgw0sxu5/
<html>
<head>
<style>
body{
background: #000;
margin: 0
}
</style>
<script>
//Some object which is used to return an id from a click
//Added a fillStyle property for testing purposes
var Labels = [
{"id":"0","image":"1-0.png","name":"","xMax":"4956","xMin":"0","yMax":"50","yMin":"0","fillStyle":"pink"},
{"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141","fillStyle":"red"},
{"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141","fillStyle":"blue"},
{"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145","fillStyle":"limegreen"},
{"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145","fillStyle":"aqua"}
];
//Initialisiing for the testcase
window.onload = function(){
//The canvas used for click events
var tCanvas = document.body.appendChild(document.createElement('canvas'));
tCanvas.width = 4956; //Highest xMax value from labels
tCanvas.height = 157; //Highest yMax value from labels
//The graphical object
var tCTX = tCanvas.getContext('2d');
//Drawing the background
tCTX.fillStyle = '#fff';
tCTX.fillRect(0, 0, tCanvas.width, tCanvas.height);
//Drawing the rects for testing purposes
//The rectangles are kinda far on the right side
for(var i=0, j=Labels.length; i<j; i++){
tCTX.fillStyle = Labels[i].fillStyle;
tCTX.fillRect(+(Labels[i].xMin), +(Labels[i].yMin), +(Labels[i].xMax)-+(Labels[i].xMin), +(Labels[i].yMax)-+(Labels[i].yMin));
};
tCanvas.onclick = function(event){
var tX = event.clientX - this.offsetLeft + (document.body.scrollLeft || document.documentElement.scrollLeft), //X-Position of click in canvas
tY = event.clientY - this.offsetTop + (document.body.scrollTop || document.documentElement.scrollTop), //Y-Position of click in canvas
tR = []; //All found id at that position (can be more in theory)
//Finding the Labels fitting the click to their bounds
for(var i=0, j=Labels.length; i<j; i++){
if(tX >= +(Labels[i].xMin) && tX <= +(Labels[i].xMax) && tY >= +(Labels[i].yMin) && +(tY) <= +(Labels[i].yMax)){
tR.push(Labels[i].id)
}
};
console.log(
'Following ids found at the position @x. @y.: '
.replace('@x.', tX)
.replace('@y.', tY),
tR.join(', ')
)
}
}
</script>
</head>
<body></body>
</html>
First of all: what exactly did not work?
var canvas = document.getElementById("canvas");
should be outside of your function to save performance at a second call.
And getting coordinates is not complicated, but complex.
There is a great resource on how to get the right ones: http://javascript.info/coordinates
Be sure about the offset measured relative to the parent element ( offsetParent
and also your offsetLeft
), document upper left ( pageX
) or viewport upper left ( clientX
).
Your logic seems to be correct, you just need to fix the syntax.
for (i = 0; i < labels.length; i++) {
if ((x>labels[i].xMin) && (x<labels[i].xMax) && (y>labels[i].yMin) && (y<labels[i].yMax)) {
console.log(labels[i].id)
}
}
Here is a complete example:
labels = [
{"id":"1","image":"1-0.png","name":"","xMax":"4802","xMin":"4770","yMax":"156","yMin":"141"},
{"id":"2","image":"1-0.png","name":"","xMax":"4895","xMin":"4810","yMax":"157","yMin":"141"},
{"id":"3","image":"1-0.png","name":"","xMax":"4923","xMin":"4903","yMax":"156","yMin":"145"},
{"id":"4","image":"1-0.png","name":"","xMax":"4956","xMin":"4931","yMax":"156","yMin":"145"}
]
var canvas = document.getElementById("canvas");
canvas.addEventListener("contextmenu", getPosition, false);
function getPosition(event) {
event.preventDefault();
var x = event.clientX;
var y = event.clientY;
var label = labels.find(function(label){
return (x>label.xMin) && (x<label.xMax) && (y>label.yMin) && (y<label.yMax)
});
if(label){
console.log("clicked label", label.id);
}else{
console.log("no label was clicked");
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.