I am using the new OffscreenCanvas released in Chrome 69 and cannot seem to render custom loaded fonts that render to ordinary canvases just fine.
Is there a trick to getting a custom font available in the worker so that the OffscreenCanvas can access it?
You should be able to use the FontFace and FontFaceSet interfaces of the CSS Font Loading API from within a Worker.
The main difference is that instead of accessing through document.fonts
, the FontFaceSet is stored as self.fonts
directly.
const worker = new Worker(generateURL(worker_script));
worker.onmessage = e => {
const img = e.data;
if(typeof img === 'string') {
console.error(img);
}
else
renderer.getContext('2d').drawImage(img, 0,0);
};
function generateURL(el) {
const blob = new Blob([el.textContent]);
return URL.createObjectURL(blob);
}
<script type="worker-script" id="worker_script">
if(self.FontFace) {
// first declare our font-face
const fontFace = new FontFace(
'Shadows Into Light',
"local('Shadows Into Light'), local('ShadowsIntoLight'), url(https://fonts.gstatic.com/s/shadowsintolight/v7/UqyNK9UOIntux_czAvDQx_ZcHqZXBNQzdcD55TecYQ.woff2) format('woff2')"
);
// add it to the list of fonts our worker supports
self.fonts.add(fontFace);
// load the font
fontFace.load()
.then(()=> {
// font loaded
if(!self.OffscreenCanvas) {
postMessage("Your browser doesn't support OffscreeenCanvas yet");
return;
}
const canvas = new OffscreenCanvas(300, 150);
const ctx = canvas.getContext('2d');
if(!ctx) {
postMessage("Your browser doesn't support the 2d context yet...");
return;
}
ctx.font = '50px "Shadows Into Light"';
ctx.fillText('Hello world', 10, 50);
const img = canvas.transferToImageBitmap();
self.postMessage(img, [img]);
});
} else {
postMessage("Your browser doesn't support the FontFace API from WebWorkers yet");
}
</script>
<canvas id="renderer"></canvas>