如何检查鼠标点击是否位于JavaScript中HTML5画布上的旋转文本内
How do I check if a mouse click is inside a rotated text on the HTML5 Canvas in JavaScript?
我在画布上绘制了一个坐标为X、Y的文本并保存了它们。我有一个简单的方法,可以检查鼠标是否在文本边界内点击。问题是,当我将文本旋转45度时,我无法检查旋转后的文本中是否发生了鼠标单击。
简而言之,如何检查鼠标单击是否在旋转的文本或形状内?
创建一个矩形对象,该对象以与文本相同的角度旋转,但不绘制。
然后使用:
// set transforms here.
// add rect representing text region:
ctx.beginPath();
ctx.rect(x, y, w, h); // region for text
if (ctx.isPointInPath(mx, my)) {
// we clicked inside the region
}
ctx.setTransform(1,0,0,1,0,0); // reset transforms after test
演示:
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d"),
txt = "ROTATED TEXT", tw, region;
// transform and draw some rotated text:
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = "32px sans-serif";
ctx.translate(150, 75);
ctx.rotate(0.33);
ctx.translate(-150, -75);
ctx.fillText(txt, 150, 75);
tw = ctx.measureText(txt).width;
// define a region for text:
region = {x: 150 - tw*0.5, y: 75 - 16, w: tw, h:32}; // approx. text region
// function to check if mouse x/y is inside (transformed) region
function isInText(region, x, y) {
ctx.beginPath();
ctx.rect(region.x, region.y, region.w, region.h);
return ctx.isPointInPath(x, y);
}
// test for demo
canvas.onmousemove = function(e) {
var rect = canvas.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top;
// just to visualize:
ctx.clearRect(0,0,300,150);
ctx.fillStyle = isInText(region, x, y) ? "red" : "black";
ctx.fillText(txt, 150, 75);
};
<canvas></canvas>
请勿直接使用以下代码。在这里,我只想解释一下如何处理这类问题的逻辑。您可能需要根据您的问题编写代码,或者扩展此解决方案以适应您的问题
这更多的是一个数学问题,你必须找到一个点是否在旋转的矩形内(与@user1693593所说的相同)您可以找到一个覆盖文本的矩形(rect(x1:text.x1,y1:text.y1,x2:text.x2,y2:text.y2),假设(text.x1,text.y1)表示文本的左上角。现在将矩形绕其中心旋转θ角,得到x1,y1,x2,y2:
假设所有角度计算都将在+ve个角度内进行。
if theta < 0 then theta = (360 - abs(theta))
现在计算中心点和点(x2,y2)之间的角度(从中心到矩形的任何一个角的角度都是相同的,我们正在计算(x2,y2),因为它会给我们正的角度)
var width = (x2-x1);
var height = (y2-y1)
var hypotenuse = Math.pow(width*width + height*height, 0.5);
var innerAngle = Math.acos(x2 - x2 / hypotenuse);
现在从中心计算角的最终角度
(x1, y1), angle((Math.PI + baseAngle) + angle) %(Math.PI*2)
(x2, y1), angle((Math.PI*2) - baseAngle + angle) % (Math.PI*2)}
(x1, y2), angle((Math.PI - baseAngle) + angle) % (Math.PI*2)}
(x2, y2), angle(baseAngle + angle) % (Math.PI*2)}
现在找出矩形的旋转点:
point.x = centre.x + (hypotenuse * Math.cos(point.angle));
point.y = centre.y + (hypotenuse * Math.sin(point.angle));
旋转点后,它们的顺序可能会发生变化,以确保正确的顺序根据x轴对它们进行排序,如果两个点的x轴相同,则根据y轴对它们排序(使用任何排序)现在我们得到了排序的分数。根据它们的位置p0、p1、p2、p3命名从这些点找到旋转矩形的新边界,找到x方向和y方向的边界:
var boundary_x1 = ( (p1.x - p0.x) / (p1.y - p0.y) ) * (mousePos.y - p0.y) + p0.x;
var boundary_x2 = ( (p3.x - p2.x) / (p3.y - p2.y) ) * (mousePos.y - p2.y) + p2.x;
var boundary_y1 = ( (p2.y - p0.y) / (p2.x - p0.x)) * (mousePos.x - p0.x) + p0.y;
var boundary_y2 = ( (p3.y - p1.y) / (p3.x - p1.x)) * (mousePos.x - p1.x) + p1.y;
在得到x和y方向上的边界点后,我们可以很容易地设置中点条件,并可以找到一个点(鼠标点)是否在rect中点击:
var clickedInside = (mousePos.x > boundary_x1 && mousePos.x < boundary_x2) && (mousePos.y > boundary_y1 && mousePos.y < boundary_y2);
如果clickedInside为true,则鼠标单击发生在rect 内部
- 下载HTML5/Javascript MOBILE应用程序中的PDF文件
- 是否可以使用HTML5/javascript播放此流
- 条形图元素的HTML5 JavaScript锚点
- Teechart HTML5/Javascript价值股票代码将保留在Tee.Line系列上
- 如果按下两个不同的键,如何使事件发生(HTML5 Javascript)
- HTML5/JavaScript图像点击事件
- 对象数组上的html5 javascript冲突
- 显示/隐藏 选择 HTML5 JavaScript
- HTML5 & Javascript
- Windows 8 HTML5 JavaScript 应用程序中向左滑动的事件名称是什么
- HTML5/JavaScript.使用索引数据库时无法插入数据
- 如何在HTML5 / javascript中查找十六进制值的特定位或数字
- 当以表单形式提交时,是否可以在PHP中访问新的数据* HTML5 / Javascript值?
- HTML5 Javascript播放/暂停按钮
- 如何使用HTML5/JavaScript检查连接类型(WiFi/LAN/WWAN)
- HTML5/Javascript验证复选框提交URL重定向
- 如何防止使用HTML5/Javascript在长触摸/点击时选择画布
- HTML5/JavaScript游戏-编辑JS代码以更改AJAX请求
- HTML5+Javascript音频在音频播放的特定时间触发事件
- html5 javascript,全局变量