I am in the process of writing some code to be viewed exclusively in Chrome (Windows and Android) which dynamically generates SVG images. My code goes something like this
<head>
<style>
#font-face
{
font-family:"toolbar";
src:url('https://cdn.jsdelivr.net/fontawesome/4.6.2/fonts/fontawesome-
webfont.ttf') format('truetype');
}
</style>
//font to be packaged as a resource in the APK in due course. My current
//tests are on Chrome in Windows
<script>
$(document).ready(function()
{
var s = Snap('#world');
s.text(821,1385,'').attr({fill:'#FAD411',
"font-size":"10vw","font-family":"toolbar"});
}
</head>
<body>
<div id='svgbox'>
<svg id='world' height="100%" width="100%" viewBox="0 0 2000 2547"
preserveAspectRatio="xMidYMid meet">
//the SVG is created in here dynamically from code
</svg>
</div>
</body>
</html>
While everything else works - and testing that the toolbar font family is actually available in normal html markup succeeds - in the SVG the text displayed is the literal string instead of the Fontawesome cart-plus icon as I expect. What am I doing wrong here.
You have to copy/paste the actual icon into the HTML. See this JSBin for an example. In your source code it will appear as an empty box, but when rendered it will properly display the icon. I copied the icon from the Font Awesome cheatsheet.
var s = Snap('#world');
var text = s.text(821, 1385, '');
text.attr({
fill: '#FAD411',
fontSize: "15vw",
fontFamily: "toolbar"
});
This answer is similar to what you were asking, except the only part that applies to this question is "just put the actual Unicode character you want into your document". No need to worry about the meta tags or encoding types.
Related
I'm importing an svg from file using the <object> element
<object data="img/icons/some-svg.svg" type="image/svg+xml"></object>
From the inspect element tool it's hierarchy appears as follows in the browser
<object data="img/icons/some-svg.svg" type="image/svg+xml">
#document
<svg ...>
...
</svg>
</object>
As I want to change the color of the svg how do I access the encapsulated svg component in the object element?
Here's how you insert a style into a document. The rect element has no colour defined in markup, the green colour comes from the javascript injected style rule.
document.styleSheets[0].insertRule('rect { fill: green; }', 0);
<svg viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100"/></svg>
So now we know how to do that how do we use it with an object tag. Well we need to get the object tag. You could either give it an id and get it by its id or try to find it in the DOM e.g.
let o = document.getElementsByTagName('object')[0];
Then you get its contentDocument i.e.
let doc = o.contentDocument;
and you can use that to insert the style as demonstrated above. I.e.
doc.styleSheets[0].insertRule('rect { fill: green; }', 0);
Unfortunately I can't demonstrate this from start to finish because the contentDocument of a data url is null.
svg {
fill: #ff0000;
}
use this css rule to change the color
I am trying to generate some SVG and allow users of my website to download these SVGs as PNGs.
After reading this I get all my external images included in the downloaded PNG.
Now I am trying to get the fonts on the PNG correct. This seems to answer that and so I added:
<defs>
<style type="text/css">
#font-face {
font-family: Parisienne;
src: url('data:application/font-woff;charset=utf-8;base64,.....')
}
</style>
</defs>
Where ..... is base64 encoded woff2 font. And then used it in text like so:
<text x="55" y="55" stroke="red" font-family="Parisienne">Blah</text>
The font gets displayed in the browser correctly (I haven't installed it on my OS), however it is still not included in the PNG.
Do I have to add some additional processing to the script I used from the first link?
Thanks.
--EDIT--
I have been asked for a complete example, here it is:
<svg id="generated-svg" class="generated-svg" width="300px" height="500px"
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns-xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
#font-face {
font-family: Parisienne;
src: url('data:application/font-woff;charset=utf-8;base64,.....')
}
</style>
</defs>
<rect width="300" height="500" fill="#222"/>
<text x="55" y="55" stroke="red" font-family="Parisienne" font-size="20px">Test text</text>
</svg>
I haven't added the base64 encoded font as it's simply too big. But you can encode any font you like and replace the ....... I am using Parisienne.
Here is working jsfiddle with the actual font: https://jsfiddle.net/z8539err/
In my browser this is the output:
Whilst after using the download script above I would end up with:
I'm able to include the font in the png itself with the following code, give it a try
var svg = document.getElementById('generated-svg');
var svgData = new XMLSerializer().serializeToString( svg );
var canvas = document.createElement("canvas");
canvas.width = 300;
canvas.height = 500;
var ctx = canvas.getContext("2d");
//display image
var img = document.createElement( "img" );
img.setAttribute( "src", "data:image/svg+xml;base64," + btoa( svgData ) );
img.onload = function() {
ctx.drawImage( img, 0, 0 );
//image link
console.log( canvas.toDataURL( "image/png" ) );
//open image
window.location.href=canvas.toDataURL( "image/png" );
};
https://jsfiddle.net/user3839189/hutvL4ks/1/
A working proof of concept project on GitHub to address OP problem statement.
https://github.com/nirus/SVG-PNG-Convert
Built generic Javascript module that can be modified and used anywhere. Read the documentation. Give it a try!
I'm trying to use Icomoon in my blazor project. I've already downloaded the icons.
HTML
<button class="search__button">
<svg class="search__button__icon">
<use xlink:href="img/icons/symbol-defs.svg#magnifying-glass.svg"></use>
</svg>
</button>
CSS
.search__button {
&__icon {
color: #444444;
width: 1.75rem;
height: 1.75rem;
}
}
The location of the SVG files
The result I'm getting
Am I missing something? I think to have followed what it's said in the documentation.
Thanks for helping
EDIT
In this documentation is says that the svg icon can be used as an image like this:
<img class="nav__level-item__icon" src="img/icons/svg/home.svg" alt="home">
When used like this, it's displaying.
&__icon {
width: 1.75rem;
height: 1.75rem;
fill: #fff; //and/or color: #fff
}
The only problem with using it as an image is that I can't style it. So, at the end, I'm still stuck.
EDIT 2
I tried to implement what's suggested in this blog post. Icons are being displayed, I can't still style them.
According to Microsoft SVG use is a still limited, in this Microsoft document it states
If you place an <svg> tag directly into a component file (.razor), basic image
rendering is supported but many advanced scenarios aren't yet supported. For
example, <use> tags aren't currently respected
If you use a string variable for the xlink:href attribute the icon will render after pre-rendering but would disappear as soon as the Blazor library was loaded in the client, but looks like there is a workaround.
Instead of putting the svg and use tags in the .razor file you can return a MarkupString instead, something like
<i class="icon">
#IconMarkupString
</i>
#code {
[Parameter]
public string IconSprite { get; set; }
private MarkupString IconMarkupString
{
get => new MarkupString($"<svg class='icon-sprite'><use xlink:href='{IconSprite}'/></svg>");
}
}
Then used like
<SVGIcon IconSprite="img/icons/symbol-defs.svg#magnifying-glass" />
One thing that I did notice was in order to get the styling to work on the SVG element itself I had to add a separate class to the SVG tag otherwise the styling would not be applied even when using ::deep.
I have an angular material dialog box that I wish to print out.
I have placed as explained here (Can I force a page break in HTML printing?) a page break div like so:
#media print {
.pagebreak { page-break-before: always; }
}
When I do this, the page break is ignored.
I have tested the printing by placing the exact same HTML on a different non-dialog page and it does indeed work as expected.
Is there a way to over-ride the dialog css when printing to allow the page break to work? I think it has something to do with box-sizing as can be seen by the answer of Yuri here: CSS Page-Break Not Working in all Browsers
As on https://developer.mozilla.org/en-US/docs/Web/CSS/break-before
For compatibility reasons, the legacy page-break-before property should be treated by browsers as an alias of break-before
page-break-before is a legacy property, try with break-before
I used page brake in angular component in below way. Apply the style page-brake-before:always inside div tag and this needs to be used inside a table tag. separate with the table tags whenever you want to brake the page.
Hopefully it helps!
app.component.html:
<button mat-icon-button class="float-right" tabindex="-1">
<mat-icon (click)="printROE()">print</mat-icon> </button>
app.component.ts:
printROE(): void {
const w = window.open();
let printHtml = '<html><head><style>.inner-text{font-family: "Open Sans", sans-serif;font-size: 10pt;text-align: justify;}' +
'</style></head><body style="position:relative;">';
printHtml += '<table width="100%" class="inner-text"><thead><title style="font-size:10pt;" align="center"></title></thead><tbody></tbody><tfoot></tfoot></table>';
reportHtml += '<table width="100%" class="inner-text"><tr><div style="page-break-before: always;"></td></tr> </div></tr></table>';
printHtml += reportHtml + '</body><footer></footer></html>';
w.document.write(printHtml);
w.document.close();
setTimeout(() => {
w.focus();
w.print();
w.close();
}, 900);
}
I'm building a dummy widget for a iGoogle/Netvibes like portal. This is a "Google Maps" widget, as it only renders a map centered on a specific location.
The widget looks good in all browsers but IE8, in which the height I specify to the <div> that contains the map is not taken into account.
Here's the interesting part of the code:
<body onload="initialize()" >
<div id="map_canvas" style="height:400px; width: 100%;"></div>
</body>
I have no control on the portal, so the only thing I can modify is the widget itself. I also tried to set the height for the <body>, but same thing.
Any idea on why it's not working in IE?
Thanks!
Put this in the page you're calling with the iframe:
<script type="text/javascript">
var iframes = window.parent.document.getElementsByTagName('iframe');
for(var i = 0; i < iframes.length; i ++)
{
if(iframes[i].src == window.location)
{
iframes[i].style.height = '400px';
}
}
</script>
If you are on 2 different domains, this isn't possible, and unfortunately there is no other way when supplying the <iframe> directly to the end-user. The best solution would be to instead give the user a script tag that generates the <iframe> tag using a document.write()
Example script tag to give to your client:
<script type="text/javascript" src="http://www.example.com/widget-getter.js?client=[clientid]&widget=[widgetid]"></script>
Contents of the script that the above tag would call:
document.write('<iframe height="400px" src="http://www.example.com/widget.html"></iframe>');
Did you try using the height attribute of the iframe tag?