SVG Inkscape generated file does not show flowRoot objects on browser - javascript

I´m dealing with SVG file in order to make some realtime animations on browser using AJAX.
Everything is fine except to make the browser (Chrome or IE9) to show the SVG image. The following HTML file does not show the flowRoot Text:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448"
height="600"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="lcl22.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="175.99454"
inkscape:cy="282.7269"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="706"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-452.36215)">
<path
sodipodi:type="arc"
style="fill:#008000;fill-opacity:1;stroke:#495677;stroke-width:23.16900063;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="circle1"
sodipodi:cx="227.14285"
sodipodi:cy="156.6479"
sodipodi:rx="47.142857"
sodipodi:ry="44.285713"
d="m 274.28571,156.6479 c 0,24.45833 -21.10658,44.28572 -47.14286,44.28572 C 201.10657,200.93362 180,181.10623 180,156.6479 c 0,-24.45832 21.10657,-44.28571 47.14285,-44.28571 26.03628,0 47.14286,19.82739 47.14286,44.28571 z"
inkscape:label="#path2985"
transform="translate(12.857143,635.71428)" />
<rect
style="fill:#00ff00;fill-opacity:1;stroke:#495677;stroke-width:4.86899996;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="box1"
width="284.28571"
height="110"
x="312.85715"
y="738.07648"
inkscape:label="#box1" />
<flowRoot
xml:space="preserve"
id="flowRoot3058"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;text-anchor:middle;text-align:center"
transform="translate(0,452.36215)"><flowRegion
id="flowRegion3060"><rect
id="rect3062"
width="365.71429"
height="100"
x="221.42857"
y="145.71428"
style="text-anchor:middle;text-align:center" /></flowRegion><flowPara
id="flowPara3064"
style="font-weight:bold;-inkscape-font-specification:Sans Bold">LCL22 TEST</flowPara></flowRoot> </g>
</svg>
I´ve tried to change the code to version 1.2 by changing the following line, but did not solve the problem...
version="1.2"
I need a easy way to edit and bring custom vector graphics to browser. I thought SVG would be a piece of cake, but I´m running aroud these kind of problems...
Any help appreciated.
Rds

