SVG image generated in browser different in Illustrator - svg

I'm writing a web application which generates SVG images in the browser.
The SVG's I'm generating work fine in ever browser. However, when I download one of the SVG's and try to open it in Adobe Illsutrator, all the transformations are all over the place.
They are in fact so different that you have to zoom right out to see where the shapes are positioned.
This is the contents of the SVG, you can see it's pretty simple. Just a couple of nested SVG's and a few basic shapes:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="592" height="592" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg style="overflow:visible;" x="88.80000305175781" y="88.80000305175781" fill="#777777">
<svg style="overflow:visible;" height="100px" width="100px">
<rect width="100" height="100" style="stroke:#006600;" transform="scale(4.144 4.144)"></rect>
</svg>
</svg>
<svg style="overflow:visible;" width="592" height="592" x="176.60000000000016" y="177.60000000000014" fill="#000000">
<rect width="592" height="592" fill="rgba(0,0,0,0)" stroke="#bbbbbb" transform="scale(0.4 0.4)"></rect>
<svg style="overflow:visible;" x="-0.0000015258789005656581" y="-0.0000015258789005656581">
<svg style="overflow:visible;" height="48px" width="48px">
<ellipse id="SvgjsEllipse1010" rx="24" ry="24" cx="24" cy="24" style="stroke:#006600;fill:#00cc00;" transform="scale(4.933333333333334 4.933333333333334)"></ellipse>
</svg>
</svg>
</svg>
</svg>
I don't know the SVG spec inside out, but I'm doing anything particularly complex, so it all seems good to me. I can't see a reason why Illustrator would render it so differently to browsers.
Does anyone know why this is happening?
Edit
This is what it looks like in Illsutrator, as you can see the scaling and positioning is all off, the small square in the center is the 592 x 592 canvas area, so you can see who far I am zoomed out.

I suspect AI doesn't like/handle/expect nested <svg> elements. Try replacing them with groups. Those with x and y attributes may need to have a transform added to get it to look the same. Also if the overflow is important, you may need to tweak things further as that property is not valid for group elements.

Related

Display of SVG on Leaflet map

