2012-12-05 74 views
2

我正在用HTML5 canvas 2D上下文構建方格網格。我翻譯&縮放畫布,使網格廣場是一個單位的大小,但是30px,說,未轉換。 Here's an example 10px格子的30px正方形。縮放HTML5畫布中字體大小小於1

這工作正常,除了一件事:文本。

要指定適合正方形的畫布的字體,我需要指定小於1的字體大小。

例如,「.5px sans-serif」應爲平方尺寸的一半(即30px未轉換​​正方形的「15px sans-serif」)。這至少在Chrome中失敗了,並且畫布恢復爲更大的默認值。

我找到的唯一解決方案是在繪製文本時撤消畫布縮放,yuk!

有沒有辦法通過亞像素字體規格解決這個問題? (自然在轉換之後,字體將是一個理智的大字體,亞像素字體大小隻是相對於畫布轉換而言)

回答

1

字體大小設置爲0.5px意味着字體是半像素未轉換的。這不是一個規模值但是絕對值

因此,指定字體大小爲未縮放大小,縮放上下文,繪製tex t和網格,然後可以選擇刪除比例。

該演示將在行動中表現出這樣的:
Scale demo

的重要組成部分:

ctx.font = '15px sans-serif'; 
ctx.scale(1/30, 1/30); 
ctx.fillText('TEXT', 5, 5); 
ctx.strokeRect(0, 0, 30, 30); 

Example demo

這個例子將產生在左上角有個小點角。

+0

您可能更喜歡下面的save&ctx.setTransform(1,0,0,1,0,0),而不是等效的比例。 – backspaces

+0

@ backpaces保存/恢復在性能方面相當昂貴(因爲他們使用push/pop堆棧方法,並且他們保存/重新設置整個上下文的設置)。 setTransform是(重新)設置比例的好替代方法,但scale只是一個設置變換矩陣值的包裝,就像setTransform一樣,但您需要setTransform才能在scale()積累時完全重置比例。希望答案有幫助! – K3N

+0

啊,我錯過了..避免保存/恢復對絕對是一個好主意。 – backspaces

-1

坦白地說,亞像素字體大小是相當無意義的。您可能想要完全刪除文本,或者用「直線」來表示文本行。在一些已知的標準尺寸下使用measureText()來獲得每一行的適當的相對長度,然後畫一條直線來表示存在(不可讀的)文本。

+0

字體使用canvas變換進行縮放,因此如果ctx.scale爲20,則「.5px serif」字體將呈現爲10px字體。這是我的問題的要點。我想指定一個小字體這樣的畫布在AFTER SCALING變成明智的字體。 – backspaces

+0

我不知道爲什麼,但我已經沒有運氣試圖自己。也許是因爲字距應用於未縮放的大小。相反,我最終放置了scale:1.0縮放地圖上的文本,並確定了JS中的縮放翻譯值。 – bjorke

+1

我遇到了同樣的問題。我的數據是規範化的(0-1),也有任意的變換,我應用上下文變換。似乎我無法繪製文本,因爲任何<.5都會消失,而且.5是巨大的(因爲它被縮放)。僅僅是Canvas規範中的一個錯誤?我很想看到解決方案。另外,我的轉換過於複雜,不容易在javascript中重現。 –

1

認爲這將很難,我意識到有一個簡單的解決方案使用變換。

考慮到上下文目前以複雜的方式轉換,並且我想在給定位置(tx,ty)處繪製文本。唯一需要了解的是當前比例,(scaleX,scaleY)(無論如何您需要知道計算小數字的大小,然後您可以轉換(在轉換後的座標系中),然後進行未縮放並繪製文本:

ctx.save(); 
ctx.translate(tx, ty); 
ctx.scale(1/scaleX, 1/scaleY); 
ctx.fillText("Some String", 0, 0); 
ctx.restore(); 

如果你需要做的有關文字大小的任何數學,就可以在「未縮放」進行協調。