Html2canvas: Custom font on SVG element is not correct

Created on 12 Mar 2018  ·  21Comments  ·  Source: niklasvh/html2canvas

Hello, I have svg element and use google font.
But when capture this element to image the font is not correctly.
I'm using version 1.0.0-alpha.10.
Thank you for your advice.

Here is my code: https://jsfiddle.net/fgppmvxo/8/

Most helpful comment

I got it to work by using this module
https://github.com/lukehorvat/computed-style-to-inline-style
to inline the font related styles into the SVG, before passing it to the convert

const el = document.querySelector('mySvg')
computedStyleToInlineStyle(el, {
    recursive: true,
    properties: ["font-size", "font-family", "font-weight"]
})

html2canvas(el).then(function(canvas) {
    document.body.appendChild(canvas);
});


All 21 comments

Experiencing the same issue. Is there any temporary fix to this? Using a dropdown to select many Google Fonts, but even though they're displayed correctly on the page, the rendering is wrong (unless i have it installed on my pc).

Temporary fix for me was https://github.com/niklasvh/html2canvas/issues/1709#issuecomment-447798425 by @maximgeerinck

any updates on this? solution from @maximgeerinck didn't work for me

Im also waiting for a fix on this one. Any update?

The same happens to me, any updates on this?

I got it to work by using this module
https://github.com/lukehorvat/computed-style-to-inline-style
to inline the font related styles into the SVG, before passing it to the convert

const el = document.querySelector('mySvg')
computedStyleToInlineStyle(el, {
    recursive: true,
    properties: ["font-size", "font-family", "font-weight"]
})

html2canvas(el).then(function(canvas) {
    document.body.appendChild(canvas);
});


Got it to work by manually adding a style tag inside the SVG element. The style tag will contain the CSS for the font you want to include.
Note that you should download the whole file of CSS for the font including replacing the fonts by their data URIs.

chart: {
    type: 'pie',
    events: {
        redraw: function(event) {
            let style = document.createElement("style"); 
            style.appendChild(document.createTextNode(abelCss));
            const element = document.getElementById(event.target.container.id).firstChild
            element.insertBefore(style, element.firstChild)
        }
    } 
}

You must do this process anytime before running the html2canvas function.
In my case, I had a chart rendered as SVG. So I used this event function that fires when the chart is rendered to include the font CSS.

The library mentioned by @lifeinchords basically does this process for you.

Did not really get this to work. Anyone care to post an complete axample?
My current code at the moment:
bilde

Did not really get this to work. Anyone care to post an complete axample?
My current code at the moment:
bilde

I agree... I took the fiddle in the original post (https://jsfiddle.net/fgppmvxo/8/) and modified it to call computedStyleToInlineStyle before html2canvas, and the results were identical. It would be really nice if this worked.

Does not work for me as well.

The provided solutions do not work here: has anyone got a solution that DOES work? Example of it not working with suggested fix:
https://jsfiddle.net/z1haze/29mucLzw/5/

Temporary fix for me was #1709 (comment) by @maximgeerinck as well. Thanks!

I'm using 1.0.0-rc.7 and a custom font is still not applied to the SVG element I try to export with html2canvas.
@niklasvh could you please reopen this ticket and take a look when you have time? 🙇‍♂️

Pasted_Image_03_12_2020__14_18

Please reopen this @niklasvh

[Quick Fix working with the joint.js Library] : You could inject a custom attribute "font-family" in each svg node :

fontFamilyInjection :

private fontFamilyInjection (targetElem) {
      var svgElem = targetElem.getElementsByTagName("svg");
      for (const node of svgElem) {
        node.setAttribute("font-family", window.getComputedStyle(node, null).getPropertyValue("font-family"));
        node.replaceWith(node);
      }
}

html2canvas :

var domElement: any = document.getElementById('paper');

// Re-inject font-family
this.fontFamilyInjection(domElement);

html2canvas(domElement, { 
   scale: 3,
   allowTaint: true,
   useCORS: true
}).then(canvas => {

          // Do something...

});

@mkubdev can you edit the jsfiddle to demonstrate your example works? It would be a great example.

@garaboncias sure... i'll try. Maybe this is related to Google Font CDN?
You should first need to load the font on the style.css of your app, and then this quick fix should work :

@import url('https://fonts.googleapis.com/css2?family=Kanit&display=swap');

Second, you should try to download directly the 'Kanit' font from GoogleFonts and import it to your app => html2canvas works as expected.

https://jsfiddle.net/1yajtgb4/

I converted the Kanit font to base64 format and still not able to see it applied:
https://jsfiddle.net/fqpcrvb0/
Pasted_Image_04_12_2020__11_53
So the problem is not with the Google Font CDN.

@goliney Damned. You are right. I don't understand why i can't get it to work on jsfiddle but it's working on my apps.

I can make it work on jsfiddle with Jquery's way... This should be convertible to TypeScript : https://jsfiddle.net/9Lvwcnu8/

@mkubdev WOW! This is awesome. Thank you for your help 🍺

In case anyone needs it, here is the @mkubdev's working example without jQuery:
https://jsfiddle.net/jt1a5xv3/
Pasted_Image_04_12_2020__12_55

It's worth mentioning, that with foreignObjectRendering: true option, the font is still not loaded correctly. My app uses this option, unfortunately.
Pasted_Image_04_12_2020__12_57

Was this page helpful?
0 / 5 - 0 ratings