gpt4 book ai didi

javascript - 使用 isPointInPath() 和响应式设计的多 Canvas 多边形检测图

转载 作者:行者123 更新时间:2023-11-28 01:31:50 26 4
gpt4 key购买 nike

我有一组可以正确绘制的 Canvas 对象。我有三个问题:

  1. 抵消。我已经在 J​​S fiddle 中测试了下面的代码并且它可以工作,但是当我将它导出到我的网页时,变量会出现偏差。检测发生,但不在正确的位置。页面宽度在 CSS 中设置,实际 Canvas 区域使用 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. 当我将响应式设计引入等式时,我对如何合并此偏移量和多边形坐标以适当缩放感到有点困惑。

任何指向正确方向的观点都将不胜感激。

最佳答案

问题#1: Canvas 移动后获取准确的鼠标位置

每当您移动 Canvas 时(fex:margin:0 auto),您必须重新计算您的offsetXoffsetY 值:

如果您手动更改 Canvas 元素的 CSS(fex:canvas.style.margin='50px' inside 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 中,您可以为 polyArray 中的每个多边形调用 hitText

保留一个标志变量,指示鼠标所在的最后一个多边形的索引号(或 -1 以指示鼠标在所有多边形之外。当您的标志变量值更改时,您知道有悬停事件或一个模糊事件。比较最后一个和当前的标志变量以确定哪个多边形现在悬停或模糊。

问题 #3 结合响应式设计

浏览器报告到 e.clientXe.clientY 中的鼠标坐标始终是相对于浏览器视口(viewport)的未缩放值。

所以如果你:

  • 点击鼠标,使用e.clientX/e.clientY判断鼠标在[100,100],
  • 缩放 Canvas :context.scale(2,2),
  • 然后在不将鼠标从其原始 [100,100] 位置移动的情况下重新单击,

然后:

使用 e.clientX/e.clientY 检测鼠标坐标仍会报告位置为 [100,100],即使 Canvas 已缩放并且鼠标相对于缩放后的 Canvas 位于 [200,200] 处.

修复:

您必须缩放浏览器报告的鼠标位置以匹配 Canvas 的缩放因子:

// 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;

关于javascript - 使用 isPointInPath() 和响应式设计的多 Canvas 多边形检测图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30030027/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com