How do I draw a circle in JS using SVG? - javascript

If you look at http://map-icons.com/ and the js included with the file contains these variable declarations:
// Define Marker Shapes
var MAP_PIN = 'M0-48c-9.8 0-17.7 7.8-17.7 17.4 0 15.5 17.7 30.6 17.7 30.6s17.7-15.4 17.7-30.6c0-9.6-7.9-17.4-17.7-17.4z';
var SQUARE_PIN = 'M22-48h-44v43h16l6 5 6-5h16z';
var SHIELD = 'M18.8-31.8c.3-3.4 1.3-6.6 3.2-9.5l-7-6.7c-2.2 1.8-4.8 2.8-7.6 3-2.6.2-5.1-.2-7.5-1.4-2.4 1.1-4.9 1.6-7.5 1.4-2.7-.2-5.1-1.1-7.3-2.7l-7.1 6.7c1.7 2.9 2.7 6 2.9 9.2.1 1.5-.3 3.5-1.3 6.1-.5 1.5-.9 2.7-1.2 3.8-.2 1-.4 1.9-.5 2.5 0 2.8.8 5.3 2.5 7.5 1.3 1.6 3.5 3.4 6.5 5.4 3.3 1.6 5.8 2.6 7.6 3.1.5.2 1 .4 1.5.7l1.5.6c1.2.7 2 1.4 2.4 2.1.5-.8 1.3-1.5 2.4-2.1.7-.3 1.3-.5 1.9-.8.5-.2.9-.4 1.1-.5.4-.1.9-.3 1.5-.6.6-.2 1.3-.5 2.2-.8 1.7-.6 3-1.1 3.8-1.6 2.9-2 5.1-3.8 6.4-5.3 1.7-2.2 2.6-4.8 2.5-7.6-.1-1.3-.7-3.3-1.7-6.1-.9-2.8-1.3-4.9-1.2-6.4z';
var ROUTE = 'M24-28.3c-.2-13.3-7.9-18.5-8.3-18.7l-1.2-.8-1.2.8c-2 1.4-4.1 2-6.1 2-3.4 0-5.8-1.9-5.9-1.9l-1.3-1.1-1.3 1.1c-.1.1-2.5 1.9-5.9 1.9-2.1 0-4.1-.7-6.1-2l-1.2-.8-1.2.8c-.8.6-8 5.9-8.2 18.7-.2 1.1 2.9 22.2 23.9 28.3 22.9-6.7 24.1-26.9 24-28.3z';
var SQUARE = 'M-24-48h48v48h-48z';
var SQUARE_ROUNDED = 'M24-8c0 4.4-3.6 8-8 8h-32c-4.4 0-8-3.6-8-8v-32c0-4.4 3.6-8 8-8h32c4.4 0 8 3.6 8 8v32z';
Now, all I want, is to add another one, a circle.
Can anyone please point me in the direction of a resource or tool with which I can achieve this? Does anyone know what those little bits even mean?

Related

Any downsides to copying svg of React Icons instead of importing the element?

Using React Icons, I imported about 15 icon elements. Then I realized in DevTools that I can simply copy the SVG that the React Icon element produces. I'm mainly concerned about performance and I'm using Webpack to build my React App. With that in mind, I'm wondering what costs the least computing and/or data between the two. I figured using the SVG element is less importing work which may lower the size of the payload a little bit?
If it helps to visualize this, I'm wondering if using a React icon like this...
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="28" width="28" xmlns="http://www.w3.org/2000/svg"><path d="M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zM167.2 307.5c5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5 4.6 8.8 9.3 17.5 14.3 26.1zm-30.3-120.3c14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26-6.3-14.9-11.6-29.5-16-43.6zm27.4 68.9c6.6-13.8 13.8-27.3 21.4-40.6s15.8-26.2 24.4-38.9c15-1.1 30.3-1.7 45.9-1.7s31 .6 45.9 1.7c8.5 12.6 16.6 25.5 24.3 38.7s14.9 26.7 21.7 40.4c-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6s-30.9-.5-45.6-1.4c-8.7-12.7-16.9-25.7-24.6-39s-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zm-149.7-15c25.3 0 45.8-20.5 45.8-45.8s-20.5-45.8-45.8-45.8c-25.3 0-45.8 20.5-45.8 45.8s20.5 45.8 45.8 45.8z"></path></svg>
will load faster than importing the same icon like this:
import {FaReact} from 'react-icons/fa';
const Example = () => {
return <FaReact/>
}

