'how to save/ export inline SVG to svg
I am currently trying to save an animated SVG as a viewable svg from inline code, My application allows the user to apply a number of set animations to the SVG, The user should then be able to save the animated SVG to their local machine and view the animated SVG.
However, when I open the downloaded SVG file I am getting this error
"This page contains the following errors: error on line 4 at column 9: Extra content at the end of the document Below is a rendering of the page up to the first error."
Here is the code that is currently being downloaded:
<rect id="background" width="100" height="120" style="fill:black; stroke-width:1;
stroke:black"></rect>
<g id="ghost" transform="rotate(0), translate(0,0), scale (1.0)">
<path id="body" d="M 10 120 A 2.0 5.8, 0 0 1, 90 120" style="stroke:white; strokewidth:0.5; fill:white"></path>
<g id="eyes" transform="rotate(0,50,40), translate(0,0)">
<g id="eye-l" transform="rotate(0,50,40), translate(0,0)">
<ellipse id="eye-l-ball" cx="45" cy="40" rx="4" ry="6" style="stroke:black;
fill:black;"></ellipse>
<rect transform="rotate(16,46,35)" x="40" y="33" width="11" height="6" fill="white" visibility="hidden"></rect>
<g id="eye-l-brow">
<path d="M 41 32 Q 45 27 49 32" stroke="black" stroke-width="0.5" fill="transparent"></path>
<path d="M 41 32 Q 45 26 49 32" stroke="black" stroke-width="0.5" fill="transparent"></path>
</g>
</g>
<g id="icon" transform="rotate(0,50,40), translate(0,0)">
<g>
<ellipse class="st1 left-eye" cx="45" cy="40" rx="4" ry="6" stroke="orange"></ellipse>
<ellipse class="st1 right-eye" cx="1409.8" cy="1304.6" rx="41.1" ry="61.7" stroke="black"></ellipse>
<g id="eye-r" transform="rotate(0,50,40), translate(0,0)">
<ellipse id="eye-r-ball" cx="55" cy="40" rx="4" ry="6"></ellipse>
<rect transform="rotate(-16,56,35)" x="49" y="32" width="11" height="6" fill="white" visibility="hidden"></rect>
</g>
<g id="eye-l-brow">
<path d="M 51 32 Q 55 27 59 32" stroke="black" stroke-width="0.5" fill="transparent"></path>
<path d="M 51 32 Q 55 26 59 32" stroke="black" stroke-width="0.5" fill="transparent"></path>
</g>
</g>
</g>
</g>
</g>
<!-- Draw the square path (circle will move around this path) -->
<!-- <path fill="none" stroke="silver" d="M 10 10 H 90 V 90 H 10 L 10 10"/> -->
<!-- Draw a 5px radius red circle - this will be animated -->
<!-- <circle r="5" fill="red"> -->
<!-- Animation One - Move Circle along square path -->
<!-- <animateMotion id="theCirclePath" dur="5s" repeatCount="indefinite"
path="M 10 10 H 90 V 90 H 10 L 10 10" /> -->
<!-- Animation Two - Change Circle Radius Size -->
<!-- <animate id="theCircleSize" dur="10s" repeatCount="indefinite"
attributeName="r" values="5;10;5"/>
</circle>
-->
So it appears to be missing the SVG tags.
Please see my code below, The function for saving the SVG starts on line 154.
<html>
<head>
<title>Animated SVG</title>
<style>
.myDisplayBox {
border: 1px solid black;
font-family: "Lucida Console", "Courier New", monospace;
color: white;
height: 500px;
width: 400px;
background-color: grey;
padding: 10px;
margin: 10 auto;
}
.mySVGBox {
height: 250px;
width: 400px;
border: 1px solid black;
margin: auto;
margin-top: 10px;
padding: 10px;
}
#myDisplayBoxTitle {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 16pt;
text-align: center;
color: black;
margin: 10 auto;
}
h1 {
font-family: Arial, Helvetica, sans-serif;
text-align: center;
}
svg,
object {
border: 1px solid grey;
display: block;
margin: auto;
}
.button {
border: none;
color: white;
padding: 13px 39px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
}
.butGreen {
background-color: #4CAF50;
}
.butBlue {
background-color: #008CBA;
}
</style>
<script type="text/javascript">
</script>
</head>
<body>
<h1>Playing with an Animated SVG</h1>
<div class="mySVGBox">
<h1>Inline SVG Content</h1>
<svg id="mySVGInline" width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<!-- Draw the square path (circle will move around this path) -->
<path fill="none" stroke="silver" d="M 10 10 H 90 V 90 H 10 L 10 10"/>
<!-- Draw a 5px radius red circle - this will be animated -->
<circle r="5" fill="red">
<!-- Animation One - Move Circle along square path -->
<animateMotion id="theCirclePath" dur="5s" repeatCount="indefinite"
path="M 10 10 H 90 V 90 H 10 L 10 10" />
<!-- Animation Two - Change Circle Radius Size -->
<animate id="theCircleSize" dur="10s" repeatCount="indefinite"
attributeName="r" values="5;10;5"/>
</circle>
</svg>
<br />
<button class="button butGreen" onclick="saveSVG();">SAVE</button>
<button class="button butGreen" onclick="updateSVGContent();">UPDATE</button>
<button class="button butGreen" onclick="displaySVG();">DISPLAY</button>
</div>
<div id="myDisplayBoxTitle"></div>
<div id="myXMLDisplay" class="myDisplayBox"></div>
<script type="text/javascript">
//
// REFERENCING THE SVG
//
// get reference to the inline SVG
var svgInline = document.getElementById('mySVGInline');
// console.log(svgInline);
//
// REFERENCING ELEMENTS
//
// inline reference
//var element = document.getElementById('circle');
// move the selected inline element 50px to right
//var cx = parseFloat(element.getAttributeNS(null, 'cx'));
//element.setAttributeNS(null, 'cx', cx + 50);
//
// BUTTON FUNCTIONS
//
// update SVG animation
function updateSVGContent() {
var circlePath = document.getElementById("theCirclePath");
var duration = "dur";
var current = circlePath.getAttributeNS(null, duration);
// toggle from 5s to 20s and visa versa
if (current == "5s") {
current = "20s"
} else {
current = "5s"
}
circlePath.setAttributeNS(null, duration, current);
}
// display the SVG as XML to the display box
function displaySVG() {
var header = "<svg width=\"100\" height=\"100\" xmlns=\"http://www.w3.org/2000/svg\">";
var footer = "</svg>";
var displayBox = document.getElementById('myXMLDisplay');
displayBox.textContent = header + svgInline.innerHTML + footer;
document.getElementById('myDisplayBoxTitle').innerHTML = "Inline SVG!";
}
// save (download) the SVG content from the display box
function saveSVG() {
var a = document.body.appendChild(
document.createElement("a")
);
a.download = "export.svg";
a.href = "data:image/svg+xml," + document.getElementById("mySVGInline").innerHTML;
a.click();
}
</script>
</body>
</html>
Solution 1:[1]
You could include the parent svg by selecting outerHTML:
function saveSVG() {
var a = document.body.appendChild(
document.createElement("a")
);
let svgCode = document.getElementById("mySVGInline").outerHTML;
a.download = "export.svg";
a.href = "data:image/svg+xml," + svgCode;
a.click();
}
You should also consider to add some additional encoding/escaping. Css tricks: Optimizing SVGs in data URIs
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | herrstrietzel |