I have a moderately large SVG to be displayed as an overlay on a Leaflet map - it's basically a selection of roads from a road network. The leaflet map is instantiated with:
testMap = L.map('mapdiv', { renderer: L.svg({ padding: 100 }) })
.setView([33.085, -96.815], 11);
and the SVG layer is created with:
var imgUrl = url, imgBnds;
L.imageOverlay(imgUrl, imgBnds, {opacity:0.3}).addTo(testMap);
This all displays nicely when zoomed out, but when zooming in, the SVG gets tiled, and only the top-left tile is displayed even though this is not the area being shown in the map.
The SVG has the following:
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" xml:space="preserve"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" x="0" y="0" width="1920" height="767"
clip-path="url(#MapClipRectangle)" style="overflow:hidden;text-rendering:optimizeLegibility" xmlns="http://www.w3.org/2000/svg">
</desc>
<defs>
<clipPath clipPathUnits="userSpaceOnUse" id="MapClipRectangle">
<rect x="0" y="0" width="1920" height="767" />
</clipPath>
<symbol id="1" style="fill:none">
<path d="M985.96 476.76 l-0.26 0.06" />
<!-- ... Many Symbols and Paths, plus some Polygons, Text, Line_artwork, Map_decoration and a Map_frame... -->
And it ends up looking like this (example actually shows the top-left tile, but if I zoom in to the right, you don't actually see anything from the overlay SVG):
How do you stop/control this behaviour?
Sample SVG for which this behaviour occurs
I have not investigated this question in any depth, but in the interest of having some answer at all that might help:
It seems unusual to me that you want to use an svg for geospatial data like a road network.
If someone runs into a similar problem in the future, I would recommend, rather than trying to fix the svg rendering, convert the data to geojson which is more of a standard option for this sort of data display need and then style as needed using the options in leaflet.
To OP, did you ever find a solution?
As a note, it is not clear to me which part of the images posted are svg's vs which parts are basemap or other layers.

svg image element not shown on mobile

I have been trying to get the cross browser compatability working of my svg project. I had a friend test my link on a mobile, but he sais the image doesn't load and he gets a black screen (I assume the black he refers too, is the rect in the background). Does anyone have any idea what is wrong with my code or why the image doesn't display properly on mobile?
svg
<svg viewbox="0 0 3000 2500">
<g transform="translate(225,50)">
<rect width="2550" height="1925" id="background-rect"></rect>
<image href="http://lorempixel.com/output/animals-q-c-640-480-3.jpg" width="2550" height="1925"></image>
</g>
</svg>
Example: https://codepen.io/RobMo/pen/aVvKEP
PS: Just an idea: It might have to do with me not declaring a namespace. I can't test it right now, but that might be what is causing this. Or maybe help people provide inspiration for an answer :).
PPS: To use the <img> tag you need to use xlink:href instead of just href. I should've decared the namespace in the svg tag as well.
What happens when you add a namespace?
<svg viewbox="0 0 3000 2500" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(225,50)">
<rect width="2550" height="1925" id="background-rect"></rect>
<image href="http://lorempixel.com/output/animals-q-c-640-480-3.jpg" width="2550" height="1925"></image>
</g>
</svg>
REF - https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image

SVG symbol with stroke has wrong size in Illustrator

I'm generating an SVG file on a website and it's supposed to be imported in Ilustrator. I use <symbol /> element to store a shape definition and I reference it with the <use /> element on the "sheet". Users are able to set size of the shape and it's really crucial that it's exactly the same size when imported to Adobe Illustrator. It works unless I add a stroke.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg id="SvgjsSvg1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="210mm" height="297mm" viewBox="0 0 210 297" viewbox="0 0 210 297">
<defs id="SvgjsDefs1001">
<symbol id="shape_id70" preserveAspectRatio="xMinYMin meet" viewBox="0 0 27.841039657592773 12.2083101272583">
<path id="SvgjsPath1030" d="M26.4405 13.067C25.685728 11.72066 22.49458 8.90142 20.73442 7.678030000000001C22.99088 7.6388854 23.85819 7.6146637 28.738950000000003 7.456081C26.298620000000003 6.628644 23.737080000000002 5.904501 21.418080000000003 4.973881C23.937200000000004 4.5081560000000005 26.519460000000002 4.085806000000001 28.376120000000004 3.7947010000000008C28.376120000000004 3.7946453179000006 19.370760000000004 2.7013810000000005 8.358420000000002 4.414499000000001L9.412540000000002 1.364679000000001L6.497860000000001 3.520859000000001L4.442800000000001 0.858699000000001L4.324531000000001 4.464059000000001L0.897911000000001 5.542179000000001L4.249861000000001 6.913239000000001L4.236664300000001 10.198599000000002L6.192894300000001 7.622079000000001L9.099554300000001 8.802649L8.143547300000002 6.432539C12.463087300000002 6.813516 22.5756473 8.818239 26.440547300000002 13.067009Z" fill="none"></path>
</symbol>
</defs>
<use id="SvgjsUse1034" xlink:href="#shape_id70" x="0" y="0" width="50"></use>
</svg>
This is fine in both browser and Illustrator. But when I add attributes stroke-width="0.1" stroke="#000". In Illustrator, the size of the shape changesto 48.951. It's still 50 in browser though. I tried to add these attributes to the <symbol />, <path /> and <use /> elements with the same result.
I know that the SVG standard doesn't have any attribute that would control how to render the stroke. I know there is a discussion about the stroke-alignment attribute for future versions of SVG. But browsers don't support that yet, and neither Adobe Illustrator.
So my question is: Is there any way how to adjust the SVG so that Illustrator would render the shape with the size that is set by the width attribute in the <use /> element regardless of the stroke settings
The width value on your <use> should be having no effect on your <symbol> because your symbol has no viewBox attribute. Without a viewBox, only the x and y attributes of the <use> will be doing anything.
Also, be aware that we've seen a few questions on S.O. in the past, complaining about bugs in Illustrator's SVG import filter. If <symbol> is working, then that's great. However, in general, you may find that keeping your SVG structure simple, and avoiding the more advanced SVG features, might be a good idea.

Clip path not displaying properly in SVG sprite when using "use"

I'm trying to hack together a sprite sheet from a set of icons. I know almost nothing about SVG. I can get the simple icons to work, but an icon with a clip path isn't displaying properly. From what I can tell it seems like it's not using the clip path.
The sprite works in jsfilddle and it works if I just load the svg on it's own and include a < use > statement in the SVG. But if I have a separate < use > it doesn't work.
All my testing has been done in Chrome (50.0.2661.94)
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<clipPath id="folder-clip-0">
<path d="..." />
</clipPath>
<symbol id="folder" viewBox="0 0 32 32">
<g class="container" data-width="32" data-height="27" transform="translate(0 2)">
<path d="..." class="..." />
<path class="..." d="..." />
<path clip-path="url(#folder-clip-0)" d="..." class="..." />
</g>
</symbol>
</defs>
</svg>
I'm using it like so:
<svg>
<use
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="/img/path/sprite.svg#folder">
</use>
</svg>
When I use the separate statement it looks like this:
But it should look like this:
The color difference is not relevant, it's just the background when the image was taken.
Edit:
I just discovered that if I dump the whole sprite sheet into the page HTML and reference it locally instead of an external file it works. So I don't know what's wrong with my external reference.
e.g.
<svg>
<use xlinkHref={"/img/path/not/work/sprite.svg#folder"}></use>
</svg>
vs.
<svg>
<symbol id="folder"></symbol>
</svg>
<svg>
<use xlinkHref={"#folder"}></use>
</svg>
This works for me as a fallback, but I'd rather have an external SVG file instead of embedding it in my HTML.
Edit 2:
If the SVG sprite sheet is embeded in the HTML directly using the external link shows the icon correctly.
This seems to be a browser support issue. Using the external reference works as expected in Firefox. Chrome doesn't handle clip paths and some other functions in external references. There's an outstanding bug report filed. Safari also doesn't support it.
Related StackOverflow ticket: Why can't I reference an SVG linear gradient defined in an external file (paint server)?
Open bugs:
https://code.google.com/p/chromium/issues/detail?id=109212
https://bugs.webkit.org/show_bug.cgi?id=105904

SVG Rotation in 3D

I need to rotate the paths in my SVG document around an arbitrary point in 3D. It appears that there are multiple ways to do this by either using a 4x4 transformation matrix or the rotateX or rotateY transforms. I've tried both of these methods, and neither seem to work. Are these supported anywhere?
For my application, a bitmap is going to be the final output, so I'm not worried about browser support. I am open to any tool--I can run a specific browser through selenium, or use a standalone SVG rasterizer.
This is what I've tried so far (using Google Chrome 31):
I would expect this to be a black rectangle, rotated about the X axis, and appearing like a trapezoid.
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="640px" height="480px">
<rect x="100" y="100" width="440" height="280" fill="#000000"
transform="rotateX(30 580 100)"></rect>
</svg>
(omitting cy and cz from rotateX gives the same result).
I've also tried with a 4x4 matrix. I don't see any difference from above. I also doubt my math is correct in finding the right matrix elements.
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="640px" height="480px">
<rect x="100" y="100" width="440" height="280" fill="#000000"
transform="matrix(102400 0 0 0 0 88681.00134752653 -159.99999999999997 1387899.8652473476 0 159.99999999999997 88681.00134752653 -15986.602540378442)"></rect>
</svg>
I found that there really isn't a way in SVG to do a 3D rotation that is supported in any modern browser (to the best of my knowledge). However, CSS3 does have a similar "transform" property.
The following works for me:
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="640px" height="480px">
<rect x="100" y="100" width="440" height="280" fill="#000000" style="-webkit-transform: rotateX(30); -webkit-transform-origin-y: 580px; -webkit-transform-origin-z: 100"></rect>
</svg>
This, obviously, isn't a good cross-browser solution (as it uses prefixed properties), but that isn't something I need in my application.
3d rotations are tricky and i've only just started using them. transform: rotateX() and rotateY() will apply the transformations for you, but to get that perspective of a trapezoid, you'll need to use perspective in the css of the parent element.
Here's a codepen.
The relevant bits are
#parent {
perspective: 4rem;
}
#child {
transform: rotateX(45deg);
}
Think of perspective as the distance the object is from the back of your screen. The lower the value, the more intense the distortion of the perspective will be.
See https://www.w3schools.com/css/css3_3dtransforms.asp :
indeed the CSS code { transform: rotateX(##deg) } and similar for -Y and -Z should work now without prefix in most browsers. But it appears these cannot be combined. So you may want to use the more general method: { transform: rotate3d(x,y,z,angle) } , where you can give an arbitrary rotation axis.
Hope that helps...

Resources