18

I am completely baffled as to how to change the font I'm using when drawing text on a canvas. The following is the font I have defined in my CSS:

@font-face{
 font-family:"Officina";
 src:url(OfficinaSansStd-Book.otf);
}

Now in my HTML/JavaScript I'm tempted to say:

context.font = '30px "Officina"';

But this doesn't work. It works fine if I use a web available font (like Arial), and the Officina font shows up fine when I just write plain text directly to the webpage. What am I missing?

cryptic_star
  • 1,808
  • 3
  • 26
  • 46
  • 2
    Not sure, but maybe you need to wait until the font is loaded before running your JS? You could try putting your script in a 5 second timeout after the DOM loads and just see if it works (since the font will most likely load within 5 seconds after the DOM loads). Just a hypothesis – Oscar Godson May 24 '11 at 22:36
  • How would one do that? I'm not very familiar with DOM. – cryptic_star May 25 '11 at 00:53
  • Try just doing document.body.onload = function(){ setTimeout(function(){ /* all your code here */ },5000) }; This doesnt wait for the DOM to load, but its close – Oscar Godson May 25 '11 at 02:59

6 Answers6

3

For folks coming to this question circa 2017 onwards it would be best to use the Web Font Loader that's co-produced by Google and Typekit located here: - https://github.com/typekit/webfontloader

JoeManFoo
  • 321
  • 2
  • 11
3

To get cross-browser compatibility you should use CSS for the embedded font like this:

@font-face {
    font-family: 'BankGothicMdBTMedium';
    src: url('bankgthd-webfont.eot');
    src: local('BankGothic Md BT'), local('BankGothicBTMedium'), url('bankgthd-webfont.woff') format('woff'), url('bankgthd-webfont.ttf') format('truetype'), url('bankgthd-webfont.svg#webfontNgZtDOtM') format('svg');
    font-weight: normal;
    font-style: normal;
}

Note: I got those font files somewhere at http://fontsquirrel.com

This is working for me, but I'm using this font also in HTML markup, so maybe a workaround (if the font-face definition doesn't help) can be using that font in some hidden div, of course I'm running all JS after body loads.

Sven
  • 1,341
  • 3
  • 34
  • 55
tomasb
  • 1,655
  • 2
  • 22
  • 28
2

You can use the Google Web Font loader, but that's rather heavyweight and/or annoying for many uses. Instead, I'll recommend Jennifer Simonds' FontDetect library, available on GitHub:

A JavaScript class you can use to determine whether a webfont got loaded, which font is being used by an element, or react to a webfont getting loaded (or failing to load).

John Whitley
  • 1,970
  • 17
  • 22
1

This is previous question should help you. Drawing text to <canvas> with @font-face does not work at the first time

Community
  • 1
  • 1
tcnarss
  • 565
  • 4
  • 22
  • So I tried adding a `
    ` with some text in it before all of my JS, to no avail. You can see it [here](http://aterrell-www.cs.wisc.edu/search/sample.php) - the text just above the white box is the correct font, the word "Computer" is sans-serif (as it should be), but the other text box is also sans-serif, but is defined as Officina.
    – cryptic_star May 25 '11 at 00:56
0

NOTE: Outdated as of 2016

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

Demo here: http://jsfiddle.net/g6LyK/ — 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);
};
Community
  • 1
  • 1
a paid nerd
  • 29,751
  • 30
  • 126
  • 170
-7

How about try to put your url as a string:

@font-face{
 font-family:"Officina";
 src:url('OfficinaSansStd-Book.otf');
}

context.font = "30px Officina";
Ashish Ahuja
  • 4,913
  • 10
  • 51
  • 65
Visal Chhourm
  • 544
  • 3
  • 12