IE10 SVG implementation refusing to antialias <rect> elements? - svg

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.

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.

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

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.

svg elements - scroll to/ centering

I've an svg dynamically created on a page. As things "happen" (user clicks) the svg expands and collapses certain elements. It may fit in the viewport, it may not. In the case that its too big to fit on a page, the user must scroll to where s(he) wants to go/see. Now this is fine, however I have a requirement that the last element "selected" becomes the center of the page/viewport. i.e. If they click on an item, thats what they need to see without scrolling.
Could anybody tell me the best way to attack this. I've googled around but can't find what I'm looking for (though I'm not long at all this so I might have been searching the wrong stuff).
Is there a way to do this purely programmatically with javascript? Or am I obliged to pass by CSS to get the solution I want. Any tips/links/advice much appreciated.
thanks and have a nice day
G
I had a similar thing and I used the viewBox property to handle this. You could also use a wrapping <g> element, which you translate. However, from my point of view the basic approach is the same and you basically need to do two things:
keep track of the x and y offset and the dimensions of the viewport. (Using the viewBox will give you that »for free«)
Compute the center of the Element. Therefore I used the getBoundingClientRect()method which yields the AABB of of the Element in absolute coordinate space, relative to top-left edge of the whole page.
With these things, all that remains is to calculate the vector from the viewport center to the object's center.
Here you can find the reference of the viewBox and here a nice tutorial about it, because it can be a bit confusing at the beginning.
Another pro for the »viewBox« approach is: There is no dependency on special DOM elements, it just works on the root <svg> element. I once implemented both methods, I started out using a wrapping <g> element, what worked fine but gave me some performance issues. So I decided to change and use the viewBox, with the result, that the performance in Firefox grow, but slowed down in Chromium.
Edit
Here you can find a little fiddle, that outlines the approach. But be aware of the following: getBoundingClientRect() yields the position of the Element on the whole Page, so if your <svg> is not positioned at (0,0) (top: 0px; left: 0px), than that will include the offset of the svg itself. The offset of the viewBox must not include this offset, so you need to cancel that out somehow. For sake of simplicity I just used the client Bounding Rect of the SVG, what works because there are no transformations applied.

Transitioning svg text opacity

Has anybody ever had any issues with transitioning the opacity of an SVG text element? I'm using both the fill-opacity style and the stroke-opacity style to fade the text elements into and out of existence. It works fine on most browsers, but doesn't transition at all in Chrome on Mac -- the text just pops in and out all at once.
I tried setting the "opacity" attribute in addition to fill-opacity and stroke-opacity and that does seem to make it work, although now I see a weird flicker effect just before and after the transition runs. It's like it's setting it to opacity=1 for a split second before it sets it to 0 and then transitions to 1.
Another interesting thing is that other shapes (circle, rect) fade in and out just fine with nearly identical code to what I'm using with text.
This does seem to be weirdness with a specific browser, but I'm wondering about other people's experiences with opacity on text elements. Are there tricks to get it to behave consistently?
What version of Chrome are you using? I noticed a bug in Chrome dev some time ago when working on the word cloud but it appears to have been fixed as of 19.0.1077.3 dev. Perhaps the fix hasn't made it into your particular version yet?
In my case, using opacity fixed the problem temporarily. The flicker effect could be due to exponent notation not being parsed for very small numbers; you can try using 1e-6 instead of 0 to get around this.
For an animation I made some months ago I toggled the style and used webkit-transition, in combination with visibility: hidden. This seems to work well. If that doesn't work, you could try transitioning to an opacity near zero.

Why does IE change the color?

I've placed an image on top of a div. I'm trying to blend the image into the div (The div is a solid color). In Google Chrome, it looks great! The colors blend perfectly. In IE 7, however, the colors show a hard line even though they should be the same color! After some examination (a print screen put into paint.net to check the actual RGB values), IE 7 is actually lightning up my image.
The blend has to look seamless. Google Chrome was fine with this thus far. Any ideas why IE 7 wont display the color right?
The two browsers are using different rendering engines. There are minor differences between them in how they render graphics, particularly jpegs.
The differences are minor but unavoidable.
Most of the time it goes unnoticed; it only makes an appearance in cases like yours when you try to position it against an element with a solid background colour that is supposed to be the same.
You may be able to resolve the issue by using a different image format. Try saving the image as a PNG. PNGs tend to be rendered more accurately between the browsers than jpegs, so that might be enough to solve your problem.
If that doesn't solve your problem, you could try using PNGs alpha transparency feature to produce an image with a fade to transparent at the edge, and then overlap the background colour behind it. This will definitely give you a smooth transition, but is a bit more technical, so harder to achieve. It will also give you problems with older versions of IE (IE6 for sure, I think you'll be okay with IE7), as they had some major bugs with PNG transparency. (If this is an issue for you, there are work-arounds for this; google IEPNGFix for more)

Resources