X3D: how to add coordinates dynamically into DOM for a IndexedFaceSet?

This is my x3d dom context:
<x3d>
<Scene>
<Shape>
<Appearance>
<Material diffuseColor="0 0 1" emissiveColor="0 0.5 0" shininess="0.8" specularColor="0.5 0.5 0.5"/>
</Appearance>
<IndexedFaceSet id="idxFS">
<!--Coordinate point with values dynamically when function addFaces() is called-->
</IndexedFaceSet>
</Shape>
</Scene>
</x3d>
This is my function addFaces() which is called when a button is pressed
function addFaces()
{
let faces = document.getElementById('idxFS');
faces.setAttribute('coordIndex', '0 1 2 3 -1 7 6 5 4 -1 0 4 5 1 -1 1 5 6 2 -1 2 6 7 3 -1 3 7 4 0');
let coords = document.createElement('Coordinate');
coords.setAttribute('point', '-2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 -2.0 -2.0 2.0 -2.0 -2.0 -2.0 2.0 2.0 -2.0 2.0 2.0 -2.0 -2.0 -2.0 -2.0 -2.0');
faces.appendChild(coords);
}
But the part with the coordinates does not work. If I put the coordinates static into the DOM it works. like it can be seen here https://www.web3d.org/x3d/content/examples/ConformanceNist/Geometry/IndexedFaceSet/default_facesetIndex.html
But my dynamic version does not work. Help would be much appreciated!! I've tried for hours now but I could not get it to work.

Is it possible to create single path SVG for below image?

