How to output a svg file from the web page? - javascript

<svg class="paint" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect class="svgobject" x="458" y="165.28750610351562" width="142" height="56" fill="black" stroke="black" id="154" transform="translate(0,0)">
</rect>
</svg>
For example, I have a web page, which contains a svg child element like above, then how could I build up a function that could extract the svg part and then save locally as .svg? Any help is appreciated

This seems to do what you're asking for using HTML5 download:
<a href='{svg content}' download='test.svg'><svg>...</svg></a>
http://jsfiddle.net/GdCcA/1043/
Also, might be worth checking out:
https://github.com/eligrey/FileSaver.js/

Related

Svg fill color update

I'm very new to HTML, SVG, javascript and all what is web programming.
I need to do a synoptic webpage to display different information's on my data acquisition.
I have a python script which read data from physical devices and I'd like to update these acquisition on a web page. My python script can change svg file fill color of different graphical components.
If , for example, this is my svg file:
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_1">
<title>Layer 1</title>
<rect id="svg_1" height="386" width="527" y="94" x="150" stroke="#231F20" fill="yellow"/>
<rect id="svg_2" height="386" width="527" y="114" x="450" stroke="#231F20" fill="yellow"/>
</g>
</svg>
how could I upload new color on the svg file object without reloading the page?
For example I'd like to change id="svg_1" fill color from "yellow" to red according to my python scrip. How can I do it and display immediately?
Thanks,
Marcin

Load external SVG icons into vanilla JavaScript code

I am using the OpenWeather API to display the current and five day forecast on my client's website.
I have some custom SVG icons that I want to use instead of the icons provided by OpenWeather. I have implemented the following switch statement to display a different icon depending on the weather condition.
let dailyCondition = value.weather[0].description;
let dailyCondtionIcon = "";
switch (dailyCondition) {
case "clear sky":
dailyConditionIcon = `<svg>icon</svg>`;
break;
case "few clouds":
dailyConditionIcon = `<svg>icon</svg>`;
break;
case "thunderstorm":
dailyConditionIcon = `<svg>icon</svg>`;
break;
case "light rain":
dailyConditionIcon = `<svg>icon</svg>`;
break;
}
Accessing the icons from template literal code works, but with lots of weather conditions in the switch statement, the code is very bloated. I would like to have the SVG icons stored in an external file and loaded from there.
How would I go about loading the external SVG icons into my vanilla JavaScript file?
If you prefer external svg files you could load them in a <use> element.
See also SVG use with External Source
You can combine all svg icons to a single sprite/asset library svg file and then loading each icon individually by a fragment identifier:
You js definitions might look something like this:
dailyConditionIcon = '<svg class="svgInline" fill="red" ><use href="sprite.svg#circle" /></svg>'
.svgAssets{
display:none
}
.svgInline{
display:inline-block;
width:1em;
height:1em;
font-size:32px;
}
<!-- this would be the content of your "sprite.svg" -->
<svg class="svgAssets" xmlns="http://www.w3.org/2000/svg">
<symbol viewBox="0 0 100 100" id="circle">
<circle cx="50%" cy="50%" r="50%"></circle>
</symbol>
<symbol viewBox="0 0 100 100" id="rect">
<rect x="0" y="0" width="100" height="100"></rect>
</symbol>
<symbol viewBox="0 0 100 100" id="rectFixedStyle">
<rect x="0" y="0" width="100" height="100" fill="#ccc"></rect>
</symbol>
</svg>
<!--
for demonstration the filenames are dropped.
The href of a hosted version would be e.g
<use href="sprite.svg#circle" />
-->
<p>
<svg class="svgInline" fill="red" >
<use href="#circle" />
</svg>
<svg class="svgInline" fill="green" >
<use href="#rect" />
</svg>
<svg class="svgInline" fill="green" >
<use href="#rectFixedStyle" />
</svg>
</p>
As you can see you also have some styling abilities like changing fill color.
However the styling options are limited (compared to fully inlined svg) and also depend on your svg structure:
E.g. Styles previously definded in your svg elements can't be overriden by a style set in use/svg tag.
For sprite creation I used: svgsprit.es

How would I add custom SVG shapes to an equation generated with MathJax?

