2011-11-18 98 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