如何检测鼠标位置是否hover

我有这个讨论 ,指出如何制作铅笔工具。

如何使用铅笔工具检测鼠标是否在绘制的区域/点/图像上hover? 然后,它将通过在其上创建一个圆圈来突出显示起点和终点。

在你的情况下唯一的解决方案是将所有绘制的点保存到数组中,它们自己保存在一个包含所有pathes的数组中:

  • onmousedown :创建一个新的路径数组。
  • onmousemove
    – 如果是绘图 – >用每个绘制的点填充currentPath的数组。
    – 否 – >检查实际鼠标坐标是否在任何路径数组中。
 var ctx = canvas.getContext("2d"), painting = false, lineThickness = 1; canvas.width = canvas.height = 600; var dCanvas = canvas.cloneNode(true); dCtx = dCanvas.getContext('2d'); pCanvas = canvas.cloneNode(true); pCtx = pCanvas.getContext('2d'); dCtx.fillStyle = "#FFF"; pCtx.fillStyle = "red"; ctx.fillRect(0, 0, 600, 600); var pathes = [], currentPath; canvas.onmousedown = function(e) { currentPath = []; pathes.push(currentPath); painting = true; }; canvas.onmouseup = function(e) { painting = false; } canvas.onmousemove = function(e) { pCtx.clearRect(0, 0, canvas.width, canvas.height); var mouseX = e.pageX - this.offsetLeft, mouseY = e.pageY - this.offsetTop; if (painting) { var lastPoint = currentPath[currentPath.length-1] || { x: e.pageX - canvas.offsetLeft, y: e.pageY - canvas.offsetTop }; var x1 = mouseX, x2 = lastPoint.x, y1 = mouseY, y2 = lastPoint.y; var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1)); if (steep) { var x = x1; x1 = y1; y1 = x; var y = y2; y2 = x2; x2 = y; } if (x1 > x2) { var x = x1; x1 = x2; x2 = x; var y = y1; y1 = y2; y2 = y; } var dx = x2 - x1, dy = Math.abs(y2 - y1), error = 0, de = dy / dx, yStep = -1, y = y1; if (y1 < y2) { yStep = 1; } lineThickness = 5-Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) / 10; if (lineThickness < 1) { lineThickness = 1; } for (var x = x1; x < x2; x++) { if (steep) { dCtx.fillRect(y, x, lineThickness, lineThickness); currentPath.push({x: y,y: x}); } else { dCtx.fillRect(x, y, lineThickness, lineThickness); currentPath.push({x: x,y: y}); } error += de; if (error >= 0.5) { y += yStep; error -= 1.0; } } currentPath.push({x: mouseX,y: mouseY}); } else { pathes.forEach(function(path) { if (path.some(function(point) { return isBetween(mouseX, point.x, 5) && isBetween(mouseY, point.y, 5) })) { pCtx.beginPath(); pCtx.arc(path[0].x+2.5, path[0].y+2.5, 5, 0, Math.PI*2); pCtx.fill(); pCtx.beginPath(); pCtx.arc(path[path.length-1].x+2.5, path[path.length-1].y+2.5, 5, 0, Math.PI*2); pCtx.fill(); } }); } ctx.fillRect(0, 0, 600, 600); ctx.drawImage(dCanvas, 0, 0); ctx.drawImage(pCanvas, 0, 0); } function isBetween(x, y, z) { return (x >= y - z && x <= y + z); } 
 canvas { border: 1px solid } 
  

您可以从canvas获取(每像素)图像数据: https : //developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData 。 然后检查鼠标是否hover在绿色像素上。

这是一个快速演示。 将鼠标移动到线的任一端的5px内以查看指南。

我们的想法是,如果鼠标位于行的起点或终点的5个像素内,它会使用碰撞检测来确定。

您可以轻松地从丑陋的方形指南更改为圆形。 你基本上可以做你想做的事。

 var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'); canvas.width = 500; canvas.height = 400; document.body.appendChild(canvas); //add as many lines as you want var lines = [ {start: {x: 100, y: 100}, end: {x: 200, y: 300}}, {start: {x: 200, y: 150}, end: {x: 50, y: 250}}, {start: {x: 240, y: 240}, end: {x: 450, y: 150}}, {start: {x: 160, y: 340}, end: {x: 10, y: 90}}, {start: {x: 380, y: 270}, end: {x: 300, y: 380}} ]; function render(){ ctx.clearRect(0,0,500,400); for(var c = 0; c < lines.length; c++){ ctx.moveTo(lines[c].start.x, lines[c].start.y); ctx.lineTo(lines[c].end.x, lines[c].end.y); ctx.stroke(); } } render(); var mouse = {x: 0, y: 0}; document.addEventListener('mousemove', function(e){ mouse.x = e.clientX; mouse.y = e.clientY; render(); for(var c = 0; c < lines.length; c++){ if( //check if within 10px of start of line (mouse.x > lines[c].start.x - 5 && mouse.x < lines[c].start.x + 5 && mouse.y > lines[c].start.y - 5 && mouse.y < lines[c].start.y + 5) || //same for the end of the line (mouse.x > lines[c].end.x - 5 && mouse.x < lines[c].end.x + 5 && mouse.y > lines[c].end.y - 5 && mouse.y < lines[c].end.y + 5) ){ showGuides(c); } } }); //function to show the guides function showGuides(i){ ctx.fillRect(lines[i].start.x - 5, lines[i].start.y - 5, 10, 10); ctx.fillRect(lines[i].end.x - 5, lines[i].end.y - 5, 10, 10); } 
 body{ margin: 0; }