Import external SVG file contents as a javascript variable/object - javascript

I have an external SVG file which contains the following SVG definition:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>
The SVG has multiple paths, so for me to be able to change colours of individual paths I need to be able to load the SVG file contents into a Javascript variable like this:
var svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';
Then I can use conditional statements to alter the colours e.g.
switch(centerId) {
case 1:
svgSource = svgSource.replace("#ffbf00", "#005D00");
break;
case 2:
svgSource = svgSource.replace("#ffbf00", "#A20000");
break;
case 3:
svgSource = svgSource.replace("#ffbf00", "#ffbf00");
break;
}
I could define and use the inline SVG code hard coded into the Javascript as shown, but for maintenance and continuity it would be much better to use existing, centralised, external SVG files.
How can I load the contents of the SVG file into a javascript variable/object?

CSS Styling
Try using CSS to style the paths instead of replacing parts of source code.
Concept code example, using the style attribute of svg elements to apply some CSS:
"use strict";
const svg = document.querySelector("svg");
const paths = svg.querySelectorAll("path");
paths[0].style = "fill: #FF0000;"
svg.querySelector("circle").style = "fill: rebeccapurple";
svg {
height: 150px;
width: 100px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>
Potentially you could improve on this by writing svg source that expects to be styled by CSS instead of being over-ridden by style attribute values.
See also: How to use external SVG in HTML?
Getting the source of an external SVG file
An external svg file can be included in HTML using a pair of <object> tags. For example if "svg-file.svg" is in the same directory as the HTML file:
<object type="image/svg+xml" id="mySVG"
data="svg-file.svg"
width="100"
height="150"
></object>
Subject to security policies: the svg file must be from the same domain and served from a network or localhost server - due to blanket security restriction placed on local files, the source of svg files loaded using the file:// protocol. can't be accessed.
Picking up the svg source is a bit obscure. This worked for me after page load, using the above HTML:
window.onload = ()=> {
console.log("loaded");
const svgObject = document.querySelector("#mySVG");
const svg = svgObject.getSVGDocument().documentElement;
const svgSource = svg.outerHTML;
console.log("svgElement, tag name '%s' ", svg.tagName, svg);
console.log("svgSource: ", svgSource);
console.log("path.st0: ", svg.querySelector('.st0'));
};

One solution is to load the svg image by setting the innerHTML property of an arbitrary container to your svg string.
This then gives you two options: firstly, for heavy changes, you have access to each path as part of the DOM and can maniulate them using javascript. This simply requires making a reference to container.children[0]; Alternatively, for simple changes such as colour changes, it makes each element directly targetable by style rules where you can specify colours in the usual way.
The snippet illustrates adding the svg to the dom using your string, and resets some colours with simple style rules. Making a reference for changes using javascript is shown commented at the foot of the code.
let svgSource = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150" ><path class="st0" fill="#FFFFFF" d="M50,145.5C40.6,131.6,2.5,73.4,2.5,50C2.5,23.8,23.8,2.5,50,2.5S97.5,23.8,97.5,50C97.5,73.4,59.4,131.6,50,145.5z"/><path class="st1" fill="#000000" d="m50 5c24.8 0 45 20.2 45 45 0 19.5-29.4 67.7-45 91.1-15.6-23.4-45-71.6-45-91.1 0-24.8 20.2-45 45-45m0-5c-27.6 0-50 22.4-50 50s50 100 50 100 50-72.4 50-100-22.4-50-50-50z"/><circle fill="#ffbf00" cx="50" cy="50" r="27.5"/><path d="m50 25c13.8 0 25 11.2 25 25s-11.2 25-25 25-25-11.2-25-25 11.2-25 25-25m0-5c-16.6 0-30 13.4-30 30s13.4 30 30 30 30-13.4 30-30-13.4-30-30-30z"/></svg>';
const container = document.getElementsByTagName('div')[0];
container.innerHTML = svgSource;
// for js manipulation:
// svgObject = container.children[0];
div {
width: 50%;
}
.st0 {
fill: red;
}
.st1 {
fill: yellow;
}
circle {
fill: green;
}
<div>
</div>

Related

How to Convert svg link into svg tag

I have an link which has the svg file with the format of svg .
svgfilelink
And this link has the following content :
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20px" height="20px" viewBox="0 0 20 20" version="1.1">
<title>Rectangle Copy 14</title>
<defs>
<linearGradient x1="5.7671933%" y1="50.1613046%" x2="99.3732272%" y2="50.1613046%" id="linearGradient-1">
<stop stop-color="#59D08F" offset="0%"/>
<stop stop-color="#26C2DC" offset="100%"/>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="06-Shapes-Properties" transform="translate(-1166.000000, -354.000000)" stroke="url(#linearGradient-1)" stroke-width="2">
<rect id="Rectangle-Copy-14" x="1167" y="355" width="18" height="18"/>
</g>
</g>
As of now I'm adding this link as src in img tag .
But I need this link as svg format.
I have tried few methods. But didn't help.
Is there any possible ways to convert the url into svg tag in JAVASCRIPT?
I don't know if this is the right way to do but you can directly fetch that svg and render it to the DOM using innerHTML or something like dangerouslySetInnerHTML with react
let svgUrl = 'https://raw.githubusercontent.com/rahuldkjain/github-profile-readme-generator/master/src/images/icons/Social/hackerrank.svg'
function getTheSvg(url) {
return fetch(url).then(res => res.text());
}
getTheSvg(svgUrl).then(res => {
let svgDiv = document.querySelector('.svg')
svgDiv.innerHTML = res
})
svg {
height: 200px
}
<div class='svg'><div>
If you used create-react-app, it already uses #svgr/webpack package, so you can do this, which will cause the image to load inline as React components containing the SVG elements directly, instead of by a link:
import { ReactComponent as RectangleIcon } from './rectangle.svg';
export const MyComponent = () => {
return <RectangleIcon />
}
If you are not using create-react-app so not using svgr yet, you can add it to your project (see docs)

SVG : how to merge multiple lines to obtain single object

i have square shape made of 4 lines and as these are 4 different paths so am not able to get size of the shape for that am trying to merge these lines together so that i have square shape as single path and then i can get its size using getBBox() method :
square shape
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 -237.4911 302.46116 237.4911">
<g xmlns="http://www.w3.org/2000/svg" transform="matrix(1 0 0 -1 0 0)">
<path d= "M129.734598 192.711157V226.160594" stroke="red" stroke-width=".56693" id="1"/>
<path d= "M129.734598 192.711157H159.496439" stroke="red" stroke-width=".56693" id="2"/>
<path d= "M159.496439 192.711157V226.160594" stroke="red" stroke-width=".56693" id="3"/>
<path d= "M129.734598 226.160594H159.496439" stroke="red" stroke-width=".56693" id="4"/>
</g>
</svg>
so i try to merged them which is partially ok like this
M129.734598 192.711157 V226.160594 H159.496439 V226.160594 H159.496439
so any idea how to properly do it to get square shape as single path
Hint 1
Your first path
M 129.734598 192.711157 V 226.160594
is equivalent to
M 129.734598 192.711157 L 129.734598 226.160594
Your second path
M 129.734598 192.711157 H 159.496439
is equivalent to
M 129.734598 192.711157 L 159.496439 192.711157
Perhaps in this form, the sequence of moves might be more obvious.
Hint 2
In your first attempt you were close (I've rounded these values for more clarity)
M 129 192 V 226 H 159 V 226 H 159
Your last two path commands are not doing anything.
In order to complete the square, your third side (the second V) needs to return to the start Y position. And your fourth side (the second H) needs to return to the start X position.
Hope this helps, and is not too cryptic.

Why svg embeded in javascript not working

Some reason i need use a react project in Rails html like this:
<html>
...
<script src="<react_project_bundle_file>.js"></script>
</html>
Because a lot of SVG images are used by icon in this react project, i'm tried refactor with svg-sprite-loader & svgo-loader. It's working very well when visit this page first visit, but the second time visited the page, none of these SvgIcon appear.
// svg-icon.jsx
import '../icons';
const SvgIcon = props => (
<svg>
<use xlinkHref={`#icon--${props.icon}`} />
</svg>
);
// icons/index.js
const requireAll = requireContext => requireContext.keys().forEach(requireContext);
// `icons/svg` is a subdirectory to store all SVG files
const req = require.context('./svg', false, /\.svg$/);
requireAll(req);
And svg inline in the bundle js file:
"use strict";
...
var symbol = new _node_modules_svg_baker_runtime_browser_symbol_js__WEBPACK_IMPORTED_MODULE_0___default.a({
"id": "icon--file-upload",
"use": "icon--file-upload-usage",
"viewBox": "0 0 20 20",
"content": "<symbol xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" id=\"icon--file-upload\"><path d=\"M5.917 6.886L9.64 3.165a.54.54 0 01.777 0l3.721 3.721c.355.355.096.94-.395.94h-1.854L10.784 12.2a.798.798 0 01-.968.573.78.78 0 01-.586-.573L8.126 7.825H6.313c-.491 0-.75-.584-.396-.939zM17 11.602v2.249A3.147 3.147 0 0113.865 17H6.149A3.15 3.15 0 013 13.851v-2.25c0-.572.463-1.022 1.022-1.022.56 0 1.023.45 1.023 1.023v2.249c0 .6.49 1.104 1.104 1.104h7.716c.6 0 1.09-.504 1.09-1.104v-2.25c0-.572.464-1.022 1.023-1.022.572 0 1.022.45 1.022 1.023z\" fill=\"#FFF\" fill-rule=\"evenodd\" /></symbol>"
});
...
HTML element debug
First visit
<svg>
<use xlink:href="#icon--upload">
#shadow-root(closed)
<svg xmlns="http://www.w3.org/2000/svg" ...>
<path ...>
</svg>
</use>
</svg>
Second visit:
<svg>
<use xlink:href="#icon--upload">
#shadow-root(closed)
!!! not anything !!!
</use>
</svg>
What's the problem here? Why is it correct the first time and not the second time?
Svg sprite not include!
fetch('svg-sprite.svg')
.then(res => res.text())
.then(data => {
document.getElementById('svg-sprite').innerHTML = data;
});
UPDATE:
svg-sprite.svg not found! worked by added path to <use xlinkHref={`static/svg-sprite.svg#icon--${icon}`} /> in the <svg></svg>

Vivus reverse selected paths

Is there a way to reverse draw (so actually erase) a chosen path drawn before using Vivus for SVG?
Let's say we have a fiddle like this:
http://jsfiddle.net/z7x4ovn7/92/
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" id="keyhole" version="1.1" width="306" height="296" id="svg2">
<g transform="translate(-162.46995,-477.2863)" id="layer1">
<path d="m 314,480 l 0,100" stroke="#20552a" id="path2000" stroke-width="2" fill="none"/>
<path d="m 314.15745,481.69558 c -59.20089,0.53774 -114.80979,36.72219 -137.3125,95.34375 -29.39129,76.56693 8.83932,162.45246 85.40625,191.84375 l 34.03125,-88.6875 c -20.0678,-7.71358 -34.3125,-27.15324 -34.3125,-49.9375 0,-29.54723 23.95277,-53.5 53.5,-53.5 29.54723,0 53.5,23.95277 53.5,53.5 0,22.78426 -14.2447,42.22392 -34.3125,49.9375 l 34.03125,88.6875 c 39.29085,-15.08234 70.3239,-46.1154 85.40625,-85.40625 29.39129,-76.56693 -8.83932,-162.48371 -85.40625,-191.875 -17.94537,-6.88859 -36.40853,-10.07087 -54.53125,-9.90625 z" id="path2830" fill="#40aa54" stroke="#20552a" stroke-width="8" stroke-miterlimit="4"/>
</g>
</svg>
new Vivus('keyhole', {
type: 'oneByOne',
duration: 50
}, function doDone(obj) {
obj.el.classList.add('finished');
});
After drawing all paths I would like to reverse-draw the path with id path2000. Would you have any ideas?
The library has a few restrictions that make it circuitous, but the effect can be achieved if you divide the SVG with two inner <svg> tags. This makes them addressable for different animations, and you can play one of them backwards:
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" id="keyhole" version="1.1" width="306" height="296">
<svg id="part1">
<path transform="translate(-162.46995,-477.2863)" d="m 314,480 l 0,100" stroke="#20552a" id="path2000" stroke-width="2" fill="none"/>
</svg>
<svg id="part2">
<path transform="translate(-162.46995,-477.2863)" d="m 314.15745,481.69558 c -59.20089,0.53774 -114.80979,36.72219 -137.3125,95.34375 -29.39129,76.56693 8.83932,162.45246 85.40625,191.84375 l 34.03125,-88.6875 c -20.0678,-7.71358 -34.3125,-27.15324 -34.3125,-49.9375 0,-29.54723 23.95277,-53.5 53.5,-53.5 29.54723,0 53.5,23.95277 53.5,53.5 0,22.78426 -14.2447,42.22392 -34.3125,49.9375 l 34.03125,88.6875 c 39.29085,-15.08234 70.3239,-46.1154 85.40625,-85.40625 29.39129,-76.56693 -8.83932,-162.48371 -85.40625,-191.875 -17.94537,-6.88859 -36.40853,-10.07087 -54.53125,-9.90625 z" id="path2830" fill="#40aa54" stroke="#20552a" stroke-width="8" stroke-miterlimit="4"/>
</svg>
</svg>
// started immediately
var inner = new Vivus('part1', {
duration: 20
}, function () {
// start outer animation after inner has been drawn
outer.play(1);
});
// started later
var outer = new Vivus('part2', {
duration: 50,
start: 'manual'
}, function (obj) {
obj.el.classList.add('finished');
// reverse inner animation after outer has been drawn
inner.play(-1);
});

how to draw inner or outer path for a path in svg

I am new to svg , I need to draw a inner or outer path for the svg editor generated svg path , i am unable to draw . I tried a lot but i cant .
help me.
<path id="svg_1" d="m697.81641,349.89844l596,0l0,282l-596,0l0,-141l0,-141z" stroke-width="6" stroke="#000000" fill="#BBD1E8"/>
the previous line make a rect on svg editor . i need to draw a inner rect or outer rect for the above path . i need to make it like a compound wall . so i need to know is there any formula or calculation is there to do it dynamically . i tried this
<path d="M 0 0, 60 0, 60 60, 0 60 Z M 15 15, 15 45, 45 45, 45 15Z"/>
it working correctly but how can i make it dynamically for user generated path .
i tried for the following user generated code
<path id="svg_1" d="m1085,757.10199l309,-84.5l292,-2.5l243.5,256l-8.5,193.99799l-749,-62l-87,-147.99799l0,-153z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="6" stroke="#000000" fill="#BBD1E8"/>
i convert this as follows
<path id="svg_1" d="m1085,757.10199l309,-84.5l292,-2.5l243.5,256l-8.5,193.99799l-749,-62l-87,-147.99799l0,-153zm832.10199,1160l-9.5,234l-77.5,217l181,318.5l268.99799,66.5l13,-824l-222.99799,-162l-228,75z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="6" stroke="#000000" fill="#BBD1E8"/>
in this first m to z original path code second m to z is generated but not working

Categories