I was able to create this(however it has the transparent part at the center - want it solid white)
"M62,31c0,17.1-13.9,31-31,31S0,48.1,0,31S13.9,0,31,0S62,13.9,62,31z M48.5,43.9L46,44l-7.3-11.3 c-0.5-0.8-1.4-1.2-2.3-1.2L26.7,32l-0.2-2.8l9.6-2.7c0.9-0.3,1.4-1.2,1.2-2.1c-0.2-0.9-1.2-1.4-2.1-1.2l-8.9,2.5L25.9,19 c-0.1-1.4-1.3-2.5-2.7-2.4c-1.4,0.1-2.5,1.3-2.4,2.7l0.9,15.6c0.1,1.4,1.3,2.5,2.7,2.4l10.7-0.6L42.5,48c0.5,0.7,1.3,1.2,2.1,1.2 c0,0,0.1,0,0.1,0l4-0.1c1.4-0.1,2.5-1.2,2.5-2.6C51.1,44.9,49.9,43.8,48.5,43.9z M23.4,6c-2.8,0-5.1,2.3-5.1,5.1s2.3,5.1,5.1,5.1 s5.1-2.3,5.1-5.1S26.2,6,23.4,6z M35.2,42.4c-0.2,5.7-4.8,10.2-10.5,10.2c-5.8,0-10.5-4.7-10.5-10.5c0-3.5,1.8-6.7,4.5-8.6v-3.9 c-4.6,2.3-7.9,7-7.9,12.5c0,7.7,6.2,13.9,13.9,13.9c6.1,0,11.3-4,13.2-9.5L35.2,42.4z"
Path 1 result :
Later, I was able to extract another path for the center figure, which is:
"M40.3,40.3c0.1,1.4-1,2.6-2.5,2.6l-4,0.1c0,0-0.1,0-0.1,0c-0.9,0-1.7-0.4-2.1-1.2l-7.3-11.3l-10.7,0.6 c-1.4,0.1-2.6-1-2.7-2.4L10,13.3c-0.1-1.4,1-2.6,2.4-2.7c1.4-0.1,2.6,1,2.7,2.4l0.4,6.8l8.9-2.5c0.9-0.2,1.8,0.3,2.1,1.2 c0.3,0.9-0.3,1.8-1.2,2.1l-9.6,2.7l0.2,2.8l9.6-0.5c0.9,0,1.8,0.4,2.3,1.2L35.1,38l2.5-0.1C39.1,37.8,40.3,38.9,40.3,40.3z M12.5,10.2c2.8,0,5.1-2.3,5.1-5.1S15.4,0,12.5,0C9.7,0,7.4,2.3,7.4,5.1S9.7,10.2,12.5,10.2z M13.9,46.6c-5.8,0-10.5-4.7-10.5-10.5 c0-3.5,1.8-6.7,4.5-8.6v-3.9C3.2,25.9,0,30.6,0,36.1C0,43.8,6.2,50,13.9,50c6.1,0,11.3-4,13.2-9.5l-2.7-4.1 C24.2,42,19.6,46.6,13.9,46.6z"
Path 2 result :
Looking for a single path SVG, which creates an exact image like .
Thank you in advance.
Haters will say I'm cheating. And they will be absolutely right.
<svg
width="60"
height="60"
style="background-color: LightSalmon; border-radius: 100%"
viewBox="1 1 60 60"
>
<path d="M62 31c0 17.1-13.9 31-31 31S0 48.1 0 31 13.9 0 31 0s31 13.9 31 31zM48.5 43.9L46 44l-7.3-11.3c-.5-.8-1.4-1.2-2.3-1.2l-9.7.5-.2-2.8 9.6-2.7c.9-.3 1.4-1.2 1.2-2.1-.2-.9-1.2-1.4-2.1-1.2l-8.9 2.5-.4-6.7c-.1-1.4-1.3-2.5-2.7-2.4-1.4.1-2.5 1.3-2.4 2.7l.9 15.6c.1 1.4 1.3 2.5 2.7 2.4l10.7-.6L42.5 48c.5.7 1.3 1.2 2.1 1.2h.1l4-.1c1.4-.1 2.5-1.2 2.5-2.6-.1-1.6-1.3-2.7-2.7-2.6zM23.4 6c-2.8 0-5.1 2.3-5.1 5.1s2.3 5.1 5.1 5.1 5.1-2.3 5.1-5.1S26.2 6 23.4 6zm11.8 36.4c-.2 5.7-4.8 10.2-10.5 10.2-5.8 0-10.5-4.7-10.5-10.5 0-3.5 1.8-6.7 4.5-8.6v-3.9c-4.6 2.3-7.9 7-7.9 12.5C10.8 49.8 17 56 24.7 56c6.1 0 11.3-4 13.2-9.5l-2.7-4.1z"/>
</svg>
The real answer is that compound paths in a single <path/> element can only have one style (as the style is defined by the said path).

Render javascript in svg

