set img.src to dynamic svg element - html

I know that I can set a svg file as the src of an HTML img element like this:
<img src="mySVG.svg"/>
but can I somehow set a dynamic SVG element as the src of an img?
<svg id="mySVGElement">
...
</svg>
<img src="?"/>

You can do this with JavaScript:
var svg = document.querySelector('svg'),
img = document.querySelector('img');
setImageToSVG(img,svg);
function setImageToSVG(img,svg){
var xml = (new XMLSerializer).serializeToString(svg);
img.src = "data:image/svg+xml;charset=utf-8,"+xml;
}​
If your SVG element is dynamic (changing) then you would need to re-run this code each time the SVG element changed.
Demo: http://jsfiddle.net/3PfcC/
Alternatively, here's a demo showing #Robert's answer, using another <svg> element to reference the first, live:
Demo: http://jsfiddle.net/3PfcC/3/
<svg id="src" xmlns="http://www.w3.org/2000/svg" …>
<!-- Your SVG here -->
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:x="http://www.w3.org/1999/xlink" …>
<use x:href="#src" x="80" y="30" width="100" height="100" />
</svg>
The demo also shows that you can resize and otherwise transform the referenced SVG document, and that the reference is live: changes to the original are immediately reflected in the <use>.

This updates the accepted answer from Phrogz (8 years after it!)
The sample does not work on Chrome or Firefox (the image appears broken)
changing to
img.src = "data:image/svg+xml;base64,"+btoa(xml);
I am not sure of the reason why the original stopped working but this may help someone landing here.

Related

Why <use> tag has ziro size? [duplicate]

I've followed many guides to adding external SVGs to a page... like this one : http://wearejh.com/design/inline-svg-use-element/
The code is like this:
<svg>
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>
It just does not load, example here: http://jsbin.com/cipacitovo/edit?html,output
What am I doing wrong?
Per the SVG specification
Unlike ‘image’, the ‘use’ element cannot reference entire files.
You need to add a fragment identifier to the URL to indicate which item within the image you are trying to display.
Why dont you use svg in img tag.Because you are not generating anything instead you are loading.
Check the example
You forgot to add xmlns:xlink="http://www.w3.org/1999/xlink" in <svg>.
This is how it should be:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>

How to <use> the <svg> element correctly for loading external sources?

I've followed many guides to adding external SVGs to a page... like this one : http://wearejh.com/design/inline-svg-use-element/
The code is like this:
<svg>
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>
It just does not load, example here: http://jsbin.com/cipacitovo/edit?html,output
What am I doing wrong?
Per the SVG specification
Unlike ‘image’, the ‘use’ element cannot reference entire files.
You need to add a fragment identifier to the URL to indicate which item within the image you are trying to display.
Why dont you use svg in img tag.Because you are not generating anything instead you are loading.
Check the example
You forgot to add xmlns:xlink="http://www.w3.org/1999/xlink" in <svg>.
This is how it should be:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>

SVG tag <use> doesn't work within polymer component in Firefox

