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

Design a custom scrolling navigation bar for enhanced user experience

Struggling with web design as I develop a site in ASP.NET. I have a database full of courses, each with numerous modules. The challenge is creating a navigation bar that dynamically adjusts to accommodate the varying number of modules per course without o ...

Invoke the identical function in between two functions that make asynchronous AJAX calls

I seem to be a little lost at the moment. The code snippet below illustrates my intent, which is to use the insertChilds() function to insert child elements in the DOM in a cascading manner (or at least that's what I'm aiming for...). The challe ...

Exploring the world of JSON and JavaScript data structures

Can someone provide some clarification please? var a = '{"item":"earth", "color":"blue", "weight":920}'; Is the data type of a a string or an array ? var b = JSON.parse(a); What is the data type of b - an object or an array ? ...

Incorporate a pseudo class to a unique custom template or directive within an Angular project

I have been developing a custom dropdown menu directive in AngularJS. The issue I'm facing is that the buttons in my template become inactive when interacting with the dropdown menu, unlike a regular HTML select which remains active while the dropdown ...

Tips for utilizing a vue.js nested for loop with two arrays using v-for

The issue has been resolved, and both my parent view and child component code are now correct and functioning properly I am using Vue.js with the goal of iterating similarly to a nested for loop to display a matrix table. Initially, I tried to achieve thi ...

Exploring HTML5 video playback in AngularJS

When I use this code: <video id="video" class="video-js vjs-default-skin" controls width="640" height="264"> <source src="http://localhost:3000/files/public/photos/Let-her-go.mp4" type='video/mp4' /> <p class="v ...

Tips for fixing a type error in javascript/cypress

While learning cypress and javascript, I encountered this type error: TypeError: _testElements.default.selectionRow is not a function I have thoroughly reviewed the documentation for cypress but cannot seem to find any errors in my code. I'm hoping ...

How can I utilize a PHP variable as the height and width parameters in a CSS style?

After spending a considerable amount of time on this project, I am still struggling to make it work. Can someone please guide me on how to correctly assign the width and height values to the img element using variables? for ($x = 1; $x <= $aantal; $x+ ...

Exploring various queries in Firestore

Does anyone know if there is a way to create a sentence similar to this one: return this.db.collection('places', ref => ref.where("CodPais", "<>", pais)).valueChanges(); I have tried using != and <> but neither seem to be valid. Is the ...

Retrieving a targeted JSON element and adding it to a fresh object

Hello everyone, I have an object that resembles the following structure: [ { "app": 1, "scalable": true, "zoomable": true, "cropBoxResizable": true }, { "app" ...

[Vue alert]: Component mounting failed due to usage of mixin with a parameter

For the past day, I've been facing difficulties creating a Vue mixin with a parameter. When attempting to do so, I encounter a [Vue warn]: Failed to mount component: template or render function not defined error. Below is my JS file which includes the ...

Encountering an error with [object%20Object] when utilizing ajaxFileUpload

I wrote a JavaSscript script that looks like this: $.ajaxFileUpload({ url: url, secureuri: false, fileElementId: ['upload-file'], dataType: "JSON", data:{ "sample_path":$(".demo-view-container-left .vie ...

Accessing PHP parameters in JSP files can be accomplished by utilizing specific

The PHP code snippet below checks for a username and password match before redirecting to a JSP page. if($userName==$dbUserName&&md5($passWord)==$dbPassWord){ echo "<input name='username' type='hidden' value='$userN ...

What could be causing these transformed canvases to not display fully in Chrome at specific resolutions?

fiddle: https://jsfiddle.net/f8hscrd0/66/ html: <body> <div id="canvas_div"> </div> </body> js: let colors = [ ['#000','#00F','#0F0'], ['#0FF','#F00','#F0F&a ...

Tips for keeping div and input tags selected even after a user clicks

I am working on a quiz script and I am trying to customize it so that when a user clicks on the div or input tags, they remain selected with a different background color. Currently, I have achieved changing the background color of the div when clicked, ...

Adding the target='_parent' attribute to the infowindow of a Google Fusion Map by utilizing a click event listener

As someone who is relatively new to Google Fusion, I am eager to expand my knowledge and skills. Recently, I created a customized map with an infowindow and embedded it onto my website using the FusionTablesLayer Wizard. I wanted to avoid using the target= ...

Exploring how to use React with a select component featuring objects

Hello, I am new to working with React and I have a question regarding the select component of Material UI. Here's my situation: I am creating functionality for creating and editing a User object. This User object has a primary key and some data, incl ...

Tips for aligning the timing of two CSS animations

I'm struggling to achieve a synchronized CSS animation where a progress bar fills up and a background changes simultaneously. For example, I want the progress bar to fill in 5000ms, with the background image changing every 5000ms as well. Despite se ...

The canvas loadFromJson function fails to implement the font-family property

I have implemented the following code to display Google font and update the canvas: /* on change of font, load the preview and update the canvas */ $('#font').on('change', function () { $('.font_preview').show ...

Error message: "An issue occurred with the Bootstrap Modal in

I've designed an AngularJS app like so: <!DOCTYPE html> <html ng-app="StudentProgram"> <head> <title>Manage Student Programs</title> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2. ...