2011-11-18 63 views
4

我正在使用HTML5画布绘制线条。一条线是通过在多个中间点上调用drawLine()来形成的。例如:如何选择在HTML5 Canvas上绘制的线条?

(0,0) - >(10,10) - >(10,5) - >(20,12)

将显示为在图上一行。

一行的所有(x,y)坐标存储在一个数组中。

我想为用户提供在点击它时选择一条线的功能。在HTML5 Canvas中执行此操作变得困难,因为该行不是由对象表示的。我留下的唯一选择是首先找到与mousedown事件的(x,y)最接近的任何行的(x,y)坐标。一旦我检测到用户选择了哪条线,那么我需要用粗体颜色重新绘制线条或在其周围放上半透明的颜色。但是,我认为这会花费太多时间,因为它涉及到遍历所有行的所有(x,y)坐标。

我正在寻找可以帮助我以更省时的方式实现上述目标的方法。我应该考虑在HTML5中使用SVG吗?

任何建议,将不胜感激。

+0

指 http://stackoverflow.com/questions/27332603/select-and-change-color-of -a-line-in-html5-canvas/27336242#27336242 答案有更清晰 –

回答

5

在HTML5画布中完成此操作的最简单方法是拍摄画布图像数据的快照,并在鼠标移动过程中查看鼠标下像素的Alpha颜色。

我已经忍了这个工作的例子在我的网站在这里:
http://phrogz.net/tmp/canvas_detect_mouseover.html

这里的核心代码我写的。将它传递给一个上下文和一个函数,它将使用像素下的RGBA组件调用你的函数。

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); 
} 

这里就是它的那个测试页面上使用:

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; 
}); 
4

我想你会发现这在SVG中更容易。每条线都是<polyline>,您可以添加一个onclick处理程序来执行您想要的操作。例如...

<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> 
+0

谢谢你的回应,罗伯特。如果我知道预先绘制的行数,SVG方法将起作用。如果我让用户通过某个UI按钮动态创建一个新行,那么这种方法是否需要在每次创建行时都修改实际的SVG文件? – kkonweb

+2

是的,但这并不难,只需使用document.createElementNS(“http://www.w3.org/2000/svg”,“polyline”)创建一个新行。 –

1

在画布上执行此操作的唯一方法是检测像素颜色并按照路径或将路径保存为对象并检测该路径上的单击。

+0

请注意,对于填充路径,您还可以使用['ctx.isPointInPath(x,y)'](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element html的#DOM上下文-2D-ispointinpath)。 – Phrogz

+2

但不适用于线路 – austinbv

+0

正确;这就是为什么我首先添加了我自己的答案,显示了抚摸线的工作解决方案。 – Phrogz