How to select lines that are drawn on HTML5 canvas?

I use HTML5 Canvas to draw lines. One line is formed by calling drawLine () at several intermediate points. For instance:

(10) → (10, 5) → (20, 12)

will be displayed as one line on the chart.

All (x, y) line coordinates are stored in an array.

I want to give users the ability to select a row when it clicks on it. This is difficult to do in HTML5 Canvas because the string is not represented by an object. The only option I stay with is to first find the coordinate (x, y) of any line that is closest to the (x, y) of the mousedown event. As soon as I determine which line is selected by the user, I need to redraw the line with bold color or put a translucent color around it. But I suppose this will be too time consuming since it involves a loop over all (x, y) coordinates of all the lines.

I am looking for ways to help me achieve the above more effectively. Should I use SVG in HTML5?

Any suggestions would be appreciated.

+4
source share
3 answers

The easiest way to do this in HTML5 canvas is to take a snapshot of the image data for the canvas, and during mousemove look at the alpha color in the pixel under the mouse.

I will give a working example of this on my website here:
http://phrogz.net/tmp/canvas_detect_mouseover.html

Here is the kernel code I wrote. Pass it the context and the function and it will call your function with the RGBA components under the pixel.

function pixelOnMouseOver(ctx,callback){ var canvas = ctx.canvas; var w = canvas.width, h=canvas.height; var data = ctx.getImageData(0,0,w,h).data; canvas.addEventListener('mousemove',function(e){ var idx = (e.offsetY*w + e.offsetX)*4; var parts = Array.prototype.slice.call(data,idx,idx+4); callback.apply(ctx,parts); },false); } 

And here is how it is used on this test page:

 var wasOver; pixelOnMouseOver(ctx,function(r,g,b,a){ var isOver = a > 10; // arbitrary threshold if (isOver != wasOver){ can.style.backgroundColor = isOver ? '#ff6' : ''; wasOver = isOver; } out.innerHTML = "r:"+r+", g:"+g+", b:"+b+", a:"+a; }); 
+6
source

I think you will find this much easier in SVG. There, each line will be <polyline> , and you can add an onclick handler to do what you want. For instance...

 <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <polyline points="20,20 40,25 60,40 80,120 120,140 200,180" style="fill:none;stroke:black;stroke-width:5" onclick="this.style.stroke='red'" /> </svg> 
+4
source

The only way to do this on the canvas is to detect the pixel color and follow the path or save the path as objects and detect a click on that path.

+1
source

Source: https://habr.com/ru/post/1381922/


All Articles