Adding js snippets to an svg file does render in the browser (Firefox), but when i convert the same file to some output formats (like png or pdf etc.) the javascript parts aren't rendered and don't show in the output files. Below is what i am trying to do (drawing a filled rectangle around a path shape):
<svg width="793.70081" height="1122.51965" version="1.1" id="toplevel"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="rectG" x="0" y="0" width="50" height="50" fill="yellow" transform="translate(100 200) scale(0.1 -0.1) "/>
<path id="pathG" d="M390.01 151l73 -366c43.3333 10 78.1667 31.3333 104.5 64c26.3333 32.6667 39.5 70.3333 39.5 113c0 52 -18.3333 96.8333 -55 134.5c-36.6667 37.6667 -81.3333 56.5 -134 56.5c-9.33333 0 -18.6667 -0.666667 -28 -2zM472.01 861c-5.33333 32 -10 53 -14 63
c-9.33333 20 -25 30.6667 -47 32s-45 -22.6667 -69 -72c-22.6667 -44.6667 -38.6667 -93.6667 -48 -147c-0.666667 -4 -1 -10 -1 -18c0 -22 2.5 -52 7.5 -90s9.16667 -62.3333 12.5 -73l36 33c13.3333 5.33333 35.3333 30.3333 66 75c39.3333 58 59 113.333 59 166
c0 10.6667 -0.666667 21 -2 31zM351.01 251l-27 141c-10.6667 -8 -31.6667 -29 -63 -63c-31.3333 -34 -55.3333 -61.6667 -72 -83c-66.6667 -86 -100 -164 -100 -234c0 -23.3333 3.33333 -46.6667 10 -70c10 -32.6667 34.6667 -68 74 -106
c57.3333 -54.6667 121.667 -80.6667 193 -78c23.3333 0.666667 48.6667 5.66667 76 15l-76 378c-49.3333 -6.66667 -87.3333 -30.6667 -114 -72c-20 -31.3333 -30.6667 -65.3333 -32 -102c-1.33333 -40 21 -78.3333 67 -115c39.3333 -31.3333 70.3333 -47.3333 93 -48v-10
c-29.3333 3.33333 -63.6667 19 -103 47c-52.6667 37.3333 -84 81.3333 -94 132c-3.33333 15.3333 -5 31 -5 47c0 52 16 98.6667 48 140s73.6667 68.3333 125 81zM401.01 1077c26 0.666667 51.3333 -32.6667 76 -100c21.3333 -58.6667 33.6667 -115.333 37 -170
c4 -64.6667 -5.33333 -129 -28 -193c-29.3333 -82.6667 -77.3333 -150.667 -144 -204l30 -155c18 2.66667 35.3333 4 52 4c82 0 145.667 -31 191 -93c40 -54 58.3333 -117.333 55 -190c-2.66667 -58.6667 -22 -108.167 -58 -148.5s-83.3333 -67.5 -142 -81.5l41 -229
c2 -9.33333 3 -18.6667 3 -28c0 -46 -19.8333 -86.5 -59.5 -121.5s-82.8333 -52.5 -129.5 -52.5c-43.3333 0 -82.6667 18 -118 54c-32.6667 34 -49 69 -49 105c0 30.6667 11.5 57.3333 34.5 80s49.8333 33.6667 80.5 33c28.6667 -0.666667 53.3333 -10.5 74 -29.5
s31.3333 -42.5 32 -70.5c0.666667 -29.3333 -9 -54.8333 -29 -76.5s-45 -32.5 -75 -32.5c-5.33333 0 -10.6667 0.333333 -16 1c32.6667 -30 64.6667 -43.3333 96 -40c20 2 44.6667 13.3333 74 34c42.6667 30.6667 64 70 64 118c0 9.33333 -1 19 -3 29l-39 218
c-18 -4 -51.3333 -6.66667 -100 -8c-94 -2.66667 -176.167 31.5 -246.5 102.5c-70.3333 71 -105.167 155.167 -104.5 252.5c0 53.3333 25 119.333 75 198c36 56.6667 82.3333 116 139 178c46 50.6667 72.3333 77.3333 79 80c-12.6667 30.6667 -25.6667 96.6667 -39 198
c-1.33333 10.6667 -2 22 -2 34c0 65.3333 14.6667 131 44 197c31.3333 70.6667 66.3333 106.333 105 107z" transform="translate(100 200) scale(0.1 -0.1) "/>
<script type="text/javascript"><![CDATA[
var x = document.getElementById("pathG");
bb=x.getBBox();
var rect = document.getElementById("rectG");
rect.setAttribute('x', bb.x);
rect.setAttribute('y', bb.y);
rect.setAttribute('width', bb.width);
rect.setAttribute('height', bb.height);
]]></script>
</svg>
This shows in Firefox:
but in Inkscape, or converting the svg file to pdf or png using commandline tools like rsvg-convert or cairosvg doesn't show the rectangle. Is there a way to achieve this?
Most SVG editors, viewers and convertors presumably do not execute JavaScript in SVG documents; they expect static XML text files. (This applies even for browser if you load such SVG as image or CSS background-image.)
If you have your SVG document displayed in browser (as document, so JS is interpreted and runs), you can then obtain resulting source code from web console using
copy(document.documentElement.outerHTML)
command: it should place SVGs source even with elements and attributes generated by JS. (It will include <script> tags as well, but since they are not needed anymore because their outcome is already present, you can safely remove them. Or you can remove them prior copying with while(x=document.querySelector('script'))x.remove();copy(document.documentElement))

