这基本上是我的要求,而不是问题,我必须在画布上绘制多边形(与绘画相同),但是我坚持我的要求,我必须显示工具提示悬停在绘制的每个多边形上。我知道对于像矩形这样的形状,我可以更容易地使用简单的for循环管理坐标,但是如何处理多边形。它甚至可能吗? 下面是我绘制多边形的代码
var startPointX = "", startPointY = "", endpointX, endpointY, isnewShape = false;
tools.polygon = function () {
var tool = this;
this.started = false;
this.mousedown = function (ev) {
tool.started = true;
tool.x0 = ev._x;
tool.y0 = ev._y;
if ((Math.abs(startPointX - ev._x) < 5) && (Math.abs(startPointY - ev._y) < 5) && (startPointX != ev._x && startPointY != ev._y) && !isnewShape) {
alert('point matched');
startPointX = "";
startPointY = "";
isnewShape = true;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(endpointX, endpointY);
context.lineTo(ev._x, ev._y);
endpointX = ev._x;
endpointY = ev._y;
context.stroke();
context.closePath();
img_update();
tool.started = false;
}
else {
// console.log(isnewShape);
if (startPointX == "" || startPointY == "")
return;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(endpointX, endpointY);
isnewShape = false;
context.lineTo(ev._x, ev._y);
endpointX = ev._x;
endpointY = ev._y;
context.stroke();
context.closePath();
img_update();
}
};
this.mousemove = function (ev) {
if (!tool.started) {
return;
}
// console.log('mousemove');
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.lineTo(ev._x, ev._y);
endpointX = ev._x;
endpointY = ev._y;
context.stroke();
context.closePath();
};
this.mouseup = function (ev) {
if (tool.started) {
if (startPointX == "" && startPointY == "") {
startPointX = tool.x0;
startPointY = tool.y0;
}
tool.started = false;
img_update();
}
};
};
答案 0 :(得分:2)
除了维护用户看到的画布外,还要在隐藏的第二个画布上绘制所有内容。重要的是每个多边形应该是自己的颜色。它不一定是人类可区分的 - 您可以将第一个绘制为#000000
,将第二个#000001
绘制,等等。这为1600万个多边形提供了支持 - 应该足够了!
然后,当用户将鼠标移到画布上时,找出鼠标的位置并查看隐藏画布上的颜色。这将告诉您正在徘徊的形状,您可以采取相应的行动。
答案 1 :(得分:1)
您可以使用canvas的内置命中测试方法:context.isPointInPath(x,y);
isPointInPath将测试x,y是否在最近定义的路径中。
它的工作原理如下:
据推测,您有定义每个多边形的坐标
// create an object holding all polygon points
var triangle=[{x:100,y:50},{x:150,y:100},{x:50,y:100}];
要进行命中测试,首先要重新定义三角形:
// define the polygon
function define(polygon){
ctx.beginPath();
ctx.moveTo(polygon[0].x,polygon[0].y);
for(var i=1;i<polygon.length;i++){
ctx.lineTo(polygon[i].x,polygon[i].y);
}
ctx.closePath();
}
然后使用isPointInPath检查是否有任何x,y在重新定义的三角形内
console.log( ctx.isPointInPath(mouseX,mouseY); );
以下是示例代码和演示:http://jsfiddle.net/m1erickson/d3kdf/
<!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>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
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;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var $results=$("#results");
// create an object holding all polygon points
var triangle=[{x:100,y:50},{x:150,y:100},{x:50,y:100}];
// draw the polygon
define(triangle);
ctx.fill();
// define the polygon
function define(polygon){
ctx.beginPath();
ctx.moveTo(polygon[0].x,polygon[0].y);
for(var i=1;i<polygon.length;i++){
ctx.lineTo(polygon[i].x,polygon[i].y);
}
ctx.closePath();
}
function hitTest(polygon){
// redefine the polygon
// (necessary to isPointInPath to work
define(polygon);
// ask isPointInPath to hit test the mouse position
// against the current path
return(ctx.isPointInPath(mouseX,mouseY));
}
function handleMouseMove(e){
e.preventDefault();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// check if the mouse is inside the polygon
var isInside=hitTest(triangle);
if(isInside){
$results.text("Mouse is inside the Triangle");
}else{
$results.text("Outside");
}
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<p id="results">Hit results</p>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>