Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
29
rated 0 times [  31] [ 2]  / answers: 1 / hits: 18796  / 10 Years ago, wed, june 4, 2014, 12:00:00

I have created a line inside a canvas element. I am looking for the easiest way to detect if the position of the mouse is inside the line, which is inside the canvas.



I have used this function to see the position of the mouse inside the canvas, but I am very confused on how I should proceed.



function getMousePos(c, evt) {
var rect = c.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}


I have also looked at this topic Fabricjs detect mouse over object path , but it detects if the mouse is inside the canvas, not inside the object.



The line that I create is a part of smaller lines, connected to each other.



 for (var i = 0; i < 140 ; i++) {

ctx.beginPath();

ctx.moveTo(x[i],y[i]);
ctx.quadraticCurveTo(x[i],50,x[i+1],y[i+1]);
ctx.lineWidth = 40;

ctx.strokeStyle = 'white';
ctx.lineCap = 'round';
ctx.stroke();

}


where x[i] and y[i] are the arrays with the coordinates that I want.



I hope my question is clear, although I am not very familiar with javascript.



Thanks
Dimitra


More From » html

 Answers
20

A Demo: http://jsfiddle.net/m1erickson/Cw4ZN/



enterenter



You need these concepts to check if the mouse is inside a line:




  • Define the starting & ending points of a line


  • Listen for mouse events


  • On mousemove, check if the mouse is within a specified distance of the line




Here's annotated example code for you to learn from.





$(function() {

// canvas related variables
var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);
var $canvas = $(#canvas);
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

// dom element to indicate if mouse is inside/outside line
var $hit = $(#hit);

// determine how close the mouse must be to the line
// for the mouse to be inside the line
var tolerance = 5;

// define the starting & ending points of the line
var line = {
x0: 50,
y0: 50,
x1: 100,
y1: 100
};

// set the fillstyle of the canvas
ctx.fillStyle = red;

// draw the line for the first time
draw(line);

// function to draw the line
// and optionally draw a dot when the mouse is inside
function draw(line, mouseX, mouseY, lineX, lineY) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(line.x0, line.y0);
ctx.lineTo(line.x1, line.y1);
ctx.stroke();
if (mouseX && lineX) {
ctx.beginPath();
ctx.arc(lineX, lineY, tolerance, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
}

// calculate the point on the line that's
// nearest to the mouse position
function linepointNearestMouse(line, x, y) {
//
lerp = function(a, b, x) {
return (a + x * (b - a));
};
var dx = line.x1 - line.x0;
var dy = line.y1 - line.y0;
var t = ((x - line.x0) * dx + (y - line.y0) * dy) / (dx * dx + dy * dy);
var lineX = lerp(line.x0, line.x1, t);
var lineY = lerp(line.y0, line.y1, t);
return ({
x: lineX,
y: lineY
});
};

// handle mousemove events
// calculate how close the mouse is to the line
// if that distance is less than tolerance then
// display a dot on the line
function handleMousemove(e) {
e.preventDefault();
e.stopPropagation();
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
if (mouseX < line.x0 || mouseX > line.x1) {
$hit.text(Outside);
draw(line);
return;
}
var linepoint = linepointNearestMouse(line, mouseX, mouseY);
var dx = mouseX - linepoint.x;
var dy = mouseY - linepoint.y;
var distance = Math.abs(Math.sqrt(dx * dx + dy * dy));
if (distance < tolerance) {
$hit.text(Inside the line);
draw(line, mouseX, mouseY, linepoint.x, linepoint.y);
} else {
$hit.text(Outside);
draw(line);
}
}

// tell the browser to call handleMousedown
// whenever the mouse moves
$(#canvas).mousemove(function(e) {
handleMousemove(e);
});

}); // end $(function(){});

body {
background-color: ivory;
}

canvas {
border: 1px solid red;
}

<!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>

</head>

<body>
<h2 id=hit>Move mouse near line</h2>
<canvas id=canvas width=300 height=300></canvas>
</body>

</html>





About hit-testing Paths:



If you create Paths using path commands you can use context.isPointInPath(mouseX,mouseY) to check if the mouse is inside a path. context.isPointInPath does not work well with lines however because lines theoretically have zero width to hit.


[#70724] Tuesday, June 3, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
mckinleykeyshawnb

Total Points: 281
Total Questions: 99
Total Answers: 111

Location: Saudi Arabia
Member since Sat, Aug 20, 2022
2 Years ago
;