Loading text with a remote web font has been successfully initiated in Fabric.js

Currently, I am immersed in developing a large custom application using Fabric JS and thus far, my progress has been commendable. However, I have encountered an issue concerning the initialization of loaded text objects that utilize web fonts.

When the font is readily available on the client's device, everything functions as expected. However, if the webfont fails to load, the text object on the canvas defaults to a sans-serif font-family.

In essence, here is what I typically do (for illustration purposes, let's assume "allstar" is the webfont being utilized):

CSS: The CSS is incorporated within fonts.css, located within the head section preceding fabric.js

@font-face{
    font-family:'allstar';
    src:
        url('/path-to-fonts/all_star-webfont.eot');
    src:
        url('/path-to-fonts/all_star-webfont.eot?#iefix') format('embedded-opentype'),
        url('/path-to-fonts/all_star-webfont.woff') format('woff'),
        url('/path-to-fonts/all_star-webfont.ttf') format('truetype'),
        url('/path-to-fonts/all_star-webfont.svg#allstarregular') format('svg');
    font-weight:normal;
    font-style:normal
}

Javascript: This is called towards the end of the page, enclosed within $(document).ready(function(){})

var textSample = new fabric.Text(text, {
    fontFamily: "allstar",
});
canvas.add(textSample);
canvas.renderAll();

While implementing the font elsewhere on the webpage (e.g., within a transparent span element with a dot and the font properly loaded) yields positive results, I believe this approach may not be the most efficient coding practice.

At the moment, I am utilizing fabric.js version 1.3.0

Answer №1

The problem:

  1. Immediate rendering of Canvas
  2. Webfonts loading by Google
  3. Canvas unaware until the next re-render event

The solution:

  1. Immediate rendering of Canvas
  2. Google loads webfonts using a callback function
  3. Force a re-render
  4. Canvas is now updated

http://jsfiddle.net/vvL6f/6/

WebFontConfig = {
    google: { families: [ 'Ribeye::latin', 'Lora::latin', 'Croissant+One::latin', 'Emblema+One::latin', 'Graduate::latin', 'Hammersmith+One::latin', 'Oswald::latin', 'Oxygen::latin', 'Krona+One::latin', 'Indie+Flower::latin', 'Courgette::latin', 'Ranchers::latin' ] }
};

(function() {
    var src = ('https:' === document.location.protocol ? 'https' : 'http') +
        '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';

    $.getScript(src, function(data) {      
        // Running this twice to ensure font loading and correct positioning
        canvas.renderAll();
        canvas.renderAll();
    });
})();

Answer №2

Shortcut:

<script src="//ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js"></script>
<script>
WebFont.load({
            google: {
                families: [ 'Abel', 'Aclonica']
            },
            fontinactive: function(familyName, fvd) {
                console.log("Apologies " + familyName + " font family cannot be loaded right now. Please try again later.");
            },
            active: function() {
                // implement font-related actions   
                $('#stuff').attr('style', "font-family:'Abel'");
                var text = new fabric.Text("Insert Text Here", {
                    left: 200,
                    top: 30,
                    fontFamily: 'Abel',
                    fill: '#000',
                    fontSize: 60
                });

                canvas.add(text);
            }
        });
</script>

Extended method When do web fonts load and can you pre-load them?

Additional details on web font loader https://github.com/typekit/webfontloader.

specific https://groups.google.com/forum/#!topic/fabricjs/sV_9xanu6Bg

Answer №3

After experimenting with fabric.js and Google Web Fonts, I found a solution that worked well for me:

Check out the code in action on this Fiddle: http://jsfiddle.net/SaraCoder123/gyR8m/

CSS

<Style>
@font-face {
font-family: 'Jolly Lodger';
font-style: normal;
font-weight: 400;
src: local('Jolly Lodger'), local('JollyLodger'),
url(http://themes.googleusercontent.com/static/fonts/jollylodger/v1/RX8HnkBgaEKQSHQyP9itiaRDOzjiPcYnFooOUGCOsRk.woff) format('woff');
}
</style>

Javascript

<script type = "text/javascript">
canvas = new fabric.Canvas('c'); 
var text = new fabric.Text("Using Web Fonts", {
                    left: 200,
                    top: 30,
                    fontFamily: 'Jolly Lodger',
                    fill: '#000',
                    fontSize: 60
                });

canvas.add(text);
</script>

HTML

<canvas id="c" height="200px" width="400px"></canvas>

I discovered that including 'local' references in the Google Web Fonts CSS was key to getting it to work properly.

Answer №4

Encountered a similar issue myself. The font display is resolved only after a certain event triggers. To ensure proper rendering, simply activate the object after creation:

var sampleText = new fabric.Text(text, {
    fontFamily: "allstar",
});
canvas.add(sampleText);
canvas.setActiveObject(sampleText); // Activates the specified object
canvas.renderAll();

Answer №5

To achieve optimal results, utilize the setTimeout() function;

setTimeout(function(){
    var currentObject = canvas.getActiveObject();
    currentObject.set({
        fontFamily: style,
        useNative: true
    });
canvas.renderAll();},500);

For further reference, view the jsfiddle link provided below:

http://jsfiddle.net/muthupandiant/x3ptsgex/1/

Answer №6

In the current year of 2017, incorporating web fonts into Fabric.js for Firefox is now a seamless process.

All you need to do is include the fonts using @import in your stylesheet or with <link href="..."> within the <head> section. Once added, you can easily select any desired font by utilizing fabric.Text's 'fontFamily' attribute.

To address any initial issues, simply calling canvas.renderAll(); will refresh the canvas and showcase all loaded web fonts correctly.

For a demonstration, check out this basic example on jsFiddle.

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

The React Router path is inaccurately matching to a different route

I'm currently utilizing React version 4.2 for my application, but it appears to be having trouble matching the correct paths for the routes. <Provider store={store}> <BrowserRouter> <div> <Switch> ...

Wait to execute until the external script in Vue.js has finished loading

How can I trigger the rendering of a recaptcha after a Vue.js component has mounted? It functions correctly on initial load and reload, but throws an error when navigating away to a different url and using the browser back button. Here is how it's se ...

Is it necessary to have bidirectional relationships in Sequelize?

In my database, I have two existing tables: "user" which contains columns "id" and "depId", and "department" with columns "id" and "name". The column user.depId is a foreign key referencing department.id. Now, I want to create a sequelize model for this r ...

Editable content tag

Is there a way to set the maximum number of rows in the contenteditable attribute? I would like to limit users once they reach the character capacity for sending data via POST method. I am currently working with HTML 5. Contenteditable is a new attribute ...

What is the best approach to retrieve a recently upserted document in MongoDB?

When executing the command below, with foos representing a collection, I perform an "upsert" of a new item: foos.update(criteria, { $set: fooUpdate }, { w: 1, upsert: true }, function(err, upsertedFoo) { /* upsertedFoo represents the count of ...

Altering the look of a button as you navigate to it by tabbing

Check out this code snippet: In my design, I have set it up so that the user can tab through the username field first, then the password field, followed by the login button and finally the navigation tabs labeled "Getting Started" and "Vegetables." The i ...

What exactly is the purpose of FormControl and why is it employed? In what ways should FormControl be properly utilized?

I'm a bit confused about how to properly use FormControl in Material-UI when creating forms in React. Can someone simplify for me what exactly FormControl does and why I should consider using it in my project? Currently, I have a Form.js Component wh ...

Customize Bootstrap 4 table by incorporating d-flex class and changing border color styling for a

Currently utilizing bootstrap 4.0, I am attempting to customize the table-bordered by changing the color and incorporating d-flex with col-* for column sizing. An issue arises where all borders become duplicated when attempting to modify the color scheme. ...

Sort through a list of objects using the criteria from a separate array

Looking to apply a filter on an array of objects: const myArray = [{ id: 4, filters: ["Norway", "Sweden"] }, { id: 2, filters :["Norway", "Sweden"] }, { id: 3, filters:["Denmark", "Sweden&q ...

How to Detect Font Resizing in Google Web Toolkit (GWT)

I am trying to find a way in GWT to capture the font resize event that occurs when the user changes the size of the font by using Ctrl-Mouse Scroll or going to View -> Zoom. I have searched on Google and looked on StackOverflow but haven't found an ...

fresh map from Google: Coordinates LatLng may not be a number, but my hunch tells me it is

Seeking Assistance with this Issue - For example, the initial location data appears as: "Object Lat: -36.768498 Lng: 174.75895" However, an error is indicating that the latitude is not recognized as a number. Rather than making adjustments without clea ...

Switching video sources with jQuery and HTML5 can be achieved by clicking on an

I need to develop an engaging video using HTML5 and jQuery. My objective is to: Start playing video1 Show button1 when video1 finishes, then switch to video2 upon clicking and hide button1 Play video2 Display button 2 after video2 ends, then change to vi ...

What is the best way to change the format of a datetime?

While working with sailsjs(node.js), I have successfully retrieved all the data from a MySQL database and displayed it in a jtable. However, the date format is currently showing as YYYY-MM-DDTHH:mm:ss.000Z. I am looking to convert this format (YYYY-MM-DDT ...

tips for optimizing javascript file caching

https://i.stack.imgur.com/UhWD1.pngMy web application was created using "pug" technology about 9-8 years ago, and more recently, pages have been added in an innovative framework (vue.js). However, whenever there is a transition between an old pug page and ...

Adsense displays empty ad banners regardless of their predetermined size

Having trouble with Adsense banners? I have a page with three fixed-size banners (336 x 280) and sometimes they appear blank. It's random - one might work while the others don't, or none may work at all. The code is the same for each banner: < ...

Vue-moment displaying incorrect time despite timezone setting

Feeling a bit puzzled about my Laravel 8 application. I store time in UTC with timestamp_no_timezone in my PostgreSQL database. When I check the time in the database, it displays today's date with 13:45 as the time. However, when I use vue-moment and ...

Using Foreach with Bootstrap to display a grid of 6 column items with images

When using a foreach loop to display clients with images, the desired layout is for them to be listed in 6 columns. For instance, if there are 18 clients, they should be displayed in a grid of 6 columns and 3 rows. Here is the Razor code and HTML: <di ...

Using AJAX, FLASK, and JavaScript to send an existing array to an endpoint

Having trouble POSTing the array songFiles generated by the getTableData() function (inside an ajax request) to the /api/fileNames endpoint, and then handling it in the postFileNames() callback function. Any assistance or alternative approaches would be gr ...

Issue with package: Unable to locate the module specified as './artifacts/index.win32-ia32-msvc.node'

I am encountering an issue while using Parcel for the first time. When I execute npx parcel .\app\index.html, I receive the following error: Error: Module not found './artifacts/index.win32-ia32-msvc.node' Require stack: - C:\Users ...

"Encountering surprising outcomes while utilizing the csv-parser module in Node.js

I am struggling to fetch the headers of a CSV file and store them in an array using the csv-parser module. There are two main issues I'm encountering: 1) I can't seem to figure out why the console.log statement at the end of the code block is ex ...