Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何检测画布中的元素?_Javascript_Html5 Canvas - Fatal编程技术网

Javascript 如何检测画布中的元素?

Javascript 如何检测画布中的元素?,javascript,html5-canvas,Javascript,Html5 Canvas,我试图检测画布中绘制的元素(例如:饼图中的每个切片),以便稍后在其上放置一个单击事件,但这似乎不是一项容易的任务,我认为数学将是执行该任务的最佳方式,但我应该从何处开始 请帮我找到解决办法 以下是演示: 代码是: <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #

我试图检测画布中绘制的元素(例如:饼图中的每个切片),以便稍后在其上放置一个单击事件,但这似乎不是一项容易的任务,我认为数学将是执行该任务的最佳方式,但我应该从何处开始

请帮我找到解决办法

以下是演示:

代码是:

    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
      #myCanvas{
            width: 50%;
            height: 50%;
        }
    </style>
    </head>
    <body>
     <canvas id="myCanvas"></canvas>
    </body>
    </html>

    class Piechart{
    constructor(){
      this.options = arguments[0];
      this.canvas = arguments[0].canvas;
      this.ctx = this.canvas.getContext('2d');
      if(this.options.colors){
        this.colors = arguments[0].colors;
      }
      else if (!this.options.colors){
        this.colors = [
          "#fde23e",
          "#f16e23",
          "#57d9ff",
          "#937e88",
          '#2fe678',
          '#228888',
          '#b111c1'
        ];
      }
      this.donut_hole = 0.5;
    }

    drawPie(){
      var total_value = 0;
      var color_index = 0;
      for(var categ in this.options.data){
        var val = this.options.data[categ];
        total_value += val;
      }

      var start_angle = 0;
      for(var categ in this.options.data){
        var val = this.options.data[categ];
        var slice_angle = 2*Math.PI*val/total_value;

        this.drawPieSlice(
          this.ctx,
          this.canvas.width/2,
          this.canvas.height/2,
          Math.min(this.canvas.width/2,this.canvas.height/2),
          start_angle,
          start_angle+slice_angle,
          this.colors[color_index%this.colors.length]
        );

        start_angle += slice_angle;
        color_index++;
      }
    }

    drawPieSlice(){
      arguments[0].fillStyle = arguments[6];
      arguments[0].beginPath();
      arguments[0].moveTo(arguments[1],arguments[2]);
      arguments[0].arc(
      arguments[1],
      arguments[2],
      arguments[3],
      arguments[4],
      arguments[5]
    );
    arguments[0].closePath();
    arguments[0].fill();
    }
  }

var myCanvas = document.getElementById("myCanvas");
var myCanvas_width = myCanvas.scrollWidth;
var myCanvas_height = myCanvas.scrollHeight;

myCanvas.width = myCanvas_width;
myCanvas.height = myCanvas_height;

var myVinyls = {
 'Classical music':10,
 'Rock':14,
 'Pop':15,
 'Jazz':4,
 'test':6,
 'test_1':7,
 'test_2':8
};

var myPiechart = new Piechart(
 {
  canvas:myCanvas,
  data:myVinyls,
  colors:[
   "#fde23e",
   "#f16e23",
   "#57d9ff",
   "#937e88",
   '#2fe678',
   '#228888',
   '#b111c1'
  ]
 }
);
myPiechart.drawPie();

文件
#我的画布{
宽度:50%;
身高:50%;
}
班级图表{
构造函数(){
this.options=参数[0];
this.canvas=参数[0]。canvas;
this.ctx=this.canvas.getContext('2d');
if(this.options.colors){
this.colors=参数[0]。颜色;
}
否则如果(!this.options.colors){
此项。颜色=[
“#fde23e”,
“#f16e23”,
“#57d9ff”,
“937e88”,
"2fe678",,
'#228888',
"b111c1"
];
}
这个.donut_孔=0.5;
}
drawPie(){
var总价值=0;
var颜色指数=0;
for(此.options.data中的变量类别){
var val=this.options.data[categ];
总_值+=val;
}
var起始角=0;
for(此.options.data中的变量类别){
var val=this.options.data[categ];
var slice_angle=2*Math.PI*val/总_值;
这是一片(
这个.ctx,
此.canvas.width/2,
此.canvas.height/2,
Math.min(this.canvas.width/2,this.canvas.height/2),
起始角,
起始角度+切片角度,
this.colors[颜色索引%this.colors.length]
);
开始角度+=切片角度;
颜色指数++;
}
}
DrawpieSicle(){
参数[0]。fillStyle=参数[6];
参数[0]。beginPath();
参数[0]。移动到(参数[1],参数[2]);
参数[0]。弧(
论点[1],
论点[2],
论点[3],
论点[4],
论点[5]
);
参数[0]。closePath();
参数[0]。填充();
}
}
var myCanvas=document.getElementById(“myCanvas”);
var myCanvas_width=myCanvas.scrollWidth;
var myCanvas_height=myCanvas.scrollHeight;
myCanvas.width=myCanvas\u width;
myCanvas.height=myCanvas\u height;
var myVinyls={
“古典音乐”:10,
"摇滚":14,,
流行音乐:15,
《爵士乐》:4,
"测试":6,,
“测试1”:7,
“测试2”:8
};
var myPiechart=新Piechart(
{
画布:我的画布,
数据:myVinyls,
颜色:[
“#fde23e”,
“#f16e23”,
“#57d9ff”,
“937e88”,
"2fe678",,
'#228888',
"b111c1"
]
}
);
myPiechart.drawPie();
如何能够检测每个切片?多谢各位

编辑

为了在画布中添加命中区域,我找到了一个惊人的解决方案,下面是链接:

首先,画布上没有任何元素,您应该理解这一点。这是一个二维平面,在这里,物体刚刚被绘制出来,如果你想移动物体,你需要完全重新绘制它们

这就是说,让我们回到原来的问题。
因为您在画布中创建了“对象”,所以您知道对象的大小和距离,您应该将其保存在一些js对象中以备将来使用。
在这种情况下,我要做的是让一个对象保存所有其他对象的数据,这样当你点击画布时,你可以点击
x和y
,并确定它们是否大于或等于任何对象的
x
s和
y
s 一个示例算法是

if click.X>elem.X && click.X<elem.X+elem.Width
 {
    x is in check the same for y
 }
if x__in&&y__in
  {
    you clicked the element
  }

如果click.X>elem.X&&click.XCanvas只是位图,那么画在上面的任何东西都不是单独的对象。您需要存储绘制的每个元素的大小及其x/y位置,并将任何单击与这些坐标进行比较。或者,也可以使用SVG而不是画布,这样您就有了实际的独立元素,可以单击、添加事件、设置样式等。感谢您的评论,我知道SVG更适合事件,因为它们是DOM中的元素,但画布在性能上更优。所以我试着用画布来做。谢谢你的回答,是的,当我说元素时,我指的是形状。现在要得到画布中点击点的x和y(坐标),我应该从偏移坐标中减去高度或宽度,对吗?或者还有其他更简单的方法?您可以将其与elem x和y进行比较,例如单击.x>elem.x&&click.x