Can I use a custom font in an HTML5 canvas?

Has anyone had success importing a custom font for use in HTML5 canvas? I've been trying to do this by loading the font file on my computer, but all my attempts have failed so far. The canvas keeps showing the default font instead of the one I want to use. It seems like there might be a step or process that I'm missing.

Currently, I am attempting to load the font with CSS:

@font-face {
    font-family: 'RifficFree-Bold';
    src: local('RifficFree-Bold'), url(./fonts/RifficFree-Bold.ttf), format('truetype');
}

Then, I call the font in JavaScript like this:

function drawText(myText, ctx) {
    ctx.font = "40px RifficFree-Bold";
    ctx.fillStyle = "rgb(0, 0, 0, " + myText.fill + ")";
    ctx.fillText(myText.text, myText.x, myText.y);
}

I can confirm that the program is recognizing the font because changing the font size value actually affects the displayed text. This leads me to believe that maybe the font file itself is not being loaded correctly. Any thoughts or suggestions?

Answer №1

The unique font-face fonts are only loaded when they are actively used, as discussed in more detail in a related question. This means that when you run your drawText function, the font will not start loading until after ctx.fillText has been called, by which point the text will have already been rendered using the default font.

If you want to ensure the font is pre-loaded, there are two methods you can use:

  1. Place a hidden div with some text in the desired custom font on any part of the page (this div can be removed once the font loads).

  2. Alternatively, if you prefer not to modify the HTML or need to load multiple fonts, you can create a simple function for loading fonts:

    function _loadFont(fontname){
        var canvas = document.createElement("canvas");
        //Setting dimensions may not be necessary
        canvas.width = 16;
        canvas.height = 16;
        var ctx = canvas.getContext("2d");
    
        //Attaching the canvas is unnecessary,
        //the browser will load the active font upon calling fillText
    
        //For multiple custom fonts, simply draw each one here
        ctx.font = "4px "+fontname;
        ctx.fillText("text", 0, 8);
    }
    

    Call this function before utilizing the font, ensuring it is loaded and ready when needed.

Answer №2

The issue in the example provided appears to be the placement of the comma (,) between the url and format parameters. It is important for the format to directly follow the url:

src: local('RifficFree-Bold'), url(./fonts/RifficFree-Bold.ttf) format('truetype');

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Problems with IE8 - Rendering correctly on all other browsers

I'm having some trouble with my website's display in IE8. It looks great in IE9, Firefox, and Chrome, but in IE8 it appears all jacked up. I'm using WordPress with Thesis Themes and editing custom.css for my changes. You can view my site he ...

What is the specific function of $('id').on('click', this.method.bind(this)) in this scenario?

Check out the app I'm talking about here: I am delving into the bind method in JavaScript to grasp its essence. Upon experimenting with it in the console, my interpretation is that bind produces a duplicate of the function, wherein "this" is tethere ...

Leveraging React hooks to combine an array and an object within an array

Struggling to incorporate an array and an object into another array. This is the setup in my constructor: const [dashboard, setDashboard] = useState({ loading: true, data: [], address: '' }) This is how I envision the final data structure: { ...

Encountering a Javascript 404 error while attempting to make an API call

I encountered an issue while trying to modify data in my database. When my api request is made, I am receiving the following error: Uncaught (in promise) SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) Additionally, I am r ...

Generate a dynamic file import loop within a React application

Suppose I have a directory containing several .md files: /static/blog/ example_title.md another_example.md three_examples.md and an array that includes all the titles: const blogEntries = ["example_title", "another_example", "three_examples"] In ...

Error: Unable to execute fields.map function while generating a dynamic sitemap using next-sitemap module

I'm in the process of creating a dynamic sitemap for my website and here's the code I'm using: import { GetServerSideProps } from 'next'; import { getServerSideSitemap, ISitemapField } from 'next-sitemap'; import { makeSl ...

Bizarre display of miscellaneous items on the monitor

Hey there, I've been working on creating a div to display information about both the Civilian and Vehicle that users input. Initially, everything worked perfectly with my HTML and CSS until I introduced two additional divs into the layout. With just o ...

The creation of an indexedDB database and the addition of content encountered an error while trying to perform a 'transaction' on the IDBDatabase

I am relatively new to using IndexedDB and have successfully created a database. However, I am encountering an error when trying to add content to it. The specific error message reads: Uncaught NotFoundError: Failed to execute 'transaction' on ...

Implementing nested popup windows using Bootstrap

I am facing an issue with my two-page sign-in and sign-up setup in the header of my angular2 project. On the sign-up page, I have a link that should redirect to the sign-in page when clicked, but I am struggling to make it work. Can someone provide guidanc ...

Implement a counter in a JavaScript table, initializing it to zero

I have successfully written my code, but there is one issue. The first row is starting with the number one instead of zero. I'm looking for suggestions on how to start from zero. Any help would be greatly appreciated. Thanks! <script> var tabl ...

What is the most effective way to remove or modify an element in an array when a button is clicked?

I've hit a roadblock because I'm uncertain about how to access and remove elements stored within an array, especially if the user wants to delete from the middle. In this scenario, using pop won't suffice as it removes from the end without c ...

Obtain Information from an Ajax GET Request

My question is fairly straightforward. I have this Ajax function: function fillProductLine(obj) { $.ajax({type: "POST", url: '/orderOnline/index.php/Orders/searchProductLine', async: false, data: { cd_cpl ...

Use ajax to load a webpage into a specific div, then reload the same div after submitting

I have a webpage that includes hyperlinks and a content area with an id of "contentarea" where the results from these hyperlinks are displayed. When a user clicks on the "Search" link, the page search.jsp loads, which contains a submit button and a form ...

Steps for launching a browser using Capybara and Selenium

I am completely new to utilizing Capybara and have not had any experience with Selenium in the past. Currently, I am working on a Ruby on Rails project on MacOSX and encountering an issue where the browser window does not open when I execute my test. My te ...

Achieving Automatic Scrolling of Drawer in Material UI React JS

Looking for assistance, can anyone lend a hand with this code snippet I've been working on? See it here: https://codesandbox.io/s/5xoj9zw56l I referenced this code as part of my project development: https://codesandbox.io/s/6jr75xj8y3 ...

Building a node.is script to validate email addresses

This code snippet is for validating email addresses. I have successfully implemented example 5, where the email length must be over 5 characters to avoid errors and prompt users to re-enter their email address. However, I am unsure how to handle examples ...

how can I display the JSON description based on the corresponding ID using Ionic 3

I have a JSON file containing: [{ "id": "1", "title": "Abba Father (1)", "description": "Abba Abba Father." }, { "id": "2", "title": "Abba Father, Let me be (2)", "description": "Abba Father, Let me be (2) we are the clay." }, { ...

What is the best way to combine two DIV table rows within Bootstrap 5?

Looking at the code below, there are 6 cells in 2 rows, but I want to merge cell number "2" and "5". I know this can be accomplished using CSS Table DIV, but is there a way to do it with Bootstrap? I haven't found any documentation that worked for me ...

"jQuery enables hover effects to be applied to elements that are not directly related

I'm attempting to achieve an effect where an element will show or hide when I hover over a completely different element. Currently, my approach involves using lists and indexes so that the nth item in list 2 changes when the nth item in list 1 is hov ...

Prior activation of express render before parameter assessment

Seeking guidance as a newcomer to nodejs, express, and javascript. Here is the code I currently have: router.get('/', function(req, res, next) { const content = fileReader(); res.render('index', { "content" : content } ); }); ...