I'm trying to draw Font Awesome duotone icons on an HTML 5 canvas but not sure how to get the duotone version of the icon, and color it properly. For example this code from this answer will draw a solid version of the icon:
ctx.font='30px FontAwesome';
ctx.fillText('\uF047',20,50);
But I don't know how to modify this code to draw each part of a duotone icon instead.
CodePudding user response:
FontAwesome DuoTone works by styling both a ::before
and an ::after
pseudo-element differently, while both will have their own glyph to render one part of the icon.
To get the same effect on the <canvas>
, you need to first set your context's font
property to the proper duotone font-family (e.g 'Font Awesome 6 DuoTone'
) so that you can get access to the "separated glyphs" of each icon.
Then, you'll have to set the styles of each part as you wish before you draw them.
Below you'll find a simple helper.
function drawDuoTone (ctx, glyph, x, y, {
fontSize = 30,
primaryColor = "#183153",
secondaryColor = primaryColor,
primaryOpacity = 1,
secondaryOpacity = primaryOpacity
} = {}) {
ctx.font = `${fontSize}px 'Font Awesome 6 DuoTone'`;
// ::before
ctx.fillStyle = primaryColor;
ctx.globalAlpha = primaryOpacity;
ctx.fillText(glyph, x, y);
// ::after
ctx.fillStyle = secondaryColor;
ctx.globalAlpha = secondaryOpacity;
// currently ::after glyph code is just the main code repeated twice
ctx.fillText(glyph.repeat(2), x, y);
}
// make sure the font is properly loaded and ready to use
document.fonts.load("30px 'Font Awesome 6 DuoTone'").then(() => {
const ctx = document.querySelector("canvas").getContext("2d");
drawDuoTone(ctx, "\uf047", 20, 50, { secondaryOpacity: 0.4 });
drawDuoTone(ctx, "\uf240", 80, 50, {
primaryColor: "limegreen",
secondaryColor: "dimgray"
});
});
@import "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css";
/*
Not sure this is legal, please don't link to that file in your own project,
I claim fair use here since it's only to expose how to make it work,
but these fonts are supposed to be behind a paywall, so pay it please.
*/
@import "https://site-assets.fontawesome.com/releases/v6.2.1/css/all.css";
<canvas></canvas>