Grouping elements in inline SVG disables getElementById() on group children - javascript

I have a simple SVG written directly in my HTML document. It contains one path with unique ID, originalPath. I can access that path directly by getElementById() like this:
HTML:
<svg id="previewImage" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="originalPath" d="" fill="none" stroke="black" stroke-width="1"></path>
</svg>
JS:
var svg = document.getElementById("previewImage");
var svgPath = svg.getElementById("originalPath");
// var svgPath = $("#originalPath")[0]; // Also working
However, if I wrap my originalPath in a group (directly in the HTML), the getElementById() function suddenly stops working, svgPath is undefined. The jQuery line doesn't work either.
<svg id="previewImage" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<path id="originalPath" d=""></path>
</g>
</svg>
I can't see what I'm doing wrong. I even tried accessing the group first and then its child, but without any success. Could someone point me in the right direction?

Related

SVG icons in ReactJS

I have to move an SVG icon from a regular website to a ReactJS website. The SVG has to be modified a little to make it compatible with JSX, so I've removed all the ':'s and replaced them with camel case attribute names for JSX compatibility. The only issue is the d attribute.
The SVG now looks like:
<svg id="Logo" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 900 800" enable-background="new 0 0 1024 1024" xmlSpace="preserve">
<g id="Layer_1"></g>
<g id="Logo">
<g>
<g id="Fish">
<g>
<path style={{fill:"#8DC046"}} d="M430.249,525.415c0,64.563-58.349,136.165-58.349,136.165l0.434,0.435l214.046-136.867L374.238,388.279
l-0.594,0.596C373.644,388.875,430.249,458.241,430.249,525.415z"></path>
</g>
<g>
<path style={{fill="#B8CD43"}} d="M586.381,525.147L374.238,388.279l-0.594,0.596c0,0,56.605,69.366,56.605,136.54L586.381,525.147z"></path>
</g>
<g>
<path style={{fill="#15AADB"}} d="M430.249,253.264c0,64.145-56.444,136.163-56.444,136.163l0.433,0.435l212.143-136.868L372.334,116.125
l-0.595,0.598C371.739,116.723,430.249,188.18,430.249,253.264z"></path>
</g>
<g>
<path style={{fill="#4AC5ED"}} d="M586.381,252.994L372.334,116.125l-0.595,0.598c0,0,58.51,71.457,58.51,136.541L586.381,252.994z"></path>
</g>
<g>
<path style={{fill="#F88F2D"}} d="M596.473,389.394c0,216.894-135.035,388.081-135.035,388.081l0.789,0.795L889.707,388.9L462.227-0.467
l-1.095,1.097C461.132,0.629,596.473,177.202,596.473,389.394z"></path>
</g>
</g>
</g>
</g>
</svg>
This gives me the following error:
Module build failed: SyntaxError: Unexpected token (90:58)
This makes sense, but in the d attributes in my case there are parts like M596.473,389.394c0. As you can imagine, the letter c between the 4 and 0 cause issues as the letter is not an integer.
How can I make this SVG work without using a library or something else? I just want to convert this SVG to valid JSX.
Change style={{fill="#B8CD43"}} to style={{fill: "#B8CD43"}} every place, it will work.
There is no need of dangerouslySetInnerHTML. Here is the working Demo
React does not play nice with SVG yet. If your svg is static I personally find it much easier to do it this way:
var img = `<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 252.5 148.7" xml:space="preserve">
<g>
<polygon points="252.5,0 252.5,52.6"/>
</g>
</svg>`
In string you can put your svg exactly how you read it from file/DB without any extra conversions.
And then later use it in render like this:
<div dangerouslySetInnerHTML={{__html: img}}/>

Setting SVG preserveAspectRatio attribute dynamically

