I wanted to make a handler when hovering over a sector of a diagram, but in order not to make the canvas not render at all, here’s an approximate code:

window.onload = function() { var drawingCanvas = document.getElementById('chart1'); if(drawingCanvas && drawingCanvas.getContext) { var context = drawingCanvas.getContext('2d'); var size = drawingCanvas.height; var n = 5; //Число секторов var rad = 2/n*Math.PI; var start = 3*Math.PI/2; var r = size/2; var colorTable = ['#DC3912','#FF9900','#FFF804','#66AA00','#6BE5F3','#3366CC','#990099','#DD4477', '#DC3912','#FF9900','#FFF804','#66AA00','#6BE5F3','#3366CC','#990099','#DD4477']; for (var i = 1; i < n+1; i++) { //сектор context.fillStyle = colorTable[i-1]; context.beginPath(); context.moveTo(drawingCanvas.height/2, drawingCanvas.width/2); context.arc(drawingCanvas.height/2, drawingCanvas.width/2,size/2/100*80,start+rad*(i-1),start+rad*i,false); context.closePath(); context.fill(); } // пишем текст context.fillStyle = '#ffffff'; context.font = '20pt Tahoma'; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillText(text, r,r); //context.onmousemove = mousemove; // Функция вызываемая в момент когда курсор перемещается в облости холста setInterval(function(){ function mousemove(evt) { var mouseX = evt.pageX - context.offsetLeft; var mouseY = evt.pageY - context.offsetTop; for (var i = 1; i < n+1; i++) { var a1 = start+rad*(i-1); var a2 = start+rad*i; if((mouseX-r)*(mouseX-r)+(mouseY-r)*(mouseY-r)<r*r && mouseY>Math.tan(a1)*mouseX+r && mouseY>Math.tan(a2)*mouseX+r){ text = i; } } }},1000 / 60); 

}}

And the canvas itself: <canvas id = 'chart1' width = '316' height = '316'> </ canvas>

I want to understand myself without the use of frameworks.

  • @Kirill Turovnikov huge chunks of code are very undesirable to throw off the question, better cut the most important. - lampa
  • @ Kirill Turovnikov is so better) - lampa
  • Yes, the code is crookedly inserted first, already corrected. - Straj

2 answers 2

Hold on, comrade!

I didn’t understand how you wanted to look for a point in the sector and therefore altered the main mechanism:

 <script> window.onload = function() { var drawingCanvas = document.getElementById('chart1'); if(drawingCanvas && drawingCanvas.getContext) { var context = drawingCanvas.getContext('2d'); var size = drawingCanvas.height; var n = 5; //Число секторов var rad = 2/n*Math.PI; var start = -.5 * Math.PI; var r = centreX = centreY = size/2; var colorTable = ['#DC3912','#FF9900','#FFF804','#66AA00','#6BE5F3','#3366CC','#990099','#DD4477', '#DC3912','#FF9900','#FFF804','#66AA00','#6BE5F3','#3366CC','#990099','#DD4477']; for (var i = 1; i < n+1; i++) { //сектор context.fillStyle = colorTable[i-1]; context.beginPath(); context.moveTo(r, r); context.arc(r, r, r, start+rad*(i-1),start+rad*i,false); context.closePath(); context.fill(); } text = 'текст'; // пишем текст context.fillStyle = '#ffffff'; context.font = '20pt Tahoma'; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillText(text, r,r); drawingCanvas.onmousemove = function(evt) { var mouseX = evt.pageX - drawingCanvas.offsetLeft; var mouseY = evt.pageY - drawingCanvas.offsetTop; var xFromCentre = mouseX - centreX; var yFromCentre = mouseY - centreY; // теорема пифагора) var distanceFromCentre = Math.sqrt( Math.pow( Math.abs( xFromCentre ), 2) + Math.pow( Math.abs( yFromCentre ), 2)); if(distanceFromCentre > r) return; // угол относительно центра (начинаем с 12 часов) var clickAngle = Math.atan2(yFromCentre, xFromCentre) - start; if ( clickAngle < 0 ) clickAngle = 2 * Math.PI + clickAngle; clickAngle = clickAngle + start; // небольшой хак for (var i = 1; i < n+1; i++) { if(clickAngle >= start+rad*(i-1) && clickAngle <= start+rad*i) { console.log(i); } } } } } </script> <canvas id='chart1' width='316' height='316'></canvas> 

The whole point comes down to the fact that we need to determine the angle of rotation of the point (mouse) relative to the center of the circle and check which sector this point belongs to, i.e. from the sector start point to the sector end point.

Often such questions regarding the canvas :)

  • Thank you, it works :) I just determined that I belonged to a region in the condition of 3 equations: lines and circles, apparently I was mistaken about something, because I did not see the result of the script. Yes, and canvas with js was little involved, and then there was a need for dynamic construction of a number of diagrams. - Straj
  • @ Kirill Turovnikov make debugging using the console (ctrl_shift + k / j / i) and the [console.log ()] [1] [1] method: developer.mozilla.org/en-US/docs/Web/API/console .log - lampa pm
  • Yes, I already understood, I came across this myself, and then I did not realize - Straj

First, you don't need to call the mousemove function every mousemove milliseconds there. It should be the onmousemove event onmousemove your canvas . I see that you tried to do this, but you made a mistake: the handler needs to be hung not at the context , but at the drawingCanvas .

Secondly, every time you draw something on canvas , a new image is superimposed on the previous one, so you need to redraw the image (or part of it). That is, every time you draw an inscription on the mousemove , you must first redraw the diagram, otherwise the next inscription will overlap with the previous one.

Thirdly, the text variable is not declared and initialized anywhere in your system, so your script will crash in the context.fillText(text, r,r); . In this regard, the advice is to look at the console output in the developer’s tools of your browser (in Chrome, for example, you can call them using the F12 button, in Firefox it’s better to install Firebug), a lot of useful information is written there for debugging.

Fourth, you have something wrong with determining which sector the cursor has hit. After correcting all previous errors, the number 4 is persistently displayed.