Convert SVG to and from JSON using JavaScript - javascript

I have created a Cordova Ionic project. I am working on an editor. How can I convert the below SVG content into JSON array and JSON array to SVG content via JavaScript?
<svg width="580" height="400" xmlns="http://www.w3.org/2000/svg">
<!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ -->
<g>
<title>background</title>
<rect fill="#fff" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
<g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid">
<rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/>
</g>
</g>
<g>
<title>Layer 1</title>
<rect total-price="129720" data-price="10" id="svg_2" height="69" width="188" y="47" x="63.5" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
<line total-price="121164.47292" height="75.36667" width="151.66666" data-price="10.6" stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_3" y2="124" x2="470.5" y1="50" x1="319.5" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
<ellipse total-price="190708.875" height="91.5" width="198.5" data-price="10.5" ry="45" rx="98.5" id="svg_4" cy="323" cx="159" fill-opacity="null" stroke-opacity="null" stroke-width="1.5" stroke="#000" fill="none"/>
</g>
</svg>

Related

Insert SVG document into HTML dynamically using JavaScript?

How can I dynamically insert an SVG into HTML?
The problem right now is that the SVG is a document, and I can only find how to insert nodes. I have tried some different things to convert the SVG to a node, but have not found anything that works.
const svgDoc = new DOMParser().parseFromString(svgText, "text/html");
window.document.querySelector("#container").appendChild(svgDoc);
const svgText = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" preserveAspectRatio="xMidYMid meet">
<title>My First Scalable Vector Graphic</title>
<desc>An experimental SVG from SitePoint.com</desc>
<g id="main">
<line x1="10" y1="10" x2="100" y2="200" stroke="#00c" stroke-width="5" stroke-linecap="round" />
<polyline points="580,10 560,390 540,200 520,390 400,390" stroke="#c00" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
<polygon points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" stroke="#ff0" stroke-width="10" fill="#ffc" />
<rect x="100" y="10" width="150" height="100" rx="10" ry="20" stroke="#060" stroke-width="8" fill="#0f0" />
<circle cx="100" cy="300" r="80" stroke="#909" stroke-width="10" fill="#f6f" />
<ellipse cx="450" cy="50" rx="80" ry="30" stroke="#0cc" stroke-width="10" fill="#0ff" />
<text x="240" y="390" font-family="sans-serif" font-size="50" fill="#00f">SVG</text>
</g>
</svg>
`;
<div id="container"></div>
Use document.documentElement to get the root element of a document.
const svgText = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400" preserveAspectRatio="xMidYMid meet">
<title>My First Scalable Vector Graphic</title>
<desc>An experimental SVG from SitePoint.com</desc>
<g id="main">
<line x1="10" y1="10" x2="100" y2="200" stroke="#00c" stroke-width="5" stroke-linecap="round" />
<polyline points="580,10 560,390 540,200 520,390 400,390" stroke="#c00" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
<polygon points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" stroke="#ff0" stroke-width="10" fill="#ffc" />
<rect x="100" y="10" width="150" height="100" rx="10" ry="20" stroke="#060" stroke-width="8" fill="#0f0" />
<circle cx="100" cy="300" r="80" stroke="#909" stroke-width="10" fill="#f6f" />
<ellipse cx="450" cy="50" rx="80" ry="30" stroke="#0cc" stroke-width="10" fill="#0ff" />
<text x="240" y="390" font-family="sans-serif" font-size="50" fill="#00f">SVG</text>
</g>
</svg>
`;
const svgDoc = new DOMParser().parseFromString(svgText, "image/svg+xml");
window.document.querySelector("#container").appendChild(svgDoc.documentElement);
<div id="container"></div>

Two or more SVGs in a page. How can I animate them on button click?

