When looking through the questions I never found a clear answer to the above. I wanted a method that worked with just about every platform. So for the benefit of the community, I thought I'd share my success in getting custom fonts to work in canvas. My main question was, What is a surefire way to get said fonts to work? I tried multiple methods such as just using a CSS stylesheet but it's a bit more complicated than that. Here's what I found:
-
1Possible duplicate of [How can I use custom fonts in an HTML5 Canvas element?](http://stackoverflow.com/questions/2608022/how-can-i-use-custom-fonts-in-an-html5-canvas-element) – Spencer Wieczorek Jul 19 '16 at 04:53
3 Answers
Update: This solution now works on all browsers except IE 11 and below.
Although it doesn't have complete support yet you can now use the FontFace API to explicitly load fonts before using them on a canvas.
var f = new FontFace('Font name', 'url(/path/to/font.ttf)');
f.load().then(function(font) {
// Ready to use the font in a canvas context
console.log('font ready');
// Add font on the html page
document.fonts.add(font);
ctx.font = '48px Font name';
ctx.strokeText('Hello world', 100, 100);
});
I can confirm that this works on Chrome 61.0.3163.100, Safari 11.0 (12604.1.38.1.7), Firefox 56.0 (all OSX) and Safari iOS 11.1.

- 2,750
- 1
- 14
- 22
-
2
-
4this didn't work for me until i changed the `f.load()` line to `f.load().then(function(font) { document.fonts.add(font);` – omikes May 06 '19 at 16:58
-
Man thanks alot this helped me alot, I got the same code from everywhere but it didn't work, but after then i saw this answer and `document.fonts.add(font);` this line was missing from everywhere – Aditya Jul 13 '21 at 18:16
I'll discuss my code underneath. First off, My Javascript:
window.onload = function start() {
canvas = document.getElementById('canvas1');
C_Width = canvas.width;
C_Height = canvas.height;
cxt = canvas.getContext('2d');
setTimeout(text_handler,200);
}
function text_handler() {
console.log('made it!');
cxt.font="20px myFont";//font size and then font family.
cxt.fillStyle="white"; //color to be seen on a black canvas, default is black text
cxt.fillText("TEST",(C_Width/2-200),C_Height/2); //cxt.fillText("message",x_coord,y_coord);
}
Allow me to explain whats going on here. I have a simple window.onload
function so that the canvas exists before I try to get its Id and Context. Inside my text_handler()
function, I have the font size and the font family defined in one line, as well as my font color (White because I have a black canvas). Then in the canvas I draw my message, and provide an x coordinate and a y coordinate. The setTimeout();
delay may be necessary in order to give the canvas time to load the font. In the test program I wrote, I actually got the delay time down really low, though 100ms is almost unnoticeable.
Another critical part of this is the CSS stylesheet:
canvas {
background-color: black; //for white text
font-family:myFont; //necessary
}
#load {
font-family:myFont; //necessary to load font with div
visibility: hidden; //makes div invisible but the div element forces the text to load before the canvas.
height: 0px;
}
@font-face {
font-family:myFont;
src: url('./Font_Path.ttf');
} //self-explanatory
I have of course defined the font in the canvas, the body of the webpage, and a necessary hidden div. The div helps load the font. I have styles in order that the div remains invisible but it still does its job. For some reason, through my testing, I determined that the font-family
style must be above the other styles in my div. Of course, you could use whatever you want. Also of course, I use @font-face
for my custom font.
Here's what the HTML looks like:
<body>
<div id="load">words</div> <!-- load font -->
<canvas id="canvas1" width="500px" height="500px"></canvas>
</body>
As explained above, the div is necessary to load the font before the canvas can implement it. That's why I have "words" inside it.
I really hope this helps someone out because I simply couldn't find anything on it. Please ask me questions, tell me what I could have done differently in the comment section below, or just simply ways I can simplify my code. I'd appreciate the help and constructive criticism. Thanks, and happy Canvas-ing...

- 1,399
- 1
- 12
- 18
-
Also one last thing I forgot to mention. A delay might be necessary before calling the `text_handler()` function. – Brendan Mar 25 '15 at 05:36
-
Would **[this](https://stackoverflow.com/questions/28591573/how-i-write-an-icon-in-the-context-canvas/28593478#28593478)** work for your scenario? – Mar 25 '15 at 06:30
-
Nice work. The delay you mention in your comment is quite important. You might take a look at @KenFyrstenberg's link on how to deal with waiting until the font is fully loaded before the code tries to make use of it in the canvas. ;-) – markE Mar 25 '15 at 17:21
An important point that might get lost is that each font that is used on canvas must also be loaded by setting the font-family style-attribute for the canvas element.
Here's my version using jquery. The ready event removes the need for any timeouts.
<head>
<script src="jquery-3.3.1.min.js"></script>
<style>
@font-face {
font-family: 'AlexBrush';
src: url('fonts/AlexBrush-Regular.ttf');
}
@font-face {
font-family: 'Pacifico';
src: url('fonts/Pacifico.ttf');
}
</style>
</head>
<body>
<canvas id='testCanvas' width='1200px' height='800px'></canvas>
<script>
$(document).ready(function()
{
$('#testCanvas').css('font-family', "AlexBrush");
$('#testCanvas').css('font-family', "Pacifico");
var ctx = c.getContext("2d");
ctx.fillStyle = "#000";
ctx.font = "100px AlexBrush";
ctx.fillText('Hello World', 100, 300);
ctx.font = "100px Pacifico";
ctx.fillText('Hello World', 100, 500);
})
</script>
</body>

- 706
- 7
- 11