使用isPointInPath()和响应式设计的多画布多边形检测映射
问题描述:
我有一个正确绘制的画布对象数组。我有三个问题:使用isPointInPath()和响应式设计的多画布多边形检测映射
- 偏移。我已经在JS小提琴中测试了下面的代码,它可以工作,但是当我将它导出到我的网页时,变量会发生偏斜。检测发生,但没有在正确的地方。页面宽度在CSS中设置,实际画布区域使用margin:0自动调用居中,但是它小于页面宽度。
<canvas id="canvas" width="780" height="690" style="position:absolute;"></canvas>
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");
// define the polygon items
var polyArray = new Array (6);
polyArray [0] =[{x:50,y:236}, {x:200,y:115}, {x:350,y:50}, {x:350,y:300}, {x:232,y:325}, {x:75,y:300}];
polyArray [1] =[{x:350,y:55}, {x:350,y:300}, {x:510,y:300}, {x:510,y:205}, {x:578,y:172}, {x:690,y:96}, {x:650,y:17}];
polyArray [2] =[{x:510,y:300}, {x:510,y:200}, {x:715,y:113}, {x:780,y:200}, {x:780,y:485}, {x:625,y:468}, {x:605,y:456}, {x:605,y:428}];
polyArray [3] =[{x:0,y:446}, {x:284,y:320}, {x:255,y:540}, {x:240,y:566}, {x:73,y:600}, {x:0,y:565}];
polyArray [4] =[{x:355,y:305}, {x:510,y:305}, {x:604,y:423}, {x:604,y:460}, {x:628,y:484}, {x:610,y:513}, {x:587,y:468}, {x:537,y:426}, {x:500,y:400}, {x:447,y:424}, {x:312,y:365}, {x:307,y:314 }];
polyArray [5] =[{x:350,y:425}, {x:415,y:421}, {x:455,y:434}, {x:495,y:411}, {x:550,y:444}, {x:618,y:590}, {x:570,y:616}, {x:359,y:597}, {x:333,y:522}];
// call the function to draw all the objects in the array
define(polyArray);
// call through the array to draw the objects
function define(polygon) {
ctx.beginPath();
for (var i = 0; i < polygon.length; i++) {
ctx.moveTo(polygon[i][0].x, polygon[i][0].y);
for (var j = 1; j < polygon[i].length; j++) {
ctx.lineTo(polygon[i][j].x, polygon[i][j].y);
}
ctx.fill();
}
ctx.closePath();
}
function hitTest(polygon) {
// redefine the polygon
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(polyArray);
if (isInside) {
canvas.style.cursor = 'pointer';
$results.text("Mouse is inside the area);
} else {
canvas.style.cursor = 'default';
$results.text("Outside");
}
}
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
检测该对象已被悬停。需要发生什么是悬停的一个阵列形状应该影响一些CSS/JS。我如何分配ID变量并检测它?
当我将响应式设计带入方程时,我有点卡住了如何合并这个偏移量和聚合度来适当缩放。
任何一点在正确的方向将不胜感激。
答
问题1:获取准确的鼠标的位置,画布移动
当你移动画布(FEX:margin: 0 auto
)后,必须重新计算offsetX
和offsetY
值:
如果手动更改canvas元素的CSS(fex:canvas.style.margin='50px'
里面的JavaScript),那么你还必须手动调用reOffset()
。
// cache the canvas's offset positions since the
// offset positions are used often
var offsetX,offsetY;
// call this once at the beginning of your app
// and whenever you change the canvas's position on the page
// (eg call when you change margins, scroll, etc)
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
// have the browser auto-reset offsetX & offsetX when
// the viewport scrolls or resizes
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
问题#2检测悬停&模糊了你的多边形
你hitTest
功能将测试如果鼠标是目前指定的多边形内部。因此,在handleMousemove
内,您可以拨打hitText
获取polyArray
中的每个多边形。
保留一个标志变量,指出鼠标最后一个多边形的索引号(或-1,表示鼠标位于所有多边形之外)当您的标志变量值更改时,您知道已经存在悬停事件或模糊的事件。比较过去和当前的标志变量来确定哪些多边形正在徘徊或模糊。
问题3包含一个响应式设计
鼠标坐标浏览器上报到e.clientX
和e.clientY
总是处于相对于浏览器视口的非缩放值
所以,如果你:
- 点击鼠标和使用e.clientX/E。clientY来确定鼠标是在[100,100],
- Scale的帆布:context.scale(2,2),
- 并且在不偏离其原始[100100]位置移动鼠标reclick,
然后:
使用e.clientX/e.clientY检测鼠标坐标,即使画布已缩放并且鼠标相对于缩放画布的[200,200]仍将报告位置为[100,100] 。
的修复:
您必须调整浏览器的报告的鼠标位置相匹配的画布的比例因子:
// Determine how much you want to scale the canvas
var scaleFactor=2.00;
// scale the canvas
context.scale(scaleFactor,scaleFactor);
// also scale the mouse position reported by the browser
mouseX=parseInt(e.clientX-offsetX)*scaleFactor;
mouseY=parseInt(e.clientY-offsetY)*scaleFactor;
稻田,你有没有得到这工作了你一个答案?想分享并帮助他人吗? – Mawg