Fraktionale Schriftgrößen html5 Leinwand?

8

Ich habe ein Problem damit, wie verschiedene Browser Schriftgrößen auf dem HTML5-Canvas darstellen. Insbesondere dort, wo die Schriftgrößen keine ganzen Zahlen sind. Zum Beispiel "8.5px Arial", "2.23em Arial" und so weiter.

Für canvas.font = FontSize + "px Arial"; wo FontSize ist (8.1, 8.2, 8.3, ...) Ich würde ein lineares Ergebnis erwarten, aber der einzige Browser, der dies konsequent archiviert, ist IE! ( Ich kenne ). Firefox läuft unter 11.2px, ist aber darüber hinaus linear. Chrome und Safari skalieren Schriftarten nur auf ganzzahlige Werte.

Die Rundungsregel scheint auf Pixel eingestellt zu sein und auf die nächste ganze Zahl unter 0,5 abgerundet zu werden.

Meine Canvas-App führt einige programmatische animierte Transformationen (Skalieren und Übersetzen) durch. Um Canvas-Transformationen aus Gründen der Effizienz zu vermeiden, obwohl ich vermute, dass es das Problem lösen würde, habe ich dies auch nicht mit HTML-Textgröße getestet CSS3 (auf dem die Canvas.font basierend auf der Spezifikation basieren soll)

Die Browser verhalten sich zumindest konsistent zwischen den Schriftgrößen pt, px, em und%. [Bearbeiten: außer Safari zeigt keine% Größen an]

[beiseite]: Alle Schriften sehen ein wenig fett aus, wenn sie einmal in die Luft gesprengt wurden. Safari nimmt diesen Kuchen, während wir von 17.4px zu 17.5px gehen. BAMB!]

Ich habe unten ein paar Beispielbilder beigefügt, aber würde wirklich gerne ein paar Ideen haben, wie man alle Browser mehr wie IE macht (hätte nie gedacht, dass ich das sagen würde) - Ist das ein Fehler oder ein Standard zum Rendern von Schriften?

Hier ist mein Testcode, der für den PX-Schriftgrößenfall repliziert werden kann.

%Vor%

Pixelskala Punkteskala em-Skala - 1em = 5px Arial Prozentskala - 100% = 5px Arial

    
dave.zap 15.03.2013, 11:06
quelle

1 Antwort

6

Ich dachte, du hättest meine Arbeit für mich erledigen sollen;) Wie auch immer, hier habe ich das Problem gelöst, obwohl es ein bisschen wie ein Hack ist und immer noch einige Probleme hat, die ich beschreiben werde.

Zur Erinnerung (weil es in der Frage vielleicht nicht klar war) habe ich mehrere Schriftgrößen mit einer Gleitkommazahl versucht, um den Text zu vergrößern und zu verkleinern. Aber dies führte zu nervigen Ergebnissen aufgrund der Tatsache, dass die Schriftgröße meistens auf den nächsten ganzzahligen Wert gerundet wird.

Also zum Beispiel.

%Vor%

zoom = 1.04 (12.48px) würde dasselbe wie der obige Code darstellen, während zoom = 1.06 (12.75px) auf 13px aufgerundet würde.

Dies führte zu einem sehr unerwünschten Springen der Schriftgröße zwischen den Werten, während alle anderen Elemente auf der Zeichenfläche korrekt skaliert wurden.

Das Problem wurde durch die Tatsache verstärkt, dass alle Browser eine gegebene Textfolge wie "BEISPIEL TEXT" und etwas andere Längen wiedergeben.

Die Lösung

Während der Initialisierung den Text in der Standardschriftgröße (Zoom = 1) rendern und die Zeilenlänge messen, lassen Sie diesen Wert iniLineLength

heißen

Beim Rendern von Szenen habe ich einen versteckten Canvas verwendet, um den Text auf drawImage mit einem Multiplikator für die Breite auf die Hauptfläche zu rendern.

%Vor%

Die resultierende Textzeile wird im Hauptbereich gestreckt oder geschrumpft, je nachdem, wie weit die Zeilenlänge von der erwarteten Zeilenlänge entfernt ist.

In einer idealen Welt würde s immer gleich eins sein, da die erwartete Zeilenlänge immer dieselbe wäre wie die tatsächliche Zeilenlänge. Die erwartete Zeilenlänge ist unsere Sample-Zeilenlänge iniLineLength multipliziert mit dem gleichen Zoomfaktor, den unsere Schriftgröße in diesem Render-Durchlauf hatte.

Ich habe den Bonus, dass alle Unterschiede im Browserverhalten normalisiert werden ... fast.

Probleme

Auch wenn die Zeilenlänge normalisiert ist, ist die genaue Position jedes Zeichens in der Zeile nicht gleich. Geben Sie den Effekt im Bild unten.

Aber das ist schon eine enorme Verbesserung gegenüber dem, was ich hatte.

Außerdem werden Sie Ihre tmpCanvas an mainCanvas anhängen wollen, sonst wird Ihr Browser zum Stillstand kommen, wenn er versucht, Ihren Megapixel-Text zu erstellen und zu kopieren, nur um einen Vollbildmodus zu haben .

In diesem Sinne können Sie auch die Breite und Höhe Ihres tmp-Canvas so einstellen, dass sie der tatsächlichen Textzeile entspricht, die Sie rendern wollen. Das spart Speicherplatz, Zeit und so weiter.

    
dave.zap 17.03.2013, 11:09
quelle

Tags und Links