How to add a custom font to an HTML canvas
Tags: html, javascript, gamedev, beginners
Published: 2021-04-27 17:02:58

So yesterday I was working on a canvas and I realized that the font I had tried to add using `@font-face` with CSS, wasn't working at all.

After doing what I guess every developer in my position would do—Yeah, I mean searching on StackOverflow‒I find that this is a pretty common issue.

But **how can you solve this?** Well, the solution is simple, even though I hope you have at least basic knowledge of HTML, CSS, and Javascript

## HTML

    <!DOCTYPE HTML>
    <html lang="en">
    <head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>My Canvas Project</title>
	<style type="text/css"  rel="stylesheet">
		body {
			margin: 0;
		}
	</style>
    </head>
    <body>
	<canvas></canvas>
	<script src="canvas.js"></script>
    </body>
    </html>

As you can see we have a **simple HTML5 document** here, with a `<canvas>` tag and a `<script>` tag that we will use to load our javascript code.

## Javascript

Now it's time for us to work on the javascript file, the one that will let us load our custom font. **I'll explain it step by step**.

    canvas = document.querySelector('canvas');

**The first thing we need to do is to get the canvas element inside a variable**. To do that we use the `document.querySelector()` method, which receives the element name ('canvas' in this case). Now we can interact with the canvas element from our javascript code.

    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_.

**This is an experimental technology, you can learn more about i's browser compatibility [here](https://developer.mozilla.org/en-US/docs/Web/API/FontFace/FontFace#browser_compatibility)**

    canvas = document.querySelector('canvas');
    var myFont = new FontFace('myFont', 'url(assets/fonts/myFont/myFont.otf)');

    myFont.load().then(function(font){

      // our code here

    });

**Now we can load our font**. As you can see, we are using `.then()` after loading the font because **this is an asynchronous operation so we need to get the font before continue**.

    canvas = document.querySelector('canvas');
    var myFont = new FontFace('myFont', 'url(assets/fonts/myFont/myFont.otf)');

    myFont.load().then(function(font){

      // with canvas, if this is ommited won't work
      document.fonts.add(font);
      console.log('Font loaded');

    });

There you go. What happened here is that we told the object `FontFace` to load our font and then we pass that font as a parameter of the function that will be executed next, the one inside the `.load()` method. **Then we add the font to our document fonts and that's it**, now we can display our "Hello, World!" with our custom font.

    ...

    // set width and height as screen w and h
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    ...

With these two lines, we **specify our canvas width and height** the same as the screen width and height.

    ...

    // get canvas context
    var ctx = canvas.getContext("2d");
    ctx.font = "50px myFont"; // set font
    ctx.textAlign = "center"; // center text
    ctx.fillText("Hello, World!", canvas.width/2, canvas.height/2); // draw centered text

    ...

Now, all we need to do is to **get our canvas context**, **assign the font we're gonna use**, **center the text**, and **draw our "Hello, World!" in the middle of our canvas**.

Here You'll find the whole javascript code. I hope you have found this useful. If anything, just let me know in the comments, and please don't forget to follow me, Iḿ working on an interesting Shell Scripting series focused on video games. Till the next time.

{% gist https://gist.github.com/alexsc6955/06148d596e75a3fce0a5cc1f9394134f %}