I'd like to use MathJax to write various equations that include SVG shapes along the lines of the following:
(2 * [red box]) + [red box] = [three red boxes]
Where each item in brackets would be a custom SVG element defined in the HTML ranging from simple (a single box) to more complex (multiple shapes). The reason for needing this is that I want to use MathJax's ability to format math equations while replacing some symbols with SVG shapes. I may need to specify other HTML as well.
I suspect this can be achieved by using MathJax's HTML snippets but I don't know how to take the sample code they provide and make it work for any given equation.
Any help would be greatly appreciated.
If you are using MathML input, you can use the <mglyph> element to include an svg image into your expression, as in:
<math>
<mglyph src="dice.svg" height="42px" width="42px" valign="-14px" alt="Dice showing five dots"></mglyph>
</math>
or even
<math>
<mglyph src='data:image/svg+xml,
<svg xmlns="http://www.w3.org/2000/svg" height="42px" width="42px">
<rect stroke="black" fill="none" x="1px" y="1px" stroke-width="2px" rx="5px" width="40px" height="40px"></rect>
<circle stroke="black" fill="black" cy="30px" cx="30px" r="5px"></circle>
<circle stroke="black" fill="black" cy="30px" cx="10px" r="5px"></circle>
<circle stroke="black" fill="black" cy="20px" cx="20px" r="5px"></circle>
<circle stroke="black" fill="black" cy="10px" cx="30px" r="5px"></circle>
<circle stroke="black" fill="black" cy="10px" cx="10px" r="5px"></circle>
</svg>'
valign="-14px"
alt="Dice showing five dots">
</mglyph>
</math>
If you are using TeX input, you can create the mglyph using the \mmlToken macro:
\mmlToken{mglyph}[src="dice.svg" width="42px" height="42px" valign="-14px" alt="Dice showing five dots"]{}
You can also use the "img" extension from the third-party extension library. This defines an \img macro that makes loading the image a bit easier:
\img[-14px][42px][42px]{dice.svg}
I think you should be able to do what you want using one of those.
(This is my response to the cross-post on the MathJax User's Forum)

Why doesn't my dynamically created <use> element show?

With JavaScript and jQuery I'm trying to replace a group element with a use element linking to another group element.
// Javascript
origgroup = $("#origgroup")[0];
repgroup = $("#referenceGroup1")[0];
origgroupParent = origgroup.parentNode;
use = document.createElementNS("http://www.w3.org/2000/svg", "use");
use.setAttribute("xlink:href", "#origgroup2");
use.setAttribute("id", "newuse");
tmp = origgroupParent.replaceChild(use, origgroup);
// After this snippet is run, "targetsvg" and "control" are identical. Except that targetsvg's use-tag has an unique ID.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- My "atlas". I want to put <use> elements in "targetsvg" below, linking to these groups. -->
Atlas <br>
<svg id="atlas" width="120" height="70" version="1.1">
<g id="referenceGroup1">
<rect x="10" y="10" width="90" height="20" fill="green"/>
<circle cx="20" cy="40" r="15" fill="blue"/>
</g>
<g id="referenceGroup2">
<rect x="40" y="10" width="90" height="20" fill="red"/>
<circle cx="50" cy="40" r="15" fill="orange"/>
</g>
</svg>
<br> Target <br>
<!-- My target -->
<svg id="targetsvg" width="120" height="70" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="origgroup">
<rect x="40" y="10" width="90" height="20" fill="red"/>
<circle cx="50" cy="40" r="15" fill="orange"/>
</g>
</svg>
<br>
Control
<br>
<!-- This is identical to the javascript modified version of "targetsvg" -->
<svg id="control" width="120" height="70" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="#referenceGroup1"></use>
</svg>
What I expect to happen is for there to be a blue circle and a green rectangle under "Target". If I inspect the resulting svg of "targetsvg" it's identical to the svg under "Control". This leads me to believe that "targetsvg" is not redrawn for some reason, is this correct? Is there a way to force that?
I've spent the last five hours searching, but I can't find anything similar. The most relevant I've found is
SVG <use> in Chrome doesn't work
But that uses Angular, which I'm not. I think the cause is the same ("the relative hash link in the element would not correctly resolve."). But if this is the case, how do I resolve this without Angular?
Thanks!
[Background: I have a huge svg-file generated from illustrator. In this file there are a number of fairly complex elements (groups of groups et.c.) that I need to have different versions of. These elements will need to appear on multiple places in the final result, so I either need to have multiple copies of them (Showing/hiding depending on the situation) or some kind of 'atlas' where I pick and replace. My gut says the latter will be more maintainable since there are at least four places and seven "versions" (Think "green", "green with symbol x", "red with symbol y" et.c.). If there are other options, I welcome those.]
Minutes after posting, I realized it was a namespace problem. Changing the JavaScript to:
origgroup = $("#origgroup")[0];
repgroup = $("#referenceGroup1")[0];
origgroupParent = origgroup.parentNode;
// Namespaces
var svgns = 'http://www.w3.org/2000/svg',
xlinkns = 'http://www.w3.org/1999/xlink'
use = document.createElementNS(svgns, "use");
// **setAttributeNS** instead of setAttribute as originally.
use.setAttributeNS(xlinkns, "xlink:href", "#referenceGroup1");
use.setAttribute("id", "newuse");
tmp = origgroupParent.replaceChild(use, origgroup);
Solved my problem.

How can i change the pattern image parameter inside SVG by JavaScript?

i have to change logo inside embedded SVG, logo image link defined in Pattern and applied to Rect/Path container. Is there a way to change link to image (xlink:href="link_to_logo.svg") by JS?
<pattern id="logo"
patternUnits="objectBoundingBox"
x="0" y="0" width="1" height="1">
<image x="0" y="0"
xlink:href="link_to_logo.svg"
width="331" height="331">
</image>
</pattern>
<path id="logo-container" d="M1152 99h331v331h-331z" fill="url(#logo)"/>
$('#logo img').attr('xlink:href', 'newValue')
should do it.
image.setAttributeNS("http://www.w3.org/1999/xlink","href",newValue)
in plain js use setAttributeNS.

Categories