SVG pattern with image not working in IE 10 and Firefox - svg

This html+svg page (no javascript) does not work on IE+Firefox, while it works on all other browsers (Chrome, Safari and Opera).
<svg height="600" version="1.1" width="600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="graphics" style="overflow: hidden; position: relative;">
<defs>
<pattern id="A" patternUnits="objectBoundingBox" width="80" height="27">
<image xlink:href="Data/Dialoghi/tl/PN.3000994/A/1.png" width="80" height="27"></image>
</pattern>
... 7 more patterns
</defs>
<path fill="url(#A)" d="M31.20418,1.17813L39.54938,1.17813L39.54938,81.79142999999999L11.964579999999998,81.79142999999999C13.448279999999999,68.15012999999999,16.862979999999997,54.26062999999999,21.96358,41.51922999999999C26.683880000000002,28.519329999999993,29.80658,14.937729999999995,31.20418,1.178129999999996Z"></path>
... 150 more paths or rects
The page works everywhere only if I keep the number of figures below 30-40; at some point after that, it stops rendering the page at all, showing only white space on IE 10 and crashing Firefox (all other browsers work great).
What do I miss? How do you debug a case like this?
Thank you very much.

You've specified patternUnits="objectBoundingBox" so a value of 1 for width and height is the size of the shape. So you're creating patterns that are 80 or so times the size of the shape that you're drawing the pattern into like creating a pattern the size of Britain in order to draw London.
Either make the pattern width and height sensible (i.e. <= 1) or use userSpaceOnUse units

Related

Width and height have no effect on <use> when referencing inline images

I'm trying to inline some images into an SVG that uses xlink:href references pointed to fully qualified local paths. For reasons why see this GitHub issue. The example python does a reasonable job, but it will inline the same image many times in a single SVG which is not optimal.
So I tried a similar approach that converts something like this:
<svg xmlns="http://www.w3.org/2000/svg">
<image x="0" y="-144" width="101px" height="101px" xlink:href="/path/to/file.png" />
<image x="0" y="-144" width="101px" height="101px" xlink:href="/path/to/file.png" />
</svg>
To this
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<image id="file.png_1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA..." />
</defs>
<use x="0" y="+144" width="101px" height="101px" href="#file.png_1" />
<use x="0" y="-144" width="101px" height="101px" href="#file.png_1" />
</svg>
The problem
The way this renders (Safari and Chrome), it seems that width and height have no effect on the <use>.
I can get the desired result to render identically to the original if I move the width and height onto the <defs><image/></defs>. But doing this makes the assumption that no SVG will EVER use the same image twice with different sizes.
Despite reading the SVG 1.1 Standard, I'm still no further forward on understanding how to size a <use> element without explicitly sizing it on the referenced <image> element.
In a comment the OP is asking for an example:
#enxaneta could you show a very short worked example as an answer.
In the next example I'm putting an image in a symbol. The image has a width and a height. Also the symbol has a viewBox. In this case the viewBox of the symbol has the same size as the image.
I'm using the symbol with use.The use element has a x and y attributes for the upper left corner. Also the use has a width and a height. Please observe that I'm preserving the same aspect ratio as the symbol's viewBox.
<svg viewBox="0 0 65 50">
<symbol id="i" viewBox="0 0 22 9.8">
<image width="22" height="9.8" href="https://assets.codepen.io/222579/bone300.svg"/>
</symbol>
<use href="#i" x="10" y="7" width="44" height="19.6" />
</svg>
According to the SVG specification width and height are ignored on a use element unless that use element points to a symbol or an svg element.
The width and height properties on the ‘use’ element override the values for the corresponding properties on a referenced ‘svg’ or ‘symbol’ element when determining the used value for that property on the instance root element.
So wrapping the image in a symbol element and then pointing the use to the symbol should work.

How to set SVG fill using pattern in a different SVG file [duplicate]