If you have an Angular component that uses svg files by referring to symbols from one packed file:
svg instance
<svg>
<use xlink:href="#my-symbol"></use>
</svg>
symbols as they appear in the imported file
<symbol id="my-symbol" viewBox="0 0 24 24">
<title>my-symbol</title>
<path class="path1" d=" ... data here ..."></path>
</symbol>
in order to get control over scaling behavior, every symbol element should apparently have preserveAspectRatio="..." set accordingly.
What if I want to do that dynamically, taking the values for preserveAspectRatio from component instance HTML input?
Something like:
imaginary my-icon template
<my-icon preserveAR="alignMeetOrSlice">
<svg preserveAspectRatio="{{preserveAR}}">
<use xlink:href="#my-symbol"></use>
</svg>
</my-icon>
desired render:
<svg>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://somedomain.com/my.svg#my-symbol"></use>
#shadow-root (user agent)
<svg id="my-symbol" viewBox="0 0 24 24"> <!-- attribute should go to this svg -->
...
</svg>
</svg>
I tried querySelector('symbol') on the container - but it returned null results.
Is there a method to get into the shadow root and modify the symbol element?
In JS you can use direct assignment for svg.preserveAspectRatio.baseVal.align.
Instead a preserveAspectRatio="none" in HTML
you can write svg.preserveAspectRatio.baseVal.align=1 or svg.setAttribute('preserveAspectRatio', 'none'); in an JS script.
The examples are presented here:
with code-generation
alternatively with HTML-injection
and available values for aspectRatio can be seen here

accessing inline SVG elements with javascript

I'm playing around with SVG and I've hit a wall.
what im trying to do it when you hover over on svg element it will cause another to appear.
my idea was using javascript to add and remove a "hidden" class when you hover, but its not working, it works on none SVG elements but I can't see why it's not working here.
<svg xmlns:cc="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
width="400px"
height="400px"
viewBox="0 150 960 900">
<path id="loc36" class="maploc" d="m 352.28954,738.20354 0,140.66609 85.8653,0 0,-140.41399 z"/>
<path id="info36" class="infopanel " d="m 306.42857,896.64787 0,157.85713 539.28572,0 0,-158.57141 z"/>
</svg>
Javascript
$("#loc36").hover(function(){
$('#info36').removeClass('hidden');
},function(){
$('#info36').addClass('hidden');
});
https://jsfiddle.net/atprsteq/
Its works on none SVG elements, like this example
http://jsfiddle.net/EzfwV/210/
Am I just missing something simple here?
Am I just missing something simple here?
Yes.
You forgot to include jQuery!
Select jQuery from the "Frameworks & Extensions" menu.

Knockout's HTML binding + SVG

I'm using Knockout to render dynamic SVG's by passing strings into an SVG data-bound with the html: binding. In Chrome this works perfectly. In Firefox it will set up the DOM correctly (i.e. I can see that the child svg elements are present in firebug) but the graphic itself is not displayed.
I made a fiddle: https://jsfiddle.net/4eTJL/1/ but interestingly, the Firefox behavior shows in both browsers in the fiddle.
<svg> tag has no innerHTML property, that's why ko html binding doesn't work, but you can avoid this problem by putting all svg content inside logo variable, then bind it to a standard html tag.
https://jsfiddle.net/4eTJL/2/
<div data-bind="html: logo"></div>
var vm = {
logo: '<svg viewBox="0 0 50 50" class="center-block" xmlns="http://www.w3.org/2000/svg" width="80" height="80" data-bind="xml: logo"><rect ry="8" rx="8" id="svg_2" height="50" width="50" y="0" x="0" stroke-width="5" fill="#bfbfbf"></rect><text font-family="Graduate" textLength="40" lengthAdjust="spacingAndGlyphs" text-anchor="middle" x="25" y="37" font-size="33" fill="crimson" stroke="black" stroke-width="1.25">NO</text></svg>'
};
ko.applyBindings(vm);

JavaScript - Is there a way how to draw SVG path UNDER the content?

I need a path that goes UNDER the content (text) - is there a way how to do that?
(as already been answered somewhere else, z-index doesnt affect svg paths)
You can declare PATH and TEXT in different SVG layers, and put one layer onto another like this
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:1">
<text x="100" y="15" fill="red">I love SVG</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:0">
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
http://jsfiddle.net/WJZrU/

Categories

Resources