The SVG 1.2 Full specification was never completed (as you can see from the link it's still in draft from 2005) and only Inkscape ever supported flowRoot I think. I don't think it's intended that flowRoot will be part of SVG 2 either as that is likely to implement flowing text with a different and more CSS compatible mechanism so flowRoot is best avoided.
Use the Convert to text" command in the Text menu to convert it to SVG 1.1 compliant text.

As others have said, you can use convert to text or unflow to remove the flowRoot.
Keep in mind however that the text will no longer stay within the boundary you specified.
To avoid flowRoot going forward, just click with the text tool and start typing rather that first dragging to set a bound for it.
To creat text that fits within a bounding box, I'm not sure what the best method is.

Related

Trying to access SVG elements generated with <use> with JavaScript

I'm trying to use JavaScript (velocity.js) to animate an SVG that I've defined using <defs> and then instantiated with <use> and I'm having trouble accessing the DOM element of the SVG component I'm trying to modify. My code works with normal inline SVG just fine, but when I switch to the <defs>/<use> method it breaks.
When I use the inline SVG I can console.log the element in question and it returns information, but trying to access that same element generated with <use> returns an empty object. Is there anything in particular I need to be doing when trying to access the DOM elements of SVG generated with <use>?
The HTML
<div class="screen">
<svg>
<use href="/media/defs.svg#poppyIdle"></use>
</svg>
</div>
and top of defs.svg (generated by inkscape, all I did was add <defs> and <symbol>) (don't want to post the whole thing)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<defs>
<symbol id="poppyIdle" viewBox="0 0 140 250">
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer12"
inkscape:label="eyelids"
style="display:inline"
transform="translate(-6.125676,0.02323548)">
<rect
style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.0694716"
id="rect942-3"
width="28.423023"
height="2.0695279"
x="34.666679"
y="34.632057" />
<rect
style="display:inline;fill:#4d4d4d;fill-opacity:1;stroke-width:0.0694716"
id="rect942-3-6"
width="28.423023"
height="2.0695279"
x="85.931053"
y="34.629658" />
</g>
</symbol>
</defs>
</svg>
SVG use elements are like shadow DOM elements in HTML. Only the attributes of the USE element itself is exposed via the SVG DOM - you cannot alter any properties on a single USE element instance that are being cloned from the original symbol. It's not like a macro.

How to output a svg file from the web page?

<svg class="paint" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect class="svgobject" x="458" y="165.28750610351562" width="142" height="56" fill="black" stroke="black" id="154" transform="translate(0,0)">
</rect>
</svg>
For example, I have a web page, which contains a svg child element like above, then how could I build up a function that could extract the svg part and then save locally as .svg? Any help is appreciated
This seems to do what you're asking for using HTML5 download:
<a href='{svg content}' download='test.svg'><svg>...</svg></a>
http://jsfiddle.net/GdCcA/1043/
Also, might be worth checking out:
https://github.com/eligrey/FileSaver.js/

SVG: Issue with multiple masks in different svg

I came across a strange problem using svg filter and masks.
Let's say I have an svg file containg these filters and masks:
<filter id="om-outline">
<feMorphology result="offset" in="SourceGraphic" operator="dilate" radius="3"/>
<feComposite in="offset" in2="SourceGraphic" operator="out" result="stroke" />
<feFlood flood-color="#79868d" result="COLOR-red-2" />
<feComposite in="COLOR-red-2" in2="stroke" operator="in" result="BEVEL_41" />
</filter>
<mask id="outline-mask">
<rect cx="0" cy="0" width="341" height="375" fill="black"/>
<!-- some more elements here that create the silhouette of my actual svg graphic -->
</mask>
using this filter and mask, creates a nice outline arround my animating svg graphic
everything is working as expected so far now, but when I add another graphic, using the same technic to create an outline, this happens:
somehow the second graphic uses the mask and outline of the first graphic, even though I used different ids for the reference.
This only happens in Firefox and Internet Explorer, Safari and Chrome seem to work as expected.

Changing the SVG attributes with javascript

So trying to get my head around how to change a SVG using javascript (I tried d3js library. And I have some issues because I am not sure wether to use it or not).
I have created a simple icon (a star and a circle, to have something).
As far as I understand, what I need to do is to change the attributes of the <g> tag.
The icon have three id's, start circle(should be the whole picture), star (which is the star) and circle
Here is the SVG image.
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="120"
height="120"
viewBox="0 0 120 120"
id="starcircle"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="starcircle.svg">
<defs
id="defstarcircle-def" />
<sodipodi:namedview
id="starcircle"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.32"
inkscape:cx="53.146552"
inkscape:cy="47.894737"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="1440"
inkscape:window-height="821"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1" />
<metadata
id="metadata5539">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="scLayer"
transform="translate(0,-932.36216)">
<path
sodipodi:type="star"
style="opacity:0.5;fill:#00aeef;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
id="star"
sodipodi:sides="5"
sodipodi:cx="59.05172"
sodipodi:cy="992.44832"
sodipodi:r1="49.260658"
sodipodi:r2="24.630329"
sodipodi:arg1="-0.27469391"
sodipodi:arg2="0.35362463"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 106.46551,979.08623 -24.307496,21.89157 4.253455,32.4346 -28.331542,-16.3529 -29.532743,14.0681 6.79764,-31.99826 -22.505694,-23.74002 32.532715,-3.42306 15.623459,-28.74026 13.308684,29.88267 z"
inkscape:transform-center-x="-0.60060082"
inkscape:transform-center-y="-4.1291064" />
<ellipse
style="opacity:0.5;fill:#0d00ef;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
id="circle"
cx="58.620693"
cy="991.80182"
rx="16.379311"
ry="16.594828" />
</g>
</svg>
So lets say that I want to rotate the star, for now only rotate it 180 degrees.
I would need to get the SVG image, then the shape, then append something like
rotate(180 , 50 , 50)
I tried doing it using d3, because it seemed like you needed a library to do it, but nothing I do seem to change the actual document. So what is the easiest way.
I created a jsfiddle with this example, and my attempt to do the rotate, but so far no luck.
I also hid the circle, mostly just to prove that the code is at least finding the objects, even if the hide function is a css option, and I want to do it using SVG transform
https://jsfiddle.net/qyt5o0s7/
Your javascript code was appending a <g> element to the #star element and then rotating the #star element. Remove the append() function and your code will then rotate the #star element. If you want to rotate the #star element around its center then you will also have add tranlate operation before and after the rotate operation. For example, change...
vard3star = d3.select("#star").append("g")
.attr("transform","rotate("+10 + "," + 15 +","+ 15 +")");
to...
var d3star = d3.select("#star").attr("transform","translate(60,992) rotate(10,15,15) translate(-60,-992)");
Also note that you were missing a space between var and d3star which was resulting in a global variable called vard3star.
Well your approach in the fiddle is wrong, Since you are not sure what the library to use or how to use it I like to give you the steps.
Use d3.js, It's great.
You just have to add a <g>, then create the star inside the <g>.
Give the <g> and id of something like starGroup
<g id="starGroup"></g>
then you can use d3 to translate the group.
d3.select('#starGroup')
.style(...);

Is it possible to dynamically modify an SVG loaded as a resource with Javascript?

I have these icons and I'd like to procedurally add a drop shadow (basically, something, anything) to them on hover so they don't look so hokey.
They are SVG's so in theory I can prepend something like this:
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
and some javascript magic to apply it on mouse over. This could possibly save ages of design work.
Problem is, the svg's are presented as <a style='background-image:url(icon.svg)' />.
Is there a way to get into the SVG element?
No, it's not directly possible. A workaround if you need this would be to use inline svg in html, or reference the svg files with either <object>, <iframe> or <embed>.
An example of using inline svg and a filter effect on hover here. The svg part looks like this essentially:
<svg width="400" height="400" viewBox="-2 -2 36 32">
<defs>
<style>
#stack polygon:hover { filter: url(#glow); }
</style>
<filter id="glow">
<feMorphology radius="0.7"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix"
values="0 0 0 0 0
0 0 0 0.9 0
0 0 0 0.9 0
0 0 0 1 0"/>
</filter>
</defs>
<g id="stack" class="icon" fill="#850508">
<polygon points="0,20 16,24 32,20 32,24 16,28 0,24"/>
<polygon points="0,12 16,16 32,12 32,16 16,20 0,16"/>
<polygon points="0,4 16,0 32,4 32,8 16,12 0,8"/>
</g>
</svg>
If you're using SVG as an image then you can't get to the image's DOM and manipulate it via javascript.
While you could load them using XMLHTTPRequest and then insert them into the main document as inline data using the DOMParser object, this exposes you to the security issues that the browsers are trying to protect you from by locking down image access i.e. the image could change and you may be loading arbitrary javascript into your page.
What would seem simplest and safest to me is if you just alter the image files directly using an editor and add the filter into them then use the modified images.
What if you use jquery addclass and simply link to another svg that has your changes?
You can also create an svg element with html code (right click on file --> view with notepad) and you will have the code there -- there are online converters that can make all neccessary tweaks and then you can enter the svg code with javascript
I don't know how to do it in the way you show... as a background image... but if you can load the svg file inside a div as in this example you can you can use my importer (a modified version of others importers founded on github) that it's here: http://www.dariomac.com/Document/Raphael-Utils. You can also see this storify where I describe all the steps followed by me to import SVG directly from file.

Categories