Chrome adds attributes [requiredExtensions, systemLanguage] when logging a cloned SVGElement [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Issue
Was working with transforms on SVGElements and discovered something I do not comprehend.
Basically I am trying to clone an exising SVGElement using cloneNode(true) and change its Matrix by using transform.baseVal.getItem(0).setMatrix(). This all works fine as long as I do not log the new SVGElement using console.log().
Here is an example
Have to check the actual console and not the inline output of the snippet.
;window.onload = function(){
var tSVG = document.querySelector('svg');
var tSVGElement = tSVG.querySelector('#AL > g');
var tSVGElement2 = tSVGElement.cloneNode(1);
var tMatrix2 = tSVGElement2.transform.baseVal.numberOfItems ? tSVGElement2.transform.baseVal.getItem(0).matrix : tSVGElement2.transform.baseVal.appendItem(tSVG.createSVGTransform()).matrix
console.log(1, tSVGElement2);
tMatrix2.e += 50;
tMatrix2.f += 50;
tSVGElement2.transform.baseVal.getItem(0).setMatrix(tMatrix2)
tSVGElement.parentNode.appendChild(tSVGElement2);
console.log(2, tSVGElement2);
};
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2253" width="811" height="661">
<g id="AL" class="Touchable">
<g transform="matrix(0.0736096,0,0,0.0736094,313.881,379.029)">
<g stroke-width=".39819491" transform="matrix(2.51133 0 0 2.51134 -239.06 -636.03)">
<rect width="397" height="397" x="95.790001" y="253.86" fill="#ccc" stroke="#000" stroke-width="1.19458485" stroke-miterlimit="3" ry="0" rx="0"></rect>
<path fill="#fff" d="M153.88 347.3H354.4v207.58H153.88z"></path>
<path fill="#010002" d="M202.2 395.8c-3.22-3.24-4.84-7.17-4.84-11.8 0-4.63 1.62-8.55 4.85-11.8 3.3-3.23 7.2-4.85 11.8-4.85 4.6 0 8.6 1.62 11.8 4.86 3.3 3.3 4.9 7.2 4.9 11.8 0 4.6-1.6 8.6-4.8 11.8-3.2 3.3-7.1 4.9-11.8 4.9-4.7 0-8.5-1.6-11.8-4.8zm-21.32 79.6c1.04.8 2.26 1.22 3.64 1.22 1.4 0 2.6-.4 3.65-1.22 1.04-.8 1.56-2.13 1.56-3.98v-45.1c0-.7.34-1.16 1.04-1.4.7-.22 1.27-.33 1.73-.33.46 0 1.04.1 1.74.3.7.2 1.04.7 1.04 1.4V530c0 2.1.75 3.83 2.25 5.2 1.5 1.4 3.3 2.1 5.38 2.1s3.9-.7 5.4-2.1c1.5-1.37 2.3-3.1 2.3-5.2v-63.46c0-1.16.5-1.9 1.4-2.26.9-.36 1.6-.53 2.1-.53s1.1.18 1.9.52c.8.34 1.2 1.1 1.2 2.25V530c0 2.08.8 3.8 2.3 5.2 1.5 1.4 3.3 2.08 5.4 2.08 2.3 0 4.2-.7 5.6-2.07 1.4-1.4 2.1-3.1 2.1-5.2l.4-103.7c0-.7.4-1.1 1.1-1.4.7-.2 1.3-.3 1.78-.3.5 0 1.05.1 1.75.4.7.3 1 .7 1 1.4v45.1c0 1.9.5 3.2 1.55 4 1 .8 2.2 1.2 3.45 1.2s2.4-.4 3.46-1.2c1.03-.8 1.55-2.1 1.55-4v-47.9c0-4.6-1.54-8.8-4.66-12.5-3.15-3.7-7.37-5.5-12.7-5.5h-36.5c-5.3 0-9.2 1.9-11.6 5.6-2.44 3.7-3.65 7.8-3.65 12.5v47.8c0 1.9.5 3.2 1.53 4zm179.86-134.93c2.08 1.96 3.12 4.45 3.12 7.46v206.73c0 3-1.04 5.5-3.12 7.46-2.1 1.97-4.63 2.95-7.64 2.95H155.04c-3 0-5.55-.98-7.63-2.95-2-1.96-3.1-4.45-3.1-7.46V347.93c0-3 1.1-5.5 3.1-7.46 2.1-1.97 4.7-2.95 7.7-2.95h198c3 0 5.6.98 7.7 2.95zm-14.23 14.4H161.7v192.86h184.8V354.86zm-52.7 45.78c4.6 0 8.6-1.62 11.8-4.85 3.2-3.23 4.9-7.17 4.9-11.8 0-4.63-1.6-8.55-4.8-11.8-3.2-3.23-7.1-4.85-11.8-4.85-4.6 0-8.5 1.62-11.8 4.86-3.2 3.3-4.8 7.2-4.8 11.8 0 4.6 1.6 8.6 4.9 11.8 3.3 3.2 7.2 4.9 11.8 4.9zm-33.1 74.75c1.1.8 2.3 1.22 3.7 1.22 1.4 0 2.6-.4 3.7-1.22 1.1-.8 1.6-2.13 1.6-3.98v-45.1c0-.7.4-1.16 1.1-1.4.7-.22 1.3-.33 1.8-.33s1.1.1 1.8.3c.7.2 1.06.7 1.06 1.4V530c0 2.1.75 3.83 2.25 5.2 1.5 1.4 3.3 2.1 5.4 2.1 2.08 0 3.87-.7 5.38-2.1 1.5-1.37 2.27-3.1 2.27-5.2v-63.46c0-1.16.43-1.9 1.4-2.26.9-.35 1.6-.53 2.1-.53s1.1.18 2 .52c.95.34 1.4 1.1 1.4 2.25V530c0 2.08.7 3.8 2.1 5.2 1.4 1.4 3.24 2.08 5.56 2.08 2.1 0 3.9-.7 5.4-2.07 1.5-1.4 2.26-3.1 2.26-5.2V426.3c0-.7.3-1.16 1-1.4.7-.22 1.25-.33 1.7-.33.46 0 1.03.1 1.73.32s1.02.7 1.02 1.4v45.1c0 1.8.5 3.1 1.56 3.9 1.05.8 2.27 1.2 3.65 1.2 1.4 0 2.6-.4 3.65-1.2 1.04-.8 1.56-2.2 1.56-4v-47.8c0-4.7-1.6-8.8-4.84-12.5-3.25-3.7-7.53-5.6-12.84-5.6H275c-5.3 0-9.26 1.8-11.8 5.5-2.55 3.7-3.8 7.8-3.8 12.5v47.8c0 1.8.5 3.1 1.54 4zm180.6 49.16h-15.6V472.7s.1-2.13-2.7-2.13h-23.7c-3.9 0-3.2 2.55-3.2 2.55v52.52h-16.8c-4.9 0-.4 4.27-.4 4.27l29.8 36.1s2.5 2.9 5.1.3c3.6-3.5 28.9-37.2 28.9-37.2s4.5-4.4-1.4-4.4zm-61.2-140.98h15.6v51.85s0 2.14 2.7 2.14H422c3.88 0 3.2-2.56 3.2-2.56v-52.5H442c4.9 0 .4-4.2.4-4.2l-29.87-36.1s-2.45-2.8-5.02-.3c-3.5 3.6-28.9 37.3-28.9 37.3s-4.5 4.5 1.5 4.5z"></path>
</g>
</g>
</g>
</svg>
Expected output:
<g transform="matrix(0.0736096 0 0 0.0736094 363.881 429.029)">..</g>
Actual output:
<g transform="matrix(0.0736096 0 0 0.0736094 363.881 429.029)" requiredExtensions="" systemLanguage="">..</g>
So as soon as I log the cloned SVGElement Chrome adds the two attributes requiredExtensions and systemLanguage, which leads to the element no being rendered. As soon as I remove the console.log(tSVGElement2); on the clone it all works fine.
Why does Chrome add those two attributes on logging?
IE11 adds it also just on the child element.
FOR YOUR WHY QUESTION:
I opened an issue for this, confirmed by chrome (https://bugs.chromium.org/p/chromium/issues/detail?id=873470), seems like this is a bug. And the reason is:
I'd guess that this is caused by attribute synchronization, and the reason console.log triggers it is that it enumerates all properties and thus creates the tear-off/wrapper for systemLanguage/requiredExtensions - which in turn makes them require synching.
pre-edit: Seems like I was wrong about namespace not being inherited, one interesting thing is though ‘requiredExtensions’ attribute should either be set to 'true' or not exist for an element to render. This is part of SVG spec # 5.7.1 here and normally the attribute (together with systemLanguage) is set on the switch element. Interestingly, consoling the cloned g within the main thread, adds this attribute with value "" which translates to false and ends up the element not being rendered.
However if you wait for the event loop to finish and then log, the attributes are not there, see this FIDDLE.
As a conclusion, if you clone a g node and console log it without appending it to the tree, these attributes will appear and the element won't be rendered. Though I do not know whether this was the intended behavior or a bug.
SOLUTION
Until the behavior is sorted out, monkey patch the appendChild, I had to use a microtask queue because apparently the attributes are added during calling appendChild:
SVGGraphicsElement.prototype.appendChild = (function(append){
return function(node){
setTimeout(function(){
node.removeAttribute("requiredExtensions");
node.removeAttribute("systemLanguage");
},0);
return append.apply(this,arguments);
}
}(SVGGraphicsElement.prototype.appendChild));
http://jsfiddle.net/ibowankenobi/8s97ophj/
SOLUTION 2:
Obviously, you'd have to monkey patch other functions that modify DOM tree as well such as inserNode etc. In that case a mutation observer provides a more generic solution. You can watch multiple times with different parents, the same observer is recycled:
function watch(node,parentNode){
var config = watch._config,
callback = function(list,observer){
list.forEach(function(d,i){
if(d.type !== "childList"){return}
if(
Array.prototype.slice.call(d.addedNodes)
.some(function(d,i){
return d === node
})
) {
console.log("added??");
setTimeout(function(){
node.removeAttribute("requiredExtensions");
node.removeAttribute("systemLanguage");
},0);
observer.disconnect();
}
})
},
observer = node._observer || (node._observer = new MutationObserver(callback));
observer.observe(parentNode,config);
return node;
}
watch._config = {childList:true,subtree:true};
to use:
var tSVG = document.querySelector('svg');
var tSVGElement = tSVG.querySelector('#AL > g');
var tSVGElement2 = tSVGElement.cloneNode(1);
watch(tSVGElement2,tSVGElement.parentNode/*Or tSVG since subtree:true*/);
....
Once in the DOM, the observer is disconnected and the attributes are removed, you can modify the function and provide a list of attributes to change if you want. See this working FIDDLE
~~This happens because you are not cloning the entire svg, but the g, at that instant the xmlns is not defined for this g because it inherited it from its ownerSVG. The moment you append it to its parent svg, the browser understands that it is part of SVG. If you console log after tSVGElement.parentNode.appendChild(tSVGElement2), it should output fine.~~

Categories