2014-02-20 73 views
1

我在HTML5畫布上使用clearRect重繪一個矩形。當使用浮點座標時,clearRect在畫布上留下矩形的邊框。當使用浮點座標時,JavaScript canvas clearRect留下邊框

以下代碼演示了使用浮點的邊框完全清除時使用整數座標的矩形的問題。

<html> 
<head> 
</head> 
<body> 
<script type="text/javascript" > 

var canvas = document.createElement("canvas"); 
canvas.width = 100; 
canvas.height = 100; 
canvas.style.border = "1px solid"; 
document.body.appendChild(canvas); 
var ctx = canvas.getContext("2d"); 
ctx.fillRect(20.1,20.1,30,30); 
ctx.clearRect(20.1,20.1,30,30); 

ctx.fillRect(50,50,30,30); 
ctx.clearRect(50,50,30,30); 

</script> 
</body> 
</html> 

所得畫布看起來像這樣: clearRect example

我可以通過清除更大區域解決這個問題,但是增加清除和重新繪製相鄰形狀的風險。這是例如在這裏建議:I can't completely clear the transformed rectangle in <canvas>

我可以通過使用整數座標來修復它,但這不是在此應用程序中的一個選項。

是否有其他方法可以使clearRect實際清除所有繪製的矩形而不清除更大的區域或使用整數座標?

+0

好了,我看到了我完全是幾乎一樣令人困惑的通知:-)你能不能詳細闡述「那在這個應用程序中不是一個選項'?爲什麼你不能限制座標總是+ 0.5? – GameAlchemist

+0

我在使用浮點座標和大小的應用程序中使用第三方物理引擎(box2dweb)。但是,我當然可以在繪圖時圍繞座標。我認爲這樣做看起來很奇怪,因爲形狀比他們應該分開的距離更遠。但是我應該在解僱之前嘗試一下,看看沒有其他很好的選擇。 –

+0

也許這就是你的意思,但不要在繪圖時座標「圓形座標」。否則,發動機會迷路。看到我的帖子的結尾。我想知道:你爲什麼要刪除給定的矩形? – GameAlchemist

回答

4

畫布中的所有點實際上都以它們的中間座標(0.5,0.5)爲中心。
如果要繪製一個像素厚的黑線,則必須使用居中座標繪製它。
如果你畫一個整數邊界上,你會在事實上繪製兩條像素粗線都與較低的不透明度,導致暗灰色而不是黑色畫出較粗的線:

這裏有一張顯示這一點,放大3倍:

enter image description here

更一般地,關閉0.5邊界任何座標將被與正比於它到中部點的距離的不透明度繪製。
這裏的一個組開始的整數邊界上的水平線段,則偏移1/10的像素的每20個像素:

enter image description here

放大4次:
enter image description here

我們可以看到我們確實只有居中時纔有1個像素線。

對於你的問題,你沒有辦法「部分」清除一個像素:像素是這裏的最終單位,因爲顏色已經混合,你只能清除整個像素,或者只是減弱其強度(這是你看到的結果)。

我能想到的兩種解決方案:

  • 而不是清除,重繪除非你不想要更多的東西應有盡有。爲此,您必須處理某種場景圖形,這意味着:您需要收集所有需要繪製的對象(例如,在數組中),並在繪製時刪除所有內容,重繪除矩形之外的所有對象。

  • 處理場景後面的一個更大的畫布,這將具有比用戶畫布更高的分辨率。這是您繪製的,質量更好,繪製後將其複製到低分辨率用戶畫布。 在整數大小(例如,寬度/高度)的0.5邊界上繪製。這個主要畫布可能是4或8倍大。畫布的最大尺寸是有限的,所以如果你瞄準所有的瀏覽器,注意這一點,它們並不都允許相同的最大尺寸(6400X6400以下應該沒問題,但不確定)。您可以處理多個後臺畫布以超出此限制,並有一些額外的工作。

(對於解決方案2的Rq:確保在複製之前禁用圖像平滑以避免失真)。

((在圖中的小提琴是在這裏:jsbin.com/xucuxoxo/1/))

編輯:這是一個很好的做法,從翻譯(0.5 0.5)上下文之後,你創造了它。然後你將總是繪製整數座標。通過這種方式,您可以確保所有1像素粗線實際上將繪製一個像素厚度。測試與地板或小屋四捨五入,並選擇你喜歡的。

+0

爲什麼現在圖像不見了?他們似乎沒有爲我顯示。我試過清爽。 – raddevus

3

Html canvas始終將抗鋸齒應用於「治癒鋸齒」。

消除鋸齒通過在線上添加半透明像素來視覺上平滑線條,因此眼睛被愚弄而看到鋸齒狀的線條。

繪製矩形時,這些半透明像素將自動應用於矩形的30,30區域之外。

這意味着您的30x30矩形實際上略大於30x30。

當你做context.clearRect瀏覽器不清除這些額外的半透明像素。

這就是爲什麼未清晰的像素出現「幽靈般」 - 它們是半透明的。

不幸的是,目前沒有辦法關閉HTML畫布原始繪圖(線條等)的抗鋸齒功能。

你已經發現了2個最快的解決方案:

  • 輪像素繪製座標整數
  • 明確的面積比原來的圖紙稍大

您可以通過無抗混疊畫使用getImageData/putImageData手動繪製像素。這種手動方法的工作原理,但性能昂貴。性能下降不利於清理繪製區域的目的。

底線:你已經發現了最佳的解決方案帆布目前所提供的:-(

相關問題