Same SVG is repeated in carousel multiple times. Carousel is constructed in PHP using a while loop. How can I trigger animation at the click of a next/prev button in carousel?
My jQuery code is as below. It animates only the first <animate> tag. I think I must have explained my whole point.
jQuery(document).ready(function($){
$('.first').click(function(){
$('animate')[0].beginElement();
$('animateTransform')[0].beginElement();
});
});
My SVG code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 425 386" style="enable-background:new 0 0 425 386;" xml:space="preserve">
<polygon class="st0" points="356.4,330 399.3,370.8 399.3,82.5 357.3,106.5 "/>
<polygon class="st1" points="63.8,105 63.8,329.3 357.3,329.3 357.3,106.5 "/>
<polygon class="st2" points="21.8,369 62.5,329.3 357.3,329.3 399.3,370.8 20.9,370.8 "/>
<polygon class="st0" points="63.8,329.2 20.9,370.8 20.9,82.5 63.8,105 "/>
<g>
<line class="st3" id="line1" x1="65.2" y1="76.3" x2="180.9" y2="76.3"/>
<animate xlink:href="#line1" attributeName="x2" from="65" to="180.9" dur="2s" class="ani" />
<line class="st3" id="line2" x1="237.6" y1="76.3" x2="338.6" y2="76.3"/>
<animate xlink:href="#line2" attributeName="x2" from="250" to="338.6" dur="2s" class="ani" />
<text x="200" y="80" class="wt1">10'</text>
</g>
<g>
<g>
<text x="368" y="70" class="wt1">5'</text>
</g>
<line class="st3" id="line3" x1="352.1" y1="76.9" x2="362.6" y2="70.8"/>
<animate xlink:href="#line3" attributeName="x2" from="351" to="362.6" dur="3s" class="ani" />
<animate xlink:href="#line3" attributeName="y2" from="77" to="70.8" dur="3s" class="ani" />
<line class="st3" id="line4" x1="387.7" y1="58" x2="396.6" y2="51.9"/>
<animate xlink:href="#line4" attributeName="x2" from="388" to="396.6" dur="3s" class="ani" />
<animate xlink:href="#line4" attributeName="y2" from="58" to="51.9" dur="3s" class="ani" />
</g>
<g>
<ellipse class="st4" id="elli1" cx="210.1" cy="344.8" rx="37.2" ry="4.5"/>
<animate xlink:href="#elli1" attributeName="rx" from="7.2" to="37.2" dur="3s" class="ani" />
<animate xlink:href="#elli1" attributeName="ry" from="0.2" to="4.5" dur="3s" class="ani" />
<g id="box1" transform="translate(0, 0)">
<polygon class="st5" points="230.8,307.5 213,307.5 213,307.9 213,314.1 207,314.1 207,307.5 189.2,307.5 188.9,345.4 231.2,345.4
"/>
<path class="st6" d="M207,307.3v-6.9c0-0.2,6-0.1,6-0.1v7.1h17.8l-8-7.1h-26.7l-7,7.1H207V307.3z"/>
<polygon class="st7" points="207,314.1 213,314.1 213,307.9 213,307.5 207,307.5 "/>
<path class="st8" d="M207,300.4v6.9v0.1h6v-7.1C213,300.4,207,300.2,207,300.4z"/>
<animateTransform xlink:href="#box1" attributeName="transform" type="translate" from="0 -70" to="0 0" dur="3s" class="ani" />
</g>
</g>
</svg>
You forgot to add a question style sheet. I restored the color values of the svg parts according to the figure.
Since all animations should start simultaneously at the click of a mouse, you can do without Javascript
To do this, add a launch command to each animation begin="Layer_1.click"
.container {
width:75%;
height:75%;
}
.st0 {fill:#C8C8C8;}
.st1 {fill:#E7E7E7;}
.st2 {fill:#6A6A6A;}
.st3 {stroke:#F6C44A;}
.st4 {fill:#323232;}
.st5 {fill:#CB9751;}
.st6 {fill:#E0B268;}
.st7 {fill:#C8A066;}
.st8 {fill:#E3C084;}
<div class="container">
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 425 386" style="enable-background:new 0 0 425 386;" xml:space="preserve">
<polygon class="st0" points="356.4,330 399.3,370.8 399.3,82.5 357.3,106.5 "/>
<polygon class="st1" points="63.8,105 63.8,329.3 357.3,329.3 357.3,106.5 "/>
<polygon class="st2" points="21.8,369 62.5,329.3 357.3,329.3 399.3,370.8 20.9,370.8 "/>
<polygon class="st0" points="63.8,329.2 20.9,370.8 20.9,82.5 63.8,105 "/>
<g>
<line class="st3" id="line1" x1="65.2" y1="76.3" x2="180.9" y2="76.3"/>
<animate xlink:href="#line1" attributeName="x2" from="65" to="180.9" begin="Layer_1.click" dur="2s" class="ani" />
<line class="st3" id="line2" x1="237.6" y1="76.3" x2="338.6" y2="76.3"/>
<animate xlink:href="#line2" attributeName="x2" from="250" to="338.6" begin="Layer_1.click" dur="2s" class="ani" />
<text x="200" y="80" class="wt1">10'</text>
</g>
<g>
<g>
<text x="368" y="70" class="wt1">5'</text>
</g>
<line class="st3" id="line3" x1="352.1" y1="76.9" x2="362.6" y2="70.8"/>
<animate xlink:href="#line3" attributeName="x2" from="351" to="362.6" begin="Layer_1.click" dur="3s" class="ani" />
<animate xlink:href="#line3" attributeName="y2" from="77" to="70.8" begin="Layer_1.click" dur="3s" class="ani" />
<line class="st3" id="line4" x1="387.7" y1="58" x2="396.6" y2="51.9"/>
<animate xlink:href="#line4" attributeName="x2" from="388" to="396.6" begin="Layer_1.click" dur="3s" class="ani" />
<animate xlink:href="#line4" attributeName="y2" from="58" to="51.9" begin="Layer_1.click" dur="3s" class="ani" />
</g>
<g>
<ellipse class="st4" id="elli1" cx="210.1" cy="344.8" rx="37.2" ry="4.5"/>
<animate xlink:href="#elli1" attributeName="rx" from="7.2" to="37.2" begin="Layer_1.click" dur="3s" class="ani" />
<animate xlink:href="#elli1" attributeName="ry" from="0.2" to="4.5" begin="Layer_1.click" dur="3s" class="ani" />
<g id="box1" transform="translate(0, 0)">
<polygon class="st5" points="230.8,307.5 213,307.5 213,307.9 213,314.1 207,314.1 207,307.5 189.2,307.5 188.9,345.4 231.2,345.4
"/>
<path class="st6" d="M207,307.3v-6.9c0-0.2,6-0.1,6-0.1v7.1h17.8l-8-7.1h-26.7l-7,7.1H207V307.3z"/>
<polygon class="st7" points="207,314.1 213,314.1 213,307.9 213,307.5 207,307.5 "/>
<path class="st8" d="M207,300.4v6.9v0.1h6v-7.1C213,300.4,207,300.2,207,300.4z"/>
<animateTransform xlink:href="#box1" attributeName="transform" type="translate" from="0 -70" to="0 0" begin="Layer_1.click" dur="3s" class="ani" />
</g>
</g>
</svg>
</div>

How to rotate SVG inside mask?

I have an SVG mask that I would like to rotate the elements inside. However, when I attempted it, it looks like the entire mask is being rotated.
I tried at this SO post, but the fiddle wasn't working (the image wasn't showing anymore).
This is what it originally looks like
What happened
What I wanted to happen
I wanted only the "liquid" element to be rotated, but somehow the liquid element is being rotated the wrong way.
This is the SVG (with mask element):
<svg width="200px" height="200px" viewBox="0 0 200 200">
<defs>
<rect id="path-1" x="75" y="65" width="50" height="100" rx="5"></rect>
</defs>
<g id="bottle" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="bottle-lid" stroke="#916548" stroke-width="5" x="82.5" y="52.5" width="35" height="15" rx="5"></rect>
<rect id="bottle-holder" stroke="#916548" stroke-width="5" x="117.5" y="55.5" width="30" height="7" rx="3.5"></rect>
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Mask"></g>
<rect id="bottle-liquid" fill="#3498DB" mask="url(#mask-2)" x="40" y="80" width="120" height="120"></rect>
<rect id="bottle-outline" stroke="#916548" stroke-width="5" mask="url(#mask-2)" x="77.5" y="67.5" width="45" height="95" rx="5"></rect>
</g>
</svg>
And this is the JS (I am using a GSAP library)
const liquid = document.querySelector("#bottle-liquid")
const tl = new TimelineMax()
tl.to(liquid, 1, {
rotation: 20
})
How can I rotate just the a certain element inside a masked SVG?
I've made a few changes to your SVG, the most important: I've putted the bottle-liquid inside a g element and I'm applying the mask to the g element and the transform to the bottle-liquid. I hope it helps.
<svg width="200px" height="200px" viewBox="0 0 200 200">
<defs>
<rect id="path-1" x="75" y="65" width="50" height="100" rx="5"></rect>
<mask id="mask-2" fill="white">
<use xlink:href="#bottle-outline"></use>
</mask>
</defs>
<g id="bottle" stroke-width="5" stroke="#916548" fill="none" fill-rule="evenodd">
<rect id="bottle-lid" x="82.5" y="52.5" width="35" height="15" rx="5"></rect>
<rect id="bottle-holder" x="117.5" y="55.5" width="30" height="7" rx="3.5"></rect>
<g mask="url(#mask-2)">
<rect id="bottle-liquid" stroke="none" fill="#3498DB" x="40" y="80" width="120" height="120" transform="rotate(20 100 140)"></rect>
</g>
<rect id="bottle-outline" x="77.5" y="67.5" width="45" height="95" rx="5"></rect>
</g>
</svg>

Change an inline SVG's x and y with ecmascript

I am using an inline SVG in an SVG and have set some default x and y values. When I change them, the inline SVG moves accordingly. I am trying to change it with
var inlineSVG = document.getElementById("inlineSVG");
inlineSVG.style.x = "90";
and that adds style="x:90px;" but that doesn't actually affect the element.
It's weird (in my head) because this works with a rect but not with an svg.
Here is my actual code:
<?xml version='1.0' encoding='UTF-8'?>
<svg width='1000' height='360'
xmlns='http://www.w3.org/2000/svg'
xmlns:xlink="http://www.w3.org/1999/xlink"
onload='init(evt)'
>
<script type='text/ecmascript'>
function init(event){
var wing1 = document.getElementById("wing1");
wing1.style.x = "90";
}
</script>
<circle cx="200" cy="140" r="5" fill="red" />
<circle cx="220" cy="170" r="5" fill="red" />
<circle cx="180" cy="170" r="5" fill="red" />
<circle cx="220" cy="220" r="5" fill="red" />
<circle cx="180" cy="220" r="5" fill="red" />
<svg id="wing1" x="280" y="100" viewBox="0 0 350 300">
<g>
<g>
<g>
<ellipse fill="#E6E7E8" cx="229.505" cy="117.813" rx="5.862" ry="4.547"/>
</g>
<g>
<ellipse fill="#E6E7E8" cx="265.931" cy="117.819" rx="5.862" ry="4.547"/>
</g>
</g>
<g>
<g>
<ellipse fill="#E6E7E8" cx="229.191" cy="125.538" rx="5.862" ry="4.547"/>
</g>
<g>
<ellipse fill="#E6E7E8" cx="265.617" cy="125.531" rx="5.861" ry="4.547"/>
</g>
</g>
</g>
<ellipse fill="#E6E7E8" cx="247.244" cy="121.796" rx="20.635" ry="38.017"/>
</svg>
<rect id="square" x="0" y="470" width="50" height="50" fill="#BADA55" style="fill-opacity : 0.5" />
<line x1="0" y1="0" x2="1000" y2="360" style="stroke: yellowgreen;
stroke-width: 1;
stroke-dasharray: 10 1;"></line>
<line x1="0" y1="360" x2="1000" y2="0" style="stroke: yellowgreen;
stroke-width: 1;
stroke-dasharray: 10 1;"></line>
I tried adding !important to the value but it didn't work ( because I guess it doesn't count it as a valid number? ).
The solution is to directly change the x attribute like so:
selector.setAttribute("attr",val);

d3js / nvd3 - graph half hidden

I have a d3 / nvd3 graph which seems to be "clipped" by half...
Hereafter is the code (sorry, quite long, but a copy/paste in an html file works). Normally I have one bar by hour (so 24 bars) here I put only three hours.
The html is splitter in sections :
The legend [g class="nv-x nv-axis" transform="translate(0,235)"]
Y axis: [g class="nv-y nv-axis"]
One bar by hours: [g class="nv-barsWrap"]
We see only the top half of the Y axis and Bars, the bottom legend is lost. But it does exist on the html ! and we can "inspect" it... I don't get what is happening, but there is this "clip" rectangle I don't master... ( [clipPath id="nv-x-label-clip-6678"] )
<div id="chart">
<svg>
<g class="nvd3 nv-wrap nv-discreteBarWithAxes">
<g transform="translate(60,15)">
<defs>
<clipPath id="nv-x-label-clip-6678">
<rect width="20.912863070539423" height="16" x="-10.456431535269711">
</rect>
</clipPath>
</defs>
<g class="nv-x nv-axis" transform="translate(0,235)">
<g class="nvd3 nv-wrap nv-axis">
<g>
<g transform="translate(6.390041493775935,0)" style="opacity: 1;">
<line class="tick" y2="-235" x2="0">
</line>
<text y="3" dy=".71em" transform="translate(0,5)" x="0" style="text-anchor: middle;">00</text>
</g>
<g transform="translate(18.008298755186722,0)" style="opacity: 1;">
<line class="tick" y2="-235" x2="0">
</line>
<text y="3" dy=".71em" transform="translate(0,17)" x="0" style="text-anchor: middle;">01</text>
</g>
<g transform="translate(29.62655601659751,0)" style="opacity: 1;">
<line class="tick" y2="-235" x2="0">
</line>
<text y="3" dy=".71em" transform="translate(0,5)" x="0" style="text-anchor: middle;">02</text>
</g>
<path class="domain">
</path>
<text class="nv-axislabel" text-anchor="middle" y="36" x="140.00000000000003" transform="translate(0,17)">
</text>
</g>
</g>
</g>
<g class="nv-y nv-axis">
<g class="nvd3 nv-wrap nv-axis">
<g>
<g transform="translate(0,235)" style="opacity: 1;">
<line class="tick zero" x2="280" y2="0">
</line>
<text x="-3" dy=".32em" opacity="0" y="0" style="text-anchor: end;">0.0</text>
</g>
<g transform="translate(0,192.54290876242095)" style="opacity: 1;">
<line class="tick" x2="280" y2="0">
</line>
<text x="-3" dy=".32em" opacity="1" y="0" style="text-anchor: end;">200.0</text>
</g>
<g transform="translate(0,150.0858175248419)" style="opacity: 1;">
<line class="tick" x2="280" y2="0">
</line>
<text x="-3" dy=".32em" opacity="1" y="0" style="text-anchor: end;">400.0</text>
</g>
</g>
</g>
</g>
<g class="nv-barsWrap">
<g class="nvd3 nv-wrap nv-discretebar" transform="translate(0,0)">
<g>
<g class="nv-groups">
<g class="nv-group nv-series-0" style="stroke-opacity: 1; fill-opacity: 0.75;">
<g transform="translate(1.6846473217010498,0)" class="nv-bar positive" style="fill: #0088cc; stroke: #0088cc;">
<rect height="235" width="9.41078838174274" class="discreteBar">
</rect>
</g>
<g transform="translate(13.30290412902832,166.00723266601562)" class="nv-bar positive" style="fill: #0088cc; stroke: #0088cc;">
<rect height="68.99277326106593" width="9.41078838174274" class="discreteBar">
</rect>
</g>
<g transform="translate(24.921161651611328,175.98464965820312)" class="nv-bar positive" style="fill: #0088cc; stroke: #0088cc;">
<rect height="59.01535682023487" width="9.41078838174274" class="discreteBar">
</rect>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
</div>
It is most likely because the container does not have enough room to contain the graph. Add height=100% and width=100% or some arbitrary large number of pixels to test it out (to the div containing the chart).

Categories

Resources