I'm writing a plugin for a bigger application which is in HTML5.
The plugin contains a svg which displays relations. I would like to add linearGradients to the svg, but that doesn't quite work because the output tags are in lower cases 'lineargradient' instead of 'linearGradient'. I already tried to add the namespace to the svg element, but that didn't help.
Also created an extra document object with svg Doctype and namespace. The tags were now correct, but in that way I won't get the linearGradient object to the plugin in the html5 document object.
The problem seems to be the document.createElement function, which is called when creating a linearGradient object. It formats the tag to lowercase if the tag is not in the namespace
Is there any way to create a working linearGradient?
Edit:
I also tried to use document.importNode and document.adoptNode to import/adopt a node that I created with a SVG Document, but they seem to use the createElement function, as the important tag 'linearGradient' ist still written lowercase and though not working.
Related
This is a follow up question to: Get DOM element by custom attribute value inside SVG
The answer was correct and let elem = document.querySelector('*[v\\:lbl="MY_UNIQUE_ID_1"]'); works fine with inline SVG.
But now I have an issue when the SVG (with the same code) is loaded from a file using the html object element or d3.js or even then the file is just opened in the browser. Then that function stops working. Something weird goes on with the namespaces and the xpath of that node.
The inline SVG has xpath: //*[#id="shape1014-243"]/v:custprops/v:cp
The SVG launched from file has xpath: //*[#id="shape1014-243"]/custProps/cp
It works fine if I select the G lement by ID (it has no namespace), so it is clearly something to do with the namespace.
What should be the selector if SVG is loaded from the file? Or how to load the file and retain the v: namespace in the xpath?
I looked at example of UDNZTimeline widget and saw in Chrome developer tools
that along with svg tag there is a div tag, containing dot tags. Also I saw pole tags somewhere in UDNZTimeline example. I don't see these tags in SVG reference although Chrome highlights visual elements on hover these tags.
The structure is like following:
<svg>
<line ...>
and other SVG tags
</svg>
<div>
<dot ....>
<pole ....>
and other non-svg tags which are visualized nevertheless
</div>
What are these tags? How to learn about their meaning?
You can define custom elements in most browsers now:
customElements.define(name, constructor, options);
But after having a closer look, it seems dot is no defined custom element (customElements.get('dot'); returned undefined).
So it seems like the devs just created elements with with name (see the source code here and here).
There seems to be no problem with browsers, since it falls back to HTMLUnknownElement, see the discussion here.
And if you want to find out more about it, here is the link to the main script.
I have a large SVG and I need to access its 'path' to modify.
I pasted SVG directly in my app. but I want to split my code and make it more clear.
so I moved my SVG in an SVG file and I need to import the SVG file so that I can access its 'path'.
solutions that I found are using img tag. But this way I can't access 'path'.
The trick is to use the HTML "object" tag to embed the SVG.
<object type="image/svg+xml" data="src/beacon.svg" class="logo">
Beacon Logo <!-- fallback image in CSS -->
</object>
After you do so, you can target the "object" tag by using "querySelector" and then get access to the SVG document by using "getSVGDocument()" method. After that use regular Javascript to select the paths from the document and manipulate as you like. Pseudo code is as follows;
let svgDoc = document.querySelector("object.logo").getSVGDocument();
let svgPaths = svgDoc.querySelectorAll('path');
I use very large SVG files as well. My SVG is organized using separate groups (g) that are assigned a css attribute. Then, I can use Greensock (gsap) to animate. The tricky part is that SVGs are very sensitive. For path-based animations, they must be put in html (not linked to svg file).
So, to overcome that clutter you are describing. I started creating what I call "content blocks". You create a content block such as large-svg-file.html and then use a single line of "include" script for the intended page. This is ALSO handy if you wish to use this content block on different web pages.
Example: ##include('./blocks/large-svg-file.html')
Note: I usually put these files in a folder called "blocks" to separate them out from the primary html files.
I am not sure if you are using PHP, Grunt, Gulp (server-side include), or whatever; but, sadly there is no include code that is html only. So, you will need to pick your favorite solution. Here is a great tutorial that shows you how to apply the option of your choice: https://css-tricks.com/the-simplest-ways-to-handle-html-includes/
You can open it any browser & inspect the code and copy it. And put in a html file for modify.
I am trying to give the user an ability to manually edit an SVG document.
Is there a strait forward way to use DOM to extract all the elements from an SVG document and place it in a text box? I tried to use innerHTML but that didn't work (not available for SVG).
Is there a method within JavaScript to extract all SVG elements from an embedded SVG document and store them as a string? I don't want to use jQuery or plugin if I can avoid it..
Sorry for my wording, my english is very poor.
You can use XMLSerializer to do this.
var str = new XMLSerializer().serializeToString(svgDocument);
If you have an <object> tag that references the svg, your svgDocument variable should be set to something like yourObjectElm.contentDocument. If the svg is inline in the html, then you can pass the element(s) instead of the document.
I'm trying to create Dynamic SVG graphics, it is my understanding that the only way to create dynamic SVG is to use a scripting language, so I have a few questions, basically I'd like to load or embed the SVG to a HTML web page and control the graphics using Inputs in the web page, rather than hardcoding the ECMAscript in the SVG file. I'm not entirely sure if I should use the embed tag or an iframe for displaying the SVG here are my doubts regarding SVG and scripting:
Whats the difference (in terms of scripting) in using an <iframe> or and <embed> tag for accessing the SVG elements?, maybe someone can include simple examples.
Can SVG evaluate math expressions in element attributes(just to be sure)?
Don't use either <iframe> or <embed>. Instead, embed your SVG directly in XHTML like so:
http://phrogz.net/svg/svg_in_xhtml5.xhtml
With that, you have full access to the SVG DOM as part of your document. As shown in that example, you simply need to be certain to create SVG elements (but not attributes) using the SVG namespace. You must also ensure that your web host is sending the content type for xhtml as application/xhtml+xml or text/xml, not text/html.
phrogz$ curl --silent -I http://phrogz.net/svg/svg_in_xhtml5.xhtml | grep "Type"
Content-Type: application/xhtml+xml
For more examples of JavaScript manipulating SVG mixed with HTML, see the various .xhtml files in that same directory. A particularly compelling example is this one, which dynamically creates hundreds of small SVG files as inline elements flowing like text.
And to your question:
Can SVG evaluate math expressions in element attributes(just to be sure)?
Not in general, no. However, the usage of SMIL Animation does allow you to specify various interpolation methods of properties over time.
Finally, note that you don't have to put SVG in HTML to make it dynamic. You can script SVG with JavaScript directly. For example, see this test file (press the green button to start simulation):
http://phrogz.net/svg/SpringzTest.svg
Whats the difference (in terms of scripting) in using an or and tag for accessing the SVG elements?, maybe someone can include simple examples.
<iframe>:
Scripts trying to access a frame's content are subject to the same-origin policy, and cannot access most of the properties in the other window object if it was loaded from a different domain. This also applies to a script inside a frame trying to access its parent window. Cross-domain communication can still be achieved with window.postMessage.
Source: https://developer.mozilla.org/en/HTML/Element/iframe#Scripting
We access iframe content by iframe_element.contentWindow method:
<html>
<body>
<iframe id="SVG_frame" src="image.svg"></iframe>
</body>
<script>
var SVG_frame = document.getElementById ( "SVG_frame" );
var SVG_content = null;
function getContent ()
{
SVG_content = SVG_frame.contentWindow;
SVG_content ? alert ( "YAY!" ) : alert ( "BOO!" );
}
SVG_frame.onload = getContent;
</script>
</html>
<embed>:
Example (view source): https://jwatt.org/svg/demos/scripting-across-embed.html
(both methods fail at least in Chromium)
<object>
Example (view source): https://jwatt.org/svg/demos/scripting-across-object.html
Can SVG evaluate math expressions in
element attributes(just to be sure)?
like <element attribute="48/2*(9+3)"/>?
I did't find a word about it in SVG spec.
EDIT
Personally, I recommend to use <object> + Data URI Scheme and/or object_element.contentDocument. I've tested both in Chromium and Firefox.
AHA! <object> has similar security behavior to <iframe>: domain, protocol must be same for site and SVG file.
EDIT2
If You are interested how to get markup vector graphics to work in Internet Explorer(s) without plug-in(s), then Vector Markup Language is the way.
Well, it depends on what you mean with dynamic. In most cases yes, you'll probably want scripts. There's no difference if you put your script in the HTML or the SVG file, both will be executed by the same engine.
You can create interactive/animated svg content with the declarative animation elements (aka SMIL). You can also do simple hover effects with CSS :hover rules, or transitions with CSS3 Transitions.
XSLT can also be used to make somewhat dynamic svg content, since it can transform your input to something else. It doesn't cover the interaction aspect though.
You can access the svg elements from the HTML file that includes it with either of:
theEmbeddingElement.contentDocument (preferred, but doesn't work on <embed>)
or alternatively theEmbeddingElement.getSVGDocument().