admin管理员组文章数量:1291121
I want to render a FontAwesome icon as an SVG dynamically provide it as an image source using Javascript. I want my output to be something like this
PS - I will draw the circle myself. Just need a way to render the icon.
So far, I have tried this approach:
function addSVG() {
var ele = document.getElementById("svg");
var svg = `<svg xmlns="" width="50" height="50">
<text x="4" y="15" style="font-family: FontAwesome" fill="red"></text>
</svg>`
var output = 'data:image/svg+xml;base64,' + btoa(svg)
ele.src = output;
}
addSVG()
<head>
<link href=".4.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body>
What it should look like:
<svg xmlns="" width="20" height="20">
<text x="4" y="15" style="font-family: FontAwesome" fill="red"></text>
</svg>
What it looks like:
<img id="svg">
</body>
I want to render a FontAwesome icon as an SVG dynamically provide it as an image source using Javascript. I want my output to be something like this
PS - I will draw the circle myself. Just need a way to render the icon.
So far, I have tried this approach:
function addSVG() {
var ele = document.getElementById("svg");
var svg = `<svg xmlns="http://www.w3/2000/svg" width="50" height="50">
<text x="4" y="15" style="font-family: FontAwesome" fill="red"></text>
</svg>`
var output = 'data:image/svg+xml;base64,' + btoa(svg)
ele.src = output;
}
addSVG()
<head>
<link href="https://maxcdn.bootstrapcdn./font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body>
What it should look like:
<svg xmlns="http://www.w3/2000/svg" width="20" height="20">
<text x="4" y="15" style="font-family: FontAwesome" fill="red"></text>
</svg>
What it looks like:
<img id="svg">
</body>
As you can see, without the Javascript (just using SVG in HTML) it works fine.
Share Improve this question edited Jul 5, 2018 at 19:19 Frame91 3,7998 gold badges47 silver badges95 bronze badges asked Jul 5, 2018 at 17:20 Janit MehtaJanit Mehta 1851 silver badge11 bronze badges 2- Which version of Font Awesome (looks like 4.4, from the CDN reference)? Have you reviewed this already? fontawesome./how-to-use/on-the-web/setup/… – Tieson T. Commented Jul 5, 2018 at 19:29
- 1 Yes, the question of which version of Font Awesome would make a big difference on the answer. Font Awesome 5 has built in methods of rendering SVG icons, so the approach in v5 may be very different than if you were limited to v4. And I would wonder whether it's necessary to implement it as an <img src= ... > or if your ultimate goal is simply to get the oute of an svg icon over a background circle. If the latter, then there are much more straightforward approaches in v5. – mwilkerson Commented Jul 6, 2018 at 4:04
4 Answers
Reset to default 4Why do you need it in img tag? SVG is an image! You do not need it to put in something else.
May be I do not know something from you, but I think this is just a bad idea from you.
My suggestion: put SVG in HTML with font-awesome icons directly:
Your benefit from this: all modern browsers support it without any limits like in img tags or as background image.
var divSvg = document.getElementById('svg'),
pics =
{
user: {col: '00a', icon: 'f007'},
home: {col: '08c', icon: 'f015'},
folder: {col: '88f', icon: 'f07c'},
gear: {col: '5a0', icon: 'f013'},
flag: {col: '05a', icon: 'f024'},
leaf: {col: '080', icon: 'f06c'}
},
svg =
'<svg xmlns="http://www.w3/2000/svg" width="32" height="32">\
<text x="4" y="24" fill="COLOR" style="font:24px FontAwesome;cursor:pointer">PIC</text>\
</svg>';
for(var title in pics)
{
var newSVG = svg.replace('PIC', '&#x'+pics[title].icon+';');
//we put it in "B" tag to have a title because IE
//does not support title attribute and title tag in SVG
divSvg.innerHTML += '<b title="' + title + '">' +
newSVG.replace('COLOR', '#'+pics[title].col) + '</b>';
}
divSvg.onclick = function(e)
{
if(e.target.tagName == 'text')
{
document.getElementById('output').innerHTML = 'Was clicked on ' +
// we take title from "B" tag:
e.target.parentNode.parentNode.title;
/* if you need you can use:
switch(e.target.parentNode.parentNode.title)
{
case 'user': alert('Here some procedure with user');
case ... YOUR CODE
and so on... YOUR CODE
}*/
}
}
<link href="https://maxcdn.bootstrapcdn./font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet">
<div id="svg"></div><br>
<div id="output">Please click on any icon.</div>
You can't use an <img>
element when referencing an external CSS stylesheet from XML. You need to use an <object>
element like this answer remends, and prepend an <?xml-stylesheet?>
processing instruction in order for the SVG+XML blob to be able to find the FontAwesome glyph for the HTML entity 
.
function addSVG() {
var ele = document.getElementById("svg");
var svg = `
<?xml-stylesheet type="text/css" href="https://maxcdn.bootstrapcdn./font-awesome/4.4.0/css/font-awesome.min.css"?>
<svg xmlns="http://www.w3/2000/svg" width="20" height="20">
<text x="4" y="15" style="font-family: FontAwesome" fill="red"></text>
</svg>`
var output = `data:image/svg+xml;utf8,${svg}`
ele.type = 'image/svg+xml';
ele.data = output;
}
addSVG()
<head>
<link href="https://maxcdn.bootstrapcdn./font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body>
What it should look like:
<svg xmlns="http://www.w3/2000/svg" width="20" height="20">
<text x="4" y="15" style="font-family: FontAwesome" fill="red"></text>
</svg> What it looks like:
<object id="svg"></object>
</body>
You don't need to convert the data into base64. I think the SVG syntax doesn't have any "crazy" characters in it, so it's safe to use.
Set the encoding to UTF-8, and drop the <svg> in there:
'data:image/svg+xml;utf8,<svg ... > ... </svg>'
As mented you should first try to find a svg repository (Also described her: "Extracting SVG from Font Awesome".
SVG won't embed any fonts automatically
However you could actually create a self contained svg including the used font.
- Find download URL e.g from a cdn like https://www.cdnpkg.
- Download the font
- Create a
@font-face
with a data URL font source via a tool like transfonter - you can also specify a subset to include only the needed glyphs/characters
Example1: svg with embedded font
<h3>Stand alone SVG</h3>
<svg xmlns="http://www.w3/2000/svg" width="20" height="20" viewBox="0 0 20 20">
<style>
@font-face {
font-family: 'FontAwesome';
src: url('data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAM4AAwAAAAAB2gAAALqAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYGYAA8EQgKgSSBPAsMAAE2AiQDFAQgBYhrBzEbnwYRFZyXyH4mZG5HaVZSDpHqn35J3i05r0RQv/bv95yFezfArIE9ADhgtnGpCJuKfy6EnwC3ImZ83+V4KEOEam9MHNuyfeD+rdGUZSQB4P///XqeNSAFvAH8vjMZWDZWidXLI3GaevlggiVGAQ/4AH4S/INug74YVWXlpRcTaANIQsiFrJwV1xXkl/M4CyabdhEXgbfZfmDnLgz4sVGqUQoIAAwQSMjQRSbQRW4ESrmQYjvqGqSz/qT9f9TnRF1LoACtkGMCFgNykAApzwc0l7Q91Gb/ofYHDh1/1arDxdfjxBuooPWl13SXFIIP8ffJV5dfP/XGlQ+2tSgGtDSK60o3lSx1av//4q8+IOz9DcuNXXYvNoSrdzM3Dp9SzRg1Pzg96uxpkmnGaoqVOTFn5sW8uSDu7IupH37IXRsI5FFuu798x5r2k39rtm6Ah/PugOfvzf6w/u7/r6qq7ISmBIIWXVqpv6vrqiL/m1Bkx22HtIhooTiOQJF6Gg4SQmA6gB4xTADGI0BobbwAScNEATLdzRAg19lSAQqdbBKgjIeGeY6gqY0nqLTyNlrr6tP17fTzVybyCquju47QLfYgaReXkBkXN5AbFndRGBLf5ZcwGm4laOqRbqPSJT1Ea6PSB13tTM6qmRIA2/IbdDiyos/KyhZezlkv/9WHnje0rD6Y6LLvgHF0pSwJqJdwvmfRUSjZyYExUKzGSV+2BCQcNsUVRvbDMORKxzpxr2HFn2xJVxKzqIvKsizj6iI7JqO4Wnavr6rBQadXur+uZ5th/JmqKC1t+Q06cJ/9yHPcUNGqbSmGRky3gMC8kan90NvVBzJ0OKN4tWxyHkaWFNawhMvxfItReuI7NFVIJwWKz3fqsOrYggXl5udOsoM4uAS1TrTgadPuzgcTXpeXkGy/NpyhY9MQW2uqxysFXk8m9xPScjxThMjUfUNlirXjUuu8CznOuFQ1hLLrtiRf0Av0HKMvjkUtkfLdDQA=') format('woff2');
font-weight: normal;
font-style: normal;
font-display: swap;
}
</style>
<circle cx="50%" cy="50%" r="50%" fill="red"/>
<text x="4" y="15" style="font-family: FontAwesome" fill="white"></text>
</svg>
<h3>Img with SVG data URL</h3>
<img src="data:image/svg+xml, %3Csvg xmlns='http://www.w3/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cstyle%3E%0A@font-face %7B font-family: 'FontAwesome'; src: url('data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAM4AAwAAAAAB2gAAALqAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYGYAA8EQgKgSSBPAsMAAE2AiQDFAQgBYhrBzEbnwYRFZyXyH4mZG5HaVZSDpHqn35J3i05r0RQv/bv95yFezfArIE9ADhgtnGpCJuKfy6EnwC3ImZ83+V4KEOEam9MHNuyfeD+rdGUZSQB4P///XqeNSAFvAH8vjMZWDZWidXLI3GaevlggiVGAQ/4AH4S/INug74YVWXlpRcTaANIQsiFrJwV1xXkl/M4CyabdhEXgbfZfmDnLgz4sVGqUQoIAAwQSMjQRSbQRW4ESrmQYjvqGqSz/qT9f9TnRF1LoACtkGMCFgNykAApzwc0l7Q91Gb/ofYHDh1/1arDxdfjxBuooPWl13SXFIIP8ffJV5dfP/XGlQ+2tSgGtDSK60o3lSx1av//4q8+IOz9DcuNXXYvNoSrdzM3Dp9SzRg1Pzg96uxpkmnGaoqVOTFn5sW8uSDu7IupH37IXRsI5FFuu798x5r2k39rtm6Ah/PugOfvzf6w/u7/r6qq7ISmBIIWXVqpv6vrqiL/m1Bkx22HtIhooTiOQJF6Gg4SQmA6gB4xTADGI0BobbwAScNEATLdzRAg19lSAQqdbBKgjIeGeY6gqY0nqLTyNlrr6tP17fTzVybyCquju47QLfYgaReXkBkXN5AbFndRGBLf5ZcwGm4laOqRbqPSJT1Ea6PSB13tTM6qmRIA2/IbdDiyos/KyhZezlkv/9WHnje0rD6Y6LLvgHF0pSwJqJdwvmfRUSjZyYExUKzGSV+2BCQcNsUVRvbDMORKxzpxr2HFn2xJVxKzqIvKsizj6iI7JqO4Wnavr6rBQadXur+uZ5th/JmqKC1t+Q06cJ/9yHPcUNGqbSmGRky3gMC8kan90NvVBzJ0OKN4tWxyHkaWFNawhMvxfItReuI7NFVIJwWKz3fqsOrYggXl5udOsoM4uAS1TrTgadPuzgcTXpeXkGy/NpyhY9MQW2uqxysFXk8m9xPScjxThMjUfUNlirXjUuu8CznOuFQ1hLLrtiRf0Av0HKMvjkUtkfLdDQA=') format('woff2'); font-weight: normal; font-style: normal; font-display: swap;%0A%7D %3C/style%3E%3Ccircle cx='50%25' cy='50%25' r='50%25' fill='red'/%3E%3Ctext x='4' y='15' style='font-family: FontAwesome' fill='white'%3E&%23xf007;%3C/text%3E%3C/svg%3E" alt="">
The data URL can also be used as css background-image.
Convert icon font to svg <path>
You can also fetch a fontAwesome font file and convert it to a svg using opentype.js.
This way your new icon can also be edited in a graphic application like inkscape, Adobe Illustrator etc.
Example 2: convert icon font
// absolute URL to fontFile
let fontURL =
"https://maxcdn.bootstrapcdn./font-awesome/4.4.0/fonts/fontawesome-webfont.woff2";
// font awesome character as entity
let text = decodeHtmlEntity("");
// define size and padding
let fontSize = 100;
let padding = 15;
let iconColor = '#fff';
let bgColor = 'red';
/**
* load font
* convert to svg pathdata
*/
(async () => {
let font = await loadFont(fontURL);
// get font metrics for positioning and scaling
let unitsPerEm = font.unitsPerEm;
let ratio = fontSize / unitsPerEm;
let ascender = font.ascender;
let glyph = font.stringToGlyphs(text)[0];
let bb = glyph.getBoundingBox();
let xOff = (fontSize - bb.x2 * ratio) / 2;
// get pathdata
let width = fontSize + padding;
let height = fontSize + padding;
let pathD = font
.getPath(text, xOff + padding / 2, ascender * ratio + padding / 2, fontSize)
.toPathData();
let ns = "http://www.w3/2000/svg";
let svg = document.createElementNS(ns, "svg");
let circle = document.createElementNS(ns, "circle");
let path = document.createElementNS(ns, "path");
//svg.setAttribute('viewBox', `0 0 ${+width.toFixed(3)} ${fontSize}` );
svg.setAttribute(
"viewBox",
`0 0 ${width} ${height}`
);
svg.setAttribute("width", width);
svg.setAttribute("height", height);
circle.setAttribute("cx", "50%");
circle.setAttribute("cy", "50%");
circle.setAttribute("r", "50%");
circle.setAttribute("fill", bgColor);
path.setAttribute("d", pathD);
path.setAttribute("fill", iconColor);
svg.append(circle);
svg.append(path);
preview.append(svg);
// create dataURL
let dataURl =
"data:image/svg+xml, " +
new XMLSerializer()
.serializeToString(svg)
.replaceAll('"', "'")
.replaceAll("#", "%23");
imgData.src = dataURl;
})();
/**
* opentype.js helper
* Based on @yne's ment
* https://github./opentypejs/opentype.js/issues/183#issuement-1147228025
* will depress woff2 files
*/
async function loadFont(src, options = {}) {
let buffer = {};
let font = {};
let ext = "woff2";
let url;
// 1. is file
if (src instanceof Object) {
// get file extension to skip woff2 depression
let filename = src.name.split(".");
ext = filename[filename.length - 1];
buffer = await src.arrayBuffer();
}
// 2. is base64 data URI
else if (/^data/.test(src)) {
// is base64
let data = src.split(";");
ext = data[0].split("/")[1];
// create buffer from blob
let srcBlob = await (await fetch(src)).blob();
buffer = await srcBlob.arrayBuffer();
}
// 3. is url
else {
// if google font css - retrieve font src
if (/googleapis./.test(src)) {
ext = "woff2";
src = await getGoogleFontUrl(src, options);
}
// might be subset - no extension
let hasExt =
src.includes(".woff2") ||
src.includes(".woff") ||
src.includes(".ttf") ||
src.includes(".otf")
? true
: false;
url = src.split(".");
ext = hasExt ? url[url.length - 1] : "woff2";
let fetchedSrc = await fetch(src);
buffer = await fetchedSrc.arrayBuffer();
}
// depress woff2
if (ext === "woff2") {
buffer = Uint8Array.from(Module.depress(buffer)).buffer;
}
// parse font
font = opentype.parse(buffer);
return font;
}
function decodeHtmlEntity(str) {
let txt = document.createElement("p");
txt.innerHTML = str;
str = txt.textContent;
txt.remove();
return str;
}
svg{
border: 1px solid #ccc;
width:20em;
height:auto;
}
img{
border: 1px solid #ccc;
width:20em;
}
<h3>SVG</h3>
<div id="preview"></div>
<h3>Img</h3>
<img id="imgData" src="">
<script src="https://unpkg./[email protected]/build/depress_binding.js"></script>
<script src='https://cdn.jsdelivr/npm/opentype.js@latest/dist/opentype.min.js'></script>
本文标签: htmlHow to render FontAwesome as SVG Image using JavascriptStack Overflow
版权声明:本文标题:html - How to render FontAwesome as SVG Image using Javascript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741515769a2382877.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论