使用isPointInPath()和响应式设计的多画布多边形检测映射

问题描述:

我有一个正确绘制的画布对象数组。我有三个问题:使用isPointInPath()和响应式设计的多画布多边形检测映射

  1. 偏移。我已经在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); 
}); 
  1. 检测该对象已被悬停。需要发生什么是悬停的一个阵列形状应该影响一些CSS/JS。我如何分配ID变量并检测它?

  2. 当我将响应式设计带入方程时,我有点卡住了如何合并这个偏移量和聚合度来适当缩放。

  3. 任何一点在正确的方向将不胜感激。

开始=>
+0

稻田,你有没有得到这工作了你一个答案?想分享并帮助他人吗? – Mawg

问题1:获取准确的鼠标的位置,画布移动

当你移动画布(FEX:margin: 0 auto)后,必须重新计算offsetXoffsetY值:

如果手动更改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.clientXe.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;