html-to-image icon indicating copy to clipboard operation
html-to-image copied to clipboard

Load fonts from document.fonts

Open nihey opened this issue 3 years ago • 23 comments

Hi there, html-to-image is great lib for us!

Expected Behavior

It would be good if it loaded fonts from documents.fonts too. Loading the fonts from document.fonts would solve this issue and give a more consistent result with the UI.

Currently, it appears that only the fonts that are on a @font-face in a <style> tag are loaded for the screenshot

Possible Solution

We can use document.fonts.entries() to iterate over all loaded fonts and use it to load the fonts in the same way it is done in CSS. It could possibly replace the currently adopted solution as fonts loaded through CSS appear on document.fonts too.

Additional Context

I'm working on a product that loads fonts directly into document.fonts, because we load fonts dynamically based on some user inputs. The fonts are rendered on the HTML without problems, but they just don't appear on the screenshot.

I've currently worked this out on our product by dynamically injecting the <style> element with the @font-face too. But I believe it would be good for this lib to support it directly too.

I would be willing to contribute.

Our UI

Screenshot from 2021-11-11 20-23-49

Screenshot (the text at the top is actually an image, so it appears in the same way)

videomatik-screenshot (21)

Expected Result

videomatik-screenshot (22)

nihey avatar Nov 11 '21 23:11 nihey

👋 @nihey

Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

biiibooo[bot] avatar Nov 11 '21 23:11 biiibooo[bot]

+1.

jessejamesrich avatar Nov 14 '21 15:11 jessejamesrich

I seem to have the same issue. I use the Gothic A1 font which shows nice on the rendered HTML (in Chrome, Edge and Firefox on Windows 10) but not in the captured .png file. Everything else works great (transparency, colors, size) but the font is not picked up.

I am using a .Net Blazor wasm app to do the work, took me a while to get it working which was mostly due to my inexperience with Javascript, Node, and Webpack. I could mimimize the app and make it available as a public repo if this helps in the diagnosis, but I doubt it would as you would potentially suffer from the reverse problem: inexperience with .Net and Blazor ;-). Just let me know though

I have attached a screenshot that clearly demonstrates the problem:

Font-problem

hugh-maaskant avatar Dec 20 '21 17:12 hugh-maaskant

OK, after some more testing I found the following:

  1. Delaying the call to htmlToImage.toPng() in the hope that the fonts were not yet downloaded from fonts.google.com did not help. So it is not an issue of the font not yet being available.
  2. Installing the font on the local machine solved the problem. This is sufficient in my case, but obviously not in the general case

Hope this helps in the diagnosis!

hugh-maaskant avatar Dec 21 '21 11:12 hugh-maaskant

+1

noeRls avatar Jan 13 '22 09:01 noeRls

+1

eyeris-ovidiumiu avatar Feb 28 '22 19:02 eyeris-ovidiumiu

+1

noeRls avatar Mar 22 '22 18:03 noeRls

Someone kill this bot, please. Bump

luigimannoni avatar May 03 '22 15:05 luigimannoni

Bump

luigimannoni avatar May 25 '22 07:05 luigimannoni

+1

noeRls avatar Jun 22 '22 17:06 noeRls

+1

noeRls avatar Jul 13 '22 18:07 noeRls

+1

noeRls avatar Aug 22 '22 17:08 noeRls

It would be great to support fonts loaded with the documents.fonts API. html2canvas supports this feature. But I prefer html-to-image as it's faster and renders text better.

Meanwhile, a way to load fonts asynchronously and use them with html-to-image is:

const urlToFontFile = 'something';
const fontName = 'something';

const response = await fetch(urlToFontFile);
const fontArrayBuffer = await response.arrayBuffer();

const style = document.createElement('style');
style.textContent = `
  @font-face {
    font-family: '${fontName}';
    src: url(${fontArrayBuffer});
  }
`;
document.head.appendChild(style);

const nodeWithCustomFontFace = document.createElement('div');
nodeWithCustomFontFace.style.fontFace = fontName;
nodeWithCustomFontFace.textContent = 'I look pretty';

const myCanvas = await htmlToImage.toCanvas(nodeWithCustomFontFace); // It should render with the custom font

AntonioRedondo avatar Nov 14 '22 13:11 AntonioRedondo

+1

swaree avatar Feb 17 '23 13:02 swaree

It would be great to support fonts loaded with the documents.fonts API. html2canvas supports this feature. But I prefer html-to-image as it's faster and renders text better.

Meanwhile, a way to load fonts asynchronously and use them with html-to-image is:

const urlToFontFile = 'something';
const fontName = 'something';

const response = await fetch(urlToFontFile);
const fontArrayBuffer = await response.arrayBuffer();

const style = document.createElement('style');
style.textContent = `
  @font-face {
    font-family: '${fontName}';
    src: url(${fontArrayBuffer});
  }
`;
document.head.appendChild(style);

const nodeWithCustomFontFace = document.createElement('div');
nodeWithCustomFontFace.style.fontFace = fontName;
nodeWithCustomFontFace.textContent = 'I look pretty';

const myCanvas = await htmlToImage.toCanvas(nodeWithCustomFontFace); // It should render with the custom font

How to handle local fonts? Fetch local fonts file is not work.

webpig avatar Mar 24 '23 07:03 webpig

+1

davinun99 avatar Jul 07 '23 19:07 davinun99

Specifically for me I fixed this issue by turning off the chrome extension Dark Reader. It was affecting how the module was grabbing styleSheets.

PattyRich avatar Jul 25 '23 07:07 PattyRich

+100

simonsankar avatar Nov 27 '23 16:11 simonsankar

I was able to fix my case with https://github.com/bubkoo/html-to-image/issues/207

suryasanchez avatar Dec 31 '23 04:12 suryasanchez

+1

mrold avatar Feb 22 '24 07:02 mrold

+1

GlebBigma avatar Mar 13 '24 13:03 GlebBigma

I am loading google fonts dynamically and its an editor where I want to take the screenshot, so please add the support for document.fonts.

ashiq-prospero avatar Apr 25 '24 14:04 ashiq-prospero