Here is an example: http://miriti.ru/svgtest/
If you'll look at this example in any browser you will see two grey squares with green circles (labled "Symbol") inside. Except for Firefox (I am testing on Firefox 35.0.1 on windows and mac os x).
These SVGs are absolutely identical but the second one is placed inside the polymer component.
Code on GitHub: https://github.com/miriti/svgtest
Any suggestion about what can be the cause of this problem?
I seem to find a workaround for your problem. First of all, wrap your <svg> element with <div id="content">. This is necessary, because later we will reinitialize the inner content of this div.
<template>
<div id="content">
<svg width="400" viewBox="0 0 400 400">
...
</svg>
</div>
</template>
Then in the script section do the following woodoo-magic:
domReady: function() {
this.async(function() {
this.injectBoundHTML(this.$.content.innerHTML, this.$.content);
}, this);
}
Please don’t complain about the weirdness of this trick :)
You are done: FF is satisfied now.
Using SVG sprites I ran into issues that are similar to the one you describe but not the same. So what I propose is not exactly a solution to your problem, however you could avoid such issues altogether by using iron-iconset-svg (https://elements.polymer-project.org/elements/iron-icons?active=iron-iconset-svg), which in my opinion provides a cleaner/easier solution. Its simply a wrapper for your SVG sprite sheet, so you define your icons almost the same way and use them with iron-icon.
Defining a custom iconset (put it directly into the page or wrap it inside an element + set a name that describes the icons, here: 'your-iconset-name')
<iron-iconset-svg name="your-iconset-name" size="24">
<svg>
<defs>
<g id="your-icon-name">
<rect x="12" y="0" width="12" height="24" />
<circle cx="12" cy="12" r="12" />
</g>
</defs>
</svg>
</iron-iconset-svg>
If you wrap them, lets say in 'your-custom-iconset', you can include the iconset like this:
<your-custom-iconset></your-custom-iconset>
Using icons
When you need an icon you just include iron-icons (https://elements.polymer-project.org/elements/iron-icons) and place it like this:
<iron-icon icon="your-iconset-name:your-icon-name"></iron-icon>
You can then give it a class to apply styling and don't need to use 'fill' for its color, just use 'color'.
I fixed it in Polymer 1.0 like this:
attached: function () {
//Fix "svg-use" in Firefox!! -> Properly bad for Performance (Issue: https://github.com/Polymer/polymer/issues/1182)
this.async(function () {
this.$.content.innerHTML = this.$.content.innerHTML;
}, this);
}
but I don't use Bindings in my component (yet)

Best practice for using SVG images?

My research came up with a several ways to insert SVG images inside an html page.
Using <img> is the most simple one but lack of ability as coloring the icons, which is my main need. So, I've read about using <object> but this still doesn't let me styling it using css fill command.
Putting the bulk of <svg> data is also non acceptable since I want to use the images as a refernced images.
I've also read about jQuery solution but I use angularJS.
So, I've read a lot about the ability of SVG Icons, and how better they are rather than the old PNG-Sprite or the IconFonts hype. but unfortunatelly, I cant find any good reference for using it. Can anyone help me here?
tried this already, this doesn't work:
html:
<object data="your.svg" type="image/svg+xml" id="myImage"></object>
css:
#myImage {
fill: #fff;
}
For <img> manupulation, read How to change color of SVG image using CSS (jQuery SVG image replacement)?
For embedding you have 3 choices:-
<object id="myObj" data="image.svg" width="200px" height="200px" type="image/svg+xml"></object>
<embed id="myEmb" src="image.svg" type="image/svg+xml" width="200px" height="200px" ></embed>
<iframe id="myIfr" src="image.svg" width="200" height="200" style="border:0" ></iframe>
Say the image.svg contains this circle in red: <circle id="redcircle" cx="100" cy="100" r="50" fill="transparent" stroke="red" stroke-width="3""/>
To manipulate this color, try this function: ColObj('myObj','blue'), ColObj('myEmb','blue') or ColObj('myIfr','blue')
function getSubDocument(embedding_element)
{
if (embedding_element.contentDocument)
{
return embedding_element.contentDocument;
}
else
{
var subdoc = null;
try {
subdoc = embedding_element.getSVGDocument();
} catch(e) {}
return subdoc;
}
}
function ColObj(elem, color)
{
var elms = document.getElementById(elem);
var subdoc = getSubDocument(elms);
if (subdoc)
subdoc.getElementById("redcircle").setAttribute("stroke", color);
}
This guide from CSS tricks is the best reference I've found so far.
Your options are, unfortunately, pretty limited to use CSS to style an SVG that's not inlined. It involves either embedding the styles inside the SVG file or linking to the stylesheet from within the SVG itself.
Both techniques are discussed in the CSS tricks guide.
Here's a JSFiddle demonstrating the linked CSS technique.
Here's how it works:
Link to the stylesheet from within the CSS and add classes to the individual paths:
<?xml-stylesheet type="text/css" href="mysvg.css"?>
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path class="demo-content" d="M11.31 44.5l12.69-12.3 12.691 12.3 7.809-8.2-12.69-12.3 12.69-12.3-7.809-8.2-12.691 12.3-12.69-12.3-7.81 8.2 12.691 12.3-12.691 12.3 7.81 8.2z" fill="rgb(98.34%, 88.24%, 32.2%)"/>
<path class="demo-border" d="M11.31 44.5l12.69-12.3 12.691 12.3 7.809-8.2-12.69-12.3 12.69-12.3-7.809-8.2-12.691 12.3-12.69-12.3-7.81 8.2 12.691 12.3-12.691 12.3 7.81 8.2z" stroke="#ccc" stroke-linecap="square" fill="none"/>
</svg>
Create the css file, in this case mysvg.css:
.demo-content {
fill: #FF0000;
}
If you're trying to conditionally style the SVG, though, you may have no chose other than embed it.

SVG Pattern Doesn't Show on Page

I am completely clueless, what is going wrong with my svg pattern. I defined it in the def section of the svg and then tried to reference it. But it doesn't show up once I include the svg in an img-tag. If I open it on itself in the browser everything is good though.
See the following examples:
http://kijani.co/img/sketch/index.html
http://kijani.co/img/sketch/livingroom.svg
And my code:
<defs>
<pattern id="paper" patternUnits="userSpaceOnUse" width="200" height="200">
<image xlink:href="http://kijani.co/img/pattern/paper.jpg" width="200" height="200"/>
</pattern>
</defs>
<g id="background">
<path id="paper" fill="url(#paper)" d="..."/>
</g>
This might be a really stupid question, but I am fairly new to svg and couldn't find a solution anywhere so far.
This is svg's referencing mode probrem.
Using img element to display svg image is restrected for refering outer resources.
So you should use object element to display svg image, or embed pattern image into svg by data scheme format.