Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing text to <canvas> with @font-face does not work at the first time

When I draw a text in a canvas with a typeface that is loaded via @font-face, the text doesn't show correctly. It doesn't show at all (in Chrome 13 and Firefox 5), or the typeface is wrong (Opera 11). This type of unexpected behavior occurs only at the first drawing with the typeface. After then everything works fine.

Is it the standard behavior or something?

Thank you.

PS: Following is the source code of the test case

<!DOCTYPE html> <html>     <head>         <meta charset="UTF-8">         <title>@font-face and &lt;canvas&gt;</title>         <style id="css"> @font-face {     font-family: 'Press Start 2P';     src: url('fonts/PressStart2P.ttf'); }         </style>         <style> canvas, pre {     border: 1px solid black;     padding: 0 1em; }         </style>     </head>     <body>         <h1>@font-face and &lt;canvas&gt;</h1>         <p>             Description: click the button several times, and you will see the problem.             The first line won't show at all, or with a wrong typeface even if it does.             <strong>If you have visited this page before, you may have to refresh (or reload) it.</strong>         </p>         <p>             <button id="draw">#draw</button>         </p>         <p>             <canvas width="250" height="250">                 Your browser does not support the CANVAS element.                 Try the latest Firefox, Google Chrome, Safari or Opera.             </canvas>         </p>         <h2>@font-face</h2>         <pre id="view-css"></pre>         <h2>Script</h2>         <pre id="view-script"></pre>         <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>         <script id="script"> var x = 30,     y = 10;  $('#draw').click(function () {     var canvas = $('canvas')[0],         ctx = canvas.getContext('2d');     ctx.font = '12px "Press Start 2P"';     ctx.fillStyle = '#000';     ctx.fillText('Hello, world!', x, y += 20);     ctx.fillRect(x - 20, y - 10, 10, 10); });         </script>         <script> $('#view-css').text($('#css').text()); $('#view-script').text($('#script').text());         </script>     </body> </html> 
like image 558
lemonedo Avatar asked May 03 '10 07:05

lemonedo


People also ask

How do I add a font to canvas?

canvas = document. querySelector('canvas'); var myFont = new FontFace('myFont', 'url(assets/fonts/myFont/myFont. otf)'); Now we create our font object using the javascript class FontFace which receives the font family and the source.

How do you put text on a picture in canvas?

Go to the Text pane on the left sidebar. Select from hundreds of pre-formatted text holders. Or add your own text box by keying T on the editor. Then, add your desired text.


2 Answers

Drawing on canvas has to happen and return immediately when you call the fillText method. However, the browser has not yet loaded the font from the network, which is a background task. So it has to fall back to the font it does have available.

If you want to make sure the font is available, have some other element on the page preload it, eg.:

<div style="font-family: PressStart;">.</div> 
like image 54
bobince Avatar answered Sep 26 '22 09:09

bobince


Use this trick and bind an onerror event to an Image element.

Demo here: works on the latest Chrome.

var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d');  var link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = 'http://fonts.googleapis.com/css?family=Vast+Shadow'; document.getElementsByTagName('head')[0].appendChild(link);  // Trick from https://stackoverflow.com/questions/2635814/ var image = new Image(); image.src = link.href; image.onerror = function() {     ctx.font = '50px "Vast Shadow"';     ctx.textBaseline = 'top';     ctx.fillText('Hello!', 20, 10); }; 
like image 32
a paid nerd Avatar answered Sep 23 '22 09:09

a paid nerd