2013-05-01 31 views
1

我正在寫一個JavaScript應用程序,它在HTML畫布上繪製任意形狀的對象。用戶應該能夠通過點擊選擇任何對象。HTML畫布:通過使用ghost畫布點擊鼠標點擊測試 - 消除鋸齒問題

爲了使這是一個O(1)操作,我使用了一個陰影畫布,即一個沒有顯示的大小完全相同的畫布,其中繪製在普通畫布上的每個對象也繪製在那裏 - 但是使用顏色代表它是ID
因此,一個簡單的ghostContex.getImageData()連同鼠標點擊座標爲我提供了該像素的顏色,因此也爲點擊對象的顏色提供了ID

所有這一切都工作正常 - 除了當我點擊一個對象的確切邊界。

,因爲它是與鬼畫布,我得到一個錯誤的顏色(如顏色是正確的ID和那是以前畫下它的對象的ID ...之間的混合物)抗鋸齒繪製。這種錯誤的顏色是代表一個錯誤ID,因此我選擇了完全不同的對象:(

我該如何解決這個問題

注意1:我已經使用的翻譯(0.5,0.5 )技巧來防止大多數反鋸齒
注意#2:我之前試圖用SVG編寫這個應用程序,但特別是這個對象的選擇非常慢,因爲我猜它是碰撞檢測的對象太多了,這是主要原因爲什麼我現在需要一個O(1)方法......哦,這樣我就可以輕鬆地在鬼畫布上畫出比線條畫在正常畫布上更大的線條,使拾取更容易。 ote#3:相關瀏覽器是Firefox,Chrome,Android 2.3+本機和iOS本機

回答

1

爲什麼我不能在這裏接受任何答案的原因是很容易的,挺傷心的:它不存在... :(

抗混疊不能切換,標準有沒有一種方法但是這個標準確實有一個命中測試功能(http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas_CR/#hit-regions),它可以完成這裏所需要的功能,即使以一種很好的方式來隱藏開發人員的討厭細節 - 但它現在還沒有在任何瀏覽器中實現。
實施期待已久,直到不可能(例如見評論#6 https://code.google.com/p/chromium/issues/detail?id=328961)。但顯然它在上個月獲得了動力...

那麼在同一時間可以做些什麼呢?我做了什麼?

在我的代碼中,我可以爲每個形狀實現一個isPointInShape()方法。所以我用幽靈帆布技巧得到一個形狀,並用isPointInShape()驗證我確實選擇了正確的形狀。這有助於防鋸齒像素不會選擇錯誤的形狀(只需單擊2號形狀的邊框即可獲得50%的抗鋸齒透明度 - 這會告訴您錯誤地選擇了1號形狀...)。

如果實現一個通用isPointInShape()是挺難爲你的形狀,你可以嘗試一招,我正在讀的其他地方(我沒有嘗試艱難的,所以我沒有測試它...):
創建一個尺寸爲1x1像素的附加虛影畫布,該畫布完全位於鼠標位置。然後繪製感興趣的形狀 - 當RGBA的A被改變時,該形狀確實屬於該像素。

0

我製作了名稱ghost的上下文!你在使用我的老教程嗎? :)

在那個老的教程中,我沒有清楚每個對象被繪製到它後的幽靈上下文。在你的情況下,爲了解決你的問題,你可能需要在幽靈環境中測試每個對象之後清除。

當然,確保您正在以相同的數量轉換幻影背景和正常背景。 (並將它們翻譯回來,或重新設置轉換,之後)。

+0

有時候,我對使用隱藏畫布(可能在某處讀取)的想法感到沮喪,因爲我可以使用隱藏畫布。那是幾個月前的事。現在我重新開始努力,並在我研究網絡的反鋸齒問題中實現它 - 當然,我偶然發現了你的舊教程。所以我得到了(至少?)如何從那裏命名 - 謝謝! – Chris 2013-05-01 17:51:29

0

我知道這是一箇舊帖子,但最近我有一個類似的問題。我解決「雙色縫」問題的方法是對輔助畫布進行10x10像素取樣,而不是單個像素。然後,我將RGB值串化並將它們用作映射到顏色表示的對象的映射中的鍵。因此,最初使用1像素採樣時,我立即使用地圖來確定關聯的對象,但是抗鋸齒創建了地圖中不存在的中途顏色。 10x10方法通過循環返回100個RGB值並創建一個「計數圖」來解決這個問題。此地圖使用字符串化的顏色並將其映射到計數,但僅包括計數中第一張地圖的有效顏色。所以你最終得到一張地圖,說你計算了65個紅色像素和23個藍色像素(其餘12個像素是一些奇怪的反混疊混合)。在我計算顏色的同一個循環中,我還爲當前的最大計數和與最大計數相關的當前顏色保留了一個變量(以避免再次循環通過此新地圖)。現在,最終你有10x10個採樣中被計數最多的顏色,並且可以使用該顏色映射回與之關聯的對象。如果在10x10樣本中沒有找到有效的顏色,您可以合理地認爲這意味着點擊了「背景」,您將只會得到未定義的結果。