The following attempt to make a rectangle with a pattern fill doesn't seem to work in Safari 6.1, Firefox 30, or Chrome 36, even though the W3 spec seems to say that a I can use a non-local IRI reference, including a relative one, like fill="url(localURL.svg#MyId)".
test.html
<html>
<head>
<style>
.patterned { fill: url("patterns.svg#polkadot");
stroke: lime; stroke-width: 5px}
</style>
</head>
<body>
<svg width="500" height="500">
<rect class="patterned" height="27" width="58">
</svg>
</body>
</html>
patterns.svg
<svg xml:space="preserve" width="225" height="110" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="polkadot" patternunits="userSpaceOnUse" x="0" y="0" width="20" height="20">
<circle r="10" cx=12 cy=10 fill="purple">
</pattern>
</defs>
</svg>
Safari and Chrome show a black-filled green-outlined rectangle. Firefox shows an empty or white-filled green-outlined rectangle. None of them show the pattern of purple circles.
I'm trying this approach because I couldn't get an SVG fill pattern to work on Safari in the Backbone+JQuery+D3 project I'm working on using the most common method, an inline defs with fill="url(#MyId)". I couldn't get that approach to fail as a simple test case -- I thought I had, but that turned out to be a different Safari bug with an obvious workaround. At least that approach worked in some browsers.
You've a load of syntax errors in your patterns.svg file. Missing " characters round attribute values, an unclosed circle element, patternunits instead of patternUnits.
SVG standalone must be valid XML, it's not as forgiving as html and it's case sensitive on attribute names too. If you loaded the patterns.svg file directly, browsers would tell you all these things.
With all this fixed (as below) this works in Firefox. I'm not sure Chrome/Webkit have implemented this yet.
<svg xml:space="preserve" width="225" height="110" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="polkadot" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20">
<circle r="10" cx="12" cy="10" fill="purple"/>
</pattern>
</defs>
</svg>

How does sizing work for nested SVGs?

I'm trying to set up some nested SVGs in d3 so that I can encapsulate some small graphs in a larger canvas.
My problem is that I can't seem to get the inner SVGs to correctly size with regards to width and height. I tried something like this:
<svg width='500' height='500'>
<svg width='200' height='200' x='10' y='10'>
<rect x='10' y='10' height='20' width='20'></rect>
</svg>
</svg>
The outer SVG sizes itself correctly, but the inner SVG is given a height and width of 10 each. (i.e. it is sizing around the rectangle.) I'd like to set it to a height and width of 200 each.
How do I accomplish this, either in HTML or else with javascript?
Fiddle is here.
The SVG is the correct size. You can see that if you put a 100% by 100% rectangle in the background.
<svg width='500' height='500'>
<svg width='200' height='200' x='10' y='10'>
<rect height='100%' width='100%' fill="orange"></rect>
<rect x='10' y='10' height='20' width='20'></rect>
</svg>
</svg>
Demo here
I don't know why you are saying it is only 10x10. What makes you think that?

SVG image generated in browser different in Illustrator

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.

Using a svg with width=100 and height=100 I got extra space in safari e chrome

testing a simple page with some text and a svg with percent value in height and weight, I got an extra space before and after the svg. There is not extra space in Firefox, but You can found it in Safari and Chrome You can see this here:
http://www.venerandi.com/svg_space.xhtml
This is the svg code:
<svg id="uno" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 500 250"
width="100%"
height="100%"
preserveAspectRatio="xMidYMid meet">
<polygon points="1, 20 500, 1 220, 250"
style="fill:#FFFFFF;
stroke:#000000;stroke-width:5"/>
<text x="47" y="42" font-size="24" fill="red" font-weight="bold">Colombini Locusta</text>
<text x="45" y="44" font-size="24" color="black" font-weight="bold">Colombini Locusta</text>
<rect x="200" y="100" width="70" height="70" style="fill:red"/>
</svg>
Some suggestion to understand why the extra space is created?
Thank you.
This is a common question. Unfortunately you've struck a bug in Webkit-based browsers. It is supposed to be calculating an appropriate height based on the width and the viewBox aspect ratio. Unfortunately it isn't. It is treating the height of "100%" to mean "the height of the page". There is not much you can do about it.
You either have to use Javascript to calculate and set the size of the SVG explicitly yourself, or set it to a fixed size and live with it.

Resources