gpt4 book ai didi

javascript - 如何在 Canvas 上使用多次点击事件

转载 作者:搜寻专家 更新时间:2023-10-31 08:40:47 25 4
gpt4 key购买 nike

我使用以下代码用 canvas 画了一个圆。

<div class="abc"><canvas id="myCanvas">HTML5 canvas tag.</canvas></div>
<script>

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(100,75,50,-0.1*Math.PI,1.7*Math.PI);
ctx.lineWidth = 15;
ctx.strokeStyle = "#c32020";
ctx.stroke();

var c2 = document.getElementById("myCanvas");
var ctx2 = c2.getContext("2d");
ctx2.beginPath();
ctx2.arc(100,75,50,1.7*Math.PI,-0.1*Math.PI);
ctx2.lineWidth = 15;
ctx2.strokeStyle = "#a9a9a9";
ctx2.stroke();

</script>

这是网络浏览器上的结果。

enter image description here

现在我需要在用户点击圆圈的红色部分和灰色部分时调用两个不同的 javascript function

点击红色部分应该调用function1,点击灰色部分应该调用function2

我尝试了很多,但没有成功。我需要一些专家的帮助来实现它。

最佳答案

让浏览器完成(大部分)工作

On click of the red part it should call function1 and on click of gray part, it should call function2.

您可以使用可重复使用的路径对象来存储要测试的不同路径,然后使用 isPointInPath()以路径和坐标作为参数。

通过检查每个路径的命中,您可以根据索引分配不同的调用。

而且没有必要这样做:

var c2 = document.getElementById("myCanvas");
var ctx2 = c2.getContext("2d");

这将简单地引用相同的上下文,因为 Canvas 只能有一个 - 如果多次请求,将给出相同的上下文(如果类型不同,则为 null)。

How to use multiple click event on a canvas

您可以共享点击处理程序来执行您想要的操作,如下所示 -

对于现代浏览器,您可以同时使用 Path2D对象来存储您以后要使用的路径信息(我将在第二个示例中解决较旧的浏览器)。

例子

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var p1 = new Path2D();
var p2 = new Path2D();
var paths = [p1, p2]; // store paths in array for check later

// store arc parts to respective path objects
p1.arc(100, 75, 50, -0.1 * Math.PI, 1.7 * Math.PI); // red part
p2.arc(100, 75, 50, 1.7 * Math.PI, -0.1 * Math.PI); // grey part

// render the two path objects using a common context, but different style
ctx.lineWidth = 15;

ctx.strokeStyle = "#c32020";
ctx.stroke(p1);

ctx.strokeStyle = "#a9a9a9";
ctx.stroke(p2);

// check for clicks on common canvas
c.onclick = function(e) {
var rect = this.getBoundingClientRect(), // adjust click coordinates
x = e.clientX - rect.left,
y = e.clientY - rect.top;

// iterate through path array to test each path for hits
for(var i = 0; i < paths.length; i++) {
if (ctx.isPointInStroke(paths[i], x, y)) { // check which path
console.log("Path " + (i+1) + " clicked");
break;
}
}
};
<canvas id="myCanvas"></canvas>

浏览器兼容性

但是,较旧的浏览器不支持 isPointInStroke(),例如 IE11。

对于这种情况,您可以使用简单的数学运算来确定点击是否在圆弧的半径范围内:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.lineWidth = 15;
ctx.arc(100, 75, 50, -0.1 * Math.PI, 1.7 * Math.PI); // red part
ctx.strokeStyle = "#c32020";
ctx.stroke();

ctx.beginPath();
ctx.arc(100, 75, 50, 1.7 * Math.PI, -0.1 * Math.PI); // grey part
ctx.strokeStyle = "#a9a9a9";
ctx.stroke();

// check for clicks on common canvas
c.onclick = function(e) {
var rect = this.getBoundingClientRect(), // adjust click coordinates
x = e.clientX - rect.left,
y = e.clientY - rect.top,
diffX = 100 - x,
diffY = 75 - y,
len = diffX*diffX + diffY*diffY, // we don't need to square-root it:
r1 = 43*43, // it's faster to scale up radius (50-50% of linewidth)
r2 = 57*57; // radius + 50% of linewidth

// are we on the edge of the circle?
if (len >= r1 && len <= r2) {
// now find angle to see if we're in red or grey area
var angle = Math.atan2(diffY, diffX);
if (angle > 0.7 * Math.PI && angle < 0.9 * Math.PI) {
console.log("Grey part");
}
else {
console.log("Red part");
}
}
};
<canvas id="myCanvas"></canvas>

请注意后一个示例中的特殊情况,即当圆弧穿过 0/360° 点时,您需要拆分检查 [0, angle> 和 [angle, 360>。

关于javascript - 如何在 Canvas 上使用多次点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45993483/

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