SVG, vector-effect="non-scaling-stroke" and IE - svg

As I understand it, the SVG attribute vector-effect="non-scaling-stroke" should prevent strokes from being distorted (made thicker or thinner) if/when the SVG object is scaled or stretched.
For example - in this fiddle (http://jsfiddle.net/1cj0ovae/5/), I have two SVG objects; both are 5x wider than they are tall. Because the view box of both calls for a square, the SVGs are stretched and distorted.
In the upper SVG - the green path is distorted - it's much thicker than it's supposed to be (stroke-width="2").
In the lower SVG, however, the red path is displayed "correctly" - a 2px thick stroke - because it has the vector-effect="non-scaling-stroke" attribute set.
This seems to work in Chrome, Safari, and Firefox, but not in even recent versions of IE (e.g., IE10).
Is this an IE bug? Is there a workaround?

vector-effects is part of SVG 1.2 tiny and the upcoming and as-yet-unfinished SVG 2 specifications.
IE has only targeted SVG 1.1 which does not have vector-effects. Other UAs have cherry picked parts of SVG 1.2 tiny such as vector-effects but no current UA implements it all (Opera 12 did I think).
To work around it figure out how wide the stroke should be using javascript. I.e. work out the difference between the transform that's applied to the shape and apply the inverse of that to the stroke-width. It's not straightforward as I found when I implemented this in Firefox.

Related

Firefox :animate SVG radius only works with percentages

I am trying to animate the SVG2 Geometry Property r, the radius property of a Circle Element.
I read that the property can be used as CSS property in browsers supporting SVG2 (see Resizing SVG Circle Radius Using CSS Animation).
Now I notice that animating r does only seem to work in Firefox if I express values as percentages. If I use absolute values, the circle is not being animated, see minimum reproduction CodeSandbox.
Does Firefox lack SVG2 support here?
As pointed out, stating lengths in pixel does the job.
The spec indeed says that absolute lenths must be given in physical units.
Omiting them will Chrome use px as fallback unit, while Firefox won't.

Stroke-dasharray and stroke-dashoffset behaving weirdly on circle in Safari

I'm using a <circle> element with stroke-dasharray and stroke-dashoffset to draw an indicator for the focused element of a donut chart, and in Safari it is not coming out right.
The outer pies are <path>s which work fine in all browsers, but as I need the indicator to transition between sectors they need to be <circle>s.
I thought it was because Safari was calculating the circle's circumference based on the svg viewbox or something like that but no dice. Any help would be appreciated.
https://codepen.io/pouretrebelle/pen/d56df310e385a0c2fdedb5bbddc2308d
Rendered in Chrome:
Rendered in Safari:

How to adjust the resizing of a SVG?

I need some help to figure out how I can adjust the resizing of an SVG graphic when displayed on my web page.
Here are joined 2 screenshots of the graphics, one shows the graphics on a desktop wide screen, and the other on a smartphone
My problem is the graphics are too small on the smartphone. How can I make it bigger? I didn't anything about the responsiveness of this graphics, just the plain SVG in my web page. So I guess something can be made but I don't know what exactly.
Here is the beginning of the SVG graphics:
<svg viewbox="0 0 1920 632" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
<title>graphics</title>
<g style="isolation:isolate">
<g data-name="before animation starts" id="0482fa28-2c72-43bc-8627-b57f09f318d3">
<path id="main-oval" class="main-oval" d="M1354.63,260.62C1338.38,142.2,1144.68,71,922,101.54c-109.4,15-205.35,51.8-272.82,99.38-69.92,49.26-109.23,110-101,170.29,16.31,118.42,210,189.59,432.62,159.07,110.79-15.17,207.86-52.73,275.44-101.15C1324.59,380.18,1362.8,320.12,1354.63,260.62Z" data-name="oval"></path>...
Thanks
Attribute names in SVG are case-sensitive. So viewbox should be viewBox.
It is possible that there are other things wring, but I can't tell without seeing the complete SVG file.
Because your SVG has a viewBox attribute without a width and height attribute it is by default responsive and will scale to fit it's parent container.
In the case of your mobile view, it is the parent container that is restricting the size rather than anything in your SVG. Try inspecting the width, margin and padding of the parent container to ensure it is 100% wide and your SVG will scale to suit.
If the SVG is still not quite legible after that you will need to modify the graphic using CSS media queries to scale and transform specific elements. That is beyond the scope of the question so I won't go into it here.

IE10 SVG implementation refusing to antialias <rect> elements?

I've been working on a charting library using d3 and SVG to display a series of rectangles. The dataset governs the number of rectangles to be displayed in a given area, and in most cases, the math doesn't work out cleanly, meaning the rectangles don't start and end on whole numbers. Firefox, Chrome and Safari all address this contingency by antialiasing the rectangles. IE seems to just round to the nearest pixel value, and refuses to antialias any rect elements. I've tried changing shape-rendering and the like, to no avail.
Here's a side-by-side comparison of the same data in IE10 and the most recent Chrome release:
IE10:
Chrome:
Is anyone aware of a fix for this that doesn't involve changing the structure of the SVG markup? Setting CSS properties or tag attributes is preferable to changing the elements themselves. Barring that, has anyone seen any Microsoft documentation explaining the rationale for this decision? I haven't been able to turn up any thus far.
IE doesn't seem to care about the shape-rendering property, but I've found that you can force it to anti-alias shapes by specifying a tiny rotate transformation:
svg {
transform: rotate(.00001deg); /* hack to force anti-aliasing in IE */
}
Tested on IE11.

SVG 'maskContentUnits' not rendering properly in mobile safari

I have an SVG I am building with Javascript. I load in a large SVG file, break it apart into pieces all drawn with paths, and place each element in my page. I'm only using these SVGs as masks for other images I am loading. Basically my structure is like the following.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="26.750152587890625 10.117172241210938 197.24969482421875 348.1596221923828" width="197.25" height="348.16015625">
<mask id="designMask" maskContentUnits="objectBoundingBox">
<g id="CutContour1bg">
<path d="[my path coords]" style="fill:#FFFFFF;">
</g>
</mask>
<image href="http://myImage.jpg" style="mask: url(#designMask);" width="800px" height="800px" x="26.75" y="10.1171875">
</svg>
This renders the image being masked by my SVG perfect, in FF, IE9, Chrome, Safari 5.1 (desktop). In mobile safari however, the image does not render properly. I trace out coords of the mask, they are all correct. In FF I can see the SVG load (all black) then disappear as it becomes the mask. (I am waiting until the design is loaded, then wrap my <g> with <mask> since FF has an issue looking for the mask before the content is loaded.
This tells me the mask's position is exactly where it needs to be, but the maskContentUnits are not. They remain in the top left corner instead of the object's bounding box, like I'm telling it. I can barely see part of the image in the mask, so the mask units are correct, but I cannot get the maskContentUnits to work or be read in mobile safari.
Has anyone ever seen this issue, or any idea how to correct it? I hate having this work everywhere except mobile safari, as it is meant to mostly work on mobile... which defeats its not purpose haha.
Thanks!
I haven't found a way to make maskContentUnits work properly in mobile safari yet, I'm pretty sure it's just not recognized yet like other browsers. But I figured out a 'hack' to make the example work.
The issue is, the mask area resides in the top left corner of the browser, rather than of the svg object being used as the mask. So if you have an svg in the middle of your page, the image being masked will not follow the same positioning.
The way I found for it to work, is, I wrapped the svg inside a div with the same width as the svg, and modify the position of the div instead of the svg. This way the mask is technically still in the 'top left' corner, but of the div rather than the offset position of the svg.
If anyone finds a better way, to make maskContentUnits render proper in mobile safari, I'd like to hear it!

Resources