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:
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() {
// Ready to use the font in a canvas context
console.log('font ready');
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.
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 ay 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...
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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.