add ajax sourced svg group to existing canvas - javascript

I have a blank svg canvas on my page
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="100%"
height="100%"
id="svg_canvas"
preserveAspectRatio="xMinYMin meet"
viewBox="0 0 250 250">
</svg>
I have another svg, with the following form, in an external file.
<?xml ...>
<svg id="external"
...>
<g id="lollipop"
...>
//LOTS OF VECTOR INSTRUCTIONS IN THIS GROUP
</g>
</svg>
I would like to ajax for the external svg and insert the lollipop group into the current canvas. I would accept answers which ajax for the entire .svg and parse out the group (id="lollipop") to insert. It may be preferable, though, to copy just the group i want and save that as a text file which can be called upon and parsed. Either way.

Using jQuery, here is the basic idea of what you want:
//here I have a hidden div element in my document called "hiddenDiv";
//I'm loading the SVG into the DOM via AJAX so we can access its elements.
$("#hiddenDiv").load("/some/path/to/yourfile.svg", function(){
//grab the content you want and add it to the canvas.
$("#lollipop").clone().appendTo("#svg_canvas");
//get rid of the extra unneeded svg
$("#hiddenDiv").empty();
}
EDIT After reading up on load, it has a nifty feature to easily do what you want:
$("#svg_canvas").load('/some/path/to/yourfile.svg #lollipop');
link to the docs: http://api.jquery.com/load/ see "Loading Page Fragments".

Related

SVG convert <g> tag to an <image> tag containing base64 PNG URI (read more)

I got an interesting problem (I hope!)
I have noticed that there are two "types" of SVGs
First we have the conventional SVG file with and tags for example:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 841.89 1190.55" style="enable-background:new 0 0 841.89 1190.55;" xml:space="preserve">
<g id="Background">
<rect id="Color1" class="st3" width="840.94" height="1190.55"/>
<g id="Texture" class="st4">
<path class="st5" d="M843.67,410.13c-73.29 ...
Secondly we have embedded tags in the image, not sure what to call them, so I've just named them "fake SVG", an example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3718" height="4899" viewBox="0 0 3718 4899">
<image id="Lager_1" data-name="Lager 1" width="185.9" height="244.95000000000002" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUh ...
My question is: Is there is any smooth way to convert a conventional SVG into a "fake" SVG? (please tell me if they have a real name). Also keep in mind that I would like to keep the groupings so each <g> should convert to a <image> tag
My thoughts: I am thinking about loading the conventional SVG into a <canvas> tag, it seems to be able to understand the <g> groupings in the conventional SVG well and consistently, and from there, somehow, convert those groups individually into base64 PNG URI, and reconstruct it into a fake SVG, perhaps there should be some library out there that can help out, does anyone have any ideas?
I'm not sure if this will exactly answer what you are trying to do, but you can do this:
<image id="something" href='data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" .../>' />
Where you can just embed the original SVG as a string in the href when the encoding is set to data:image/svg+xml;utf8.
This will render the SVG in an <image> tag, but not in Base64 (I could not get this working, but there may be a way).
Source: https://css-tricks.com/probably-dont-base64-svg/
It is possible to convert an inline SVG with tags in the DOM to an image data-url. You just need to turn it into one like this:
imageTag.src = 'data:image/svg+xml,' + window.escape(svgTag.outerHTML);
The imageTag version can not have external links embedded in the SVG. It also needs width and height attributes on the SVG tag otherwise it will not show in some browsers. You could also draw this image to a canvas to rasterize the image, but as the comment mentioned that would only make it uglier if scaled.
If you want to convert it to a SVG file you should add this as a first line and then add the outerHTML of the svgTag.
<?xml version="1.0" encoding="UTF-8"?>
You can save the file with the .svg extension

How do i get the data of the paths and shapes of an <image> tag within an svg

I am having problems with the displaying of my image with as a source an URL, the problem is that is will not show within my svg <mask> when used as a <image x="0" y="0" height="350" width="350" attr.xlink:href="URL"> I know this must work because when i place the tag anywhere else in the svg it does show, but because i want it within the <mask> i need to find a way to succeed. when i open the image in a notepad file and copy the data into the <mask> tag it works perfectly, but because i need the <image> to change when the url changes i cannot hard code it into the <mask>
therefore the solution i thought of was to convert the <image> to a string to obtain the data and put this into a variable which i can place inside the mask. But i cannot find anywhere how i should convert this if it is even possible.
i want to convert this element of my html page
<svg xmlns:attr.xlink="http://www.w3.org/2000/xlink">
<image height="350" width="350" attr.xlink:href="URL"></image>
</svg>
into this to put it in a variable:
<polygon points="135.956,125.591 137.161,130.401 142.109,130.061 137.906,132.693 139.759,137.294 135.956,134.111 132.153,137.294 134.006,132.693 129.803,130.061 134.751,130.401 "/>
<polygon points="205.763,125.24 206.968,130.05 211.915,129.71 207.713,132.343 209.566,136.943 205.763,133.76 201.96,136.943 203.812,132.343 199.61,129.71 204.557,130.05 "/>
<g>
<g>
<path d="M155.837,153.597c0,0,0.126-0.008,0.362-0.022c0.236-0.012,0.582-0.034,1.024-0.034 c0.441-0.003,0.979,0.018,1.591,0.059c0.611,0.037,1.298,0.045,2.05,0.025c0.752-0.022,1.565-0.062,2.42-0.161 c0.852-0.111,1.778-0.246,2.727-0.261c0.948-0.025,1.931-0.039,2.93,0.068c 0.498,0.049,0.989,0.105,1.484,0.129 c0.494,0.027,0.996,0.034,1.493,0.032c1.008,0.01,1.986-0.048,2.979-0.162c0.998-0.109,1.985-0.093,2.929-0.069 c0.477,0.017,0.943,0.039,1.401,0.092c0.453,0.058,0.896,0.114,1.327,0.168c0.854,0.099,1.667,0.138,2.42,0.161 c0.751,0.02,1.439,0.011,2.05-0.025c0.612-0.041,1.15-0.063,1.591-0.059c0.441,0,0.788,0.022,1.024,0.034 c0.236,0.014,0.362,0.022,0.362,0.022s-0.504,0.028-1.381,0.124 c-0.439,0.045-0.967,0.131-1.579,0.225 c-0.612,0.095-1.307,0.17-2.065,0.199c-0.756,0.035-1.579,0.056-2.451-0.006c-0.872-0.067-1.767-0.145-2.703-0.138 c-0.941-0.001-1.905,0.037-2.883,0.144c-0.981,0.124-2.014,0.198-3.018,0.195c-0.509-0.004-1.014-0.016-1.521-0.049 c-0.506-0.03-1.011-0.093-1.501-0.147c-0.977-0.108-1.944-0.145-2.882-0.144 c-0.939-0.006-1.832,0.069-2.704,0.138 c-0.872,0.062-1.695,0.04-2.451,0.006c-0.757-0.029-1.453-0.104-2.064-0.199c-0.611-0.093-1.14-0.179-1.579-0.224 C156.341,153.625,155.837,153.597,155.837,153.597z"/>
</g>
</g>
is there a way to do this in javascript/typescript? or should i try some other way. i am using angular in this project
EDIT
i am trying it this way because i do not know what to do to fix my problem in my angular application.
i am trying to show designs on productimage for a webshop, the designs consists of text elements, which the users can adjust, and most of the time a svg logo of some sorts. because the designs mostly consists out of different colors, i am working with masking to make sure the correct design is shown. The problem is that the logo is not showing but the text is and when i paste the raw data into the mask it is working only with a tag within the mask it is not. therefore i am trying to obtain the raw data out of the image tag which i now have hidden on the top of my html page

D3 Multiple Visualizations Per Page Namespace IRI Conflicts [duplicate]

I've enbedded d3's force directed graph layout into extjs tabs so that each time a new tab gets added a new graph svg gets generated.
No Problemo so far.
Now I intended to turn the graph into a directed one (by adding a marker and tell the lines to use it)
Each generated svg elements is following this pattern:
<svg width="100%" height="100%">
<defs><marker id="end-arrow" viewBox="0 -5 10 10" refX="6" markerWidth="3" markerHeight="3" orient="auto"><path d="M0,-5L10,0L0,5" fill="#ccc"></path></marker>
</defs>
<g transform="translate(4,0) scale(1)"><line class="link" sig="30.84" style="stroke-width: 3;" x1="538" y1="347" x2="409" y2="467" marker-end="url(#end-arrow)"></line>
...
</g>
</svg>
With Crome everything works just fine.
So I arrived at the concusion that the structur and
the way I generate the svgs should be more or less correct.
But with Firefox the Markers will only show for the first svg. (the first tab)
All other svgs won't show any Arrowheads.
"Inspect Elements" tells me the Markers are there and that the lines are refering to them.
And this is where I'm running out of Ideas where or what to look for. :(
You have multiple non-distinct IDs within the same html or svg document. This is invalid, different UAs respond differently but as you're not allowed to do this, it doesn't really matter that they are inconsistent.

SVG clipPath not working in Firefox when defined dynamically

I have the following code:
<div class="blah" style="clip-path: url(#clippath)"></div>
<svg width="0" height="0"><defs><clipPath id="clippath">
<rect x="0" y="0" height="100" width="100"></rect>
</clipPath></defs></svg>
This correctly clips the blah div to 100x100 square. However, if I use JavaScript to add the svg to the DOM (rather than it being there from page load), it no longer works. Specifically, I'd like to create a dynamic clip path based on events happening in my app.
What am I doing wrong? This only needs to work in Firefox (which unfortunately doesn't support clip-path: polygon(...))
Make sure you are you using the namespace variant of createElement.
document.createElementNS("http://www.w3.org/2000/svg", "clipPath");
If you are just using createElement() then the element will be going into the default namespace (ie HTML) and won't be recognised by the SVG renderer.

Trying to create a re-usable text-box (text with a square background-colour) in SVG 1.1?

I'm trying to create (what I thought would be!) a simple re-usable bit of SVG to show three lines of text, with a background colour - to simulate a 'post-it' note.
I have found some useful code here to get the Bounds of the Text http://my.opera.com/MacDev_ed/blog/2009/01/21/getting-boundingbox-of-svg-elements which I am using.
So: I'm creating an group of text elements like this in the 'defs' section of my SVG:
<svg id="canvas" width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="post_it">
<text x="0" y="30" id="heading" class="heading">My Heading</text>
<text x="0" y="45" id="description" class="description">This will contain the description</text>
<text x="0" y="60" id="company" class="company">Very Big Company Ltd.</text>
</g>
And I'm displaying the text with a 'use' element like this:
<use id="12345" class="postit" xlink:href="#post_it" onclick="showId(this);"/>
I'm using the onclick to trigger a call to the following javascript function (defined in 'defs' section):
function showId(elem) {
post_it_rect=getBBoxAsRectElement(elem);
document.getElementById('canvas').appendChild(post_it_rect);
}
(The 'getBBoxAsRectElement(elem)' is from the link I posted).
As this stands; this works just fine - however if I change my 'use' element to position the text in a different place like this:
<use x="100" y="100" id="12345" class="postit" xlink:href="#post_it" onclick="showId(this);"/>
Now, the text displays in the correct place, but the resultant 'background-color' (actually a 'rect' element with opacity of 0.5) still shows on the top-left of the svg canvass - and the function used to calculate the rect is returning '-2' rather than '100' ('-98'?) as I need (I think).
What do I need to do to line up the 'rect' elements and the text elements ?
The author of the (very helpful article btw) script provides a more advanced script to draw a box round any 'bb' in an SVG, but I couldn't get this to work (missing 'transform' functions?).
I'm using Firefox 7.x to render the SVG ; and I'm loading a .svg file (ie, not embedded in html etc) straight from disk to test this).
Yes, you may need to compensate yourself for the x and y attributes on the <use> element for the time being, I'll try to find some time to update the blogpost and script.
Here's a draft SVG 1.1 test that among other things checks that the effect of the x and y attributes are included in the bbox. The line starting [myUse] is the one that tests this case, if it's red then that subtest failed. Chromium and Opera Next both pass that subtest, while Firefox nightly and IE9 doesn't. Note that the test itself has not gone through full review yet, and that it may still change.

Categories