Share Posted April 27, 2017 Hey fellow GreenSockers. I was going to post this in the SVG Gotchas thread, but this question is asked a lot around here so I thought maybe a new topic would be the way to go. SVG circles start at 3 o’clock and most people want to animate the stroke from the 12 o’clock position. Conventional wisdom would tell you to simply rotate the circle by -90 degrees and you’re all set, but there are some problems with this approach. Using GSAP to rotate the circle -90 degrees will work perfectly fine in Chrome and FF, but Safari will ignore that set() for some reason. (IE and Edge honor the rotation, but they have another problem.) You can simply add a transform attribute directly to the circle like <circle cx="500" cy="75" r="60" transform="rotate(-90 500 75)"/> This will work correctly in Chrome, FF and Safari, but not completely in IE and Edge. If you're animating the stroke with DrawSVG, IE and Edge need the stroke-dasharray set to 0 in the attributes or they will cause problems. If you don’t add that attribute, a regular circle will start at 9 o’clock and the circle that you’ve rotated -90 degrees with GSAP or a transform attribute will start at 6 o’clock. Strangely, if you resize the browser window to the point of the SVG changing size, IE and Edge will correct themselves. The only bulletproof way I see to draw a circle stroke from the 12 o’clock position with DrawSVG in all browsers is transforming the circle -90 degrees and adding the extra attributes to keep IE and Edge happy. <circle cx="500" cy="225" r="60" stroke-dashoffset="0" stroke-dasharray="0" transform="rotate(-90 500 225)"/> It appears that only adding the stroke-dasharray attribute fixes the IE/Edge issues, but I also add a stroke-dashoffset="0" attribute also just to be safe. Check out the demo in all your browsers. Hopefully this helps somebody with this type of animation. Happy tweening. See the Pen VbPPwY by PointC (@PointC) on CodePen 2 1 Link to comment Share on other sites More sharing options...
Share Posted April 27, 2017 Nice work Craig! The reason that adding the stroke-dasharray attribute fixes the IE/Edge issues. Is due to IE/Edge being really strict and needs the attributes to exist on the element. I have even seen IE/Edge fail to animate with CSS transitions/animations for not even having the stroke attribute present on the element. But that is expected with IE/Edge since they are big poopy pants. 1 Link to comment Share on other sites More sharing options...
Author Share Posted April 27, 2017 Thanks for the extra info Jonathan. I figured this was IE/Edge being the usual pain in the rear that they always seem to be, but I thought I had tested a circle drawing animation a while back and it worked without that attribute in Edge. Maybe I'm just crazy. This one reminded me of the other issue I discovered with DrawSVG and linecaps in IE/Edge, but Jack fixed that one in the plugin. I'm not sure if this one can be fixed or not? Hopefully this info helps others avoid some problems. Link to comment Share on other sites More sharing options...
Author Share Posted April 27, 2017 Just an additional follow-up and clarification. Safari ignores the rotation if you do it like this: <circle id="circ1" stroke="navy" cx="100" cy="75" r="60" /> TweenMax.set("#circ1", {rotation:-90, transformOrigin:"center center"}); It will work if you use the attribute plugin like this: <circle id="circ2" stroke="green" cx="300" cy="75" r="60" /> TweenMax.set("#circ2", {attr: {transform: "rotate(-90 300 75)"}}); I guess that's probably to be expected since it is an attribute, but the unwelcome surprise will come when you expect a regular rotation to work like it does in the other browsers. Happy tweening. Link to comment Share on other sites More sharing options...
Share Posted April 28, 2017 Great write-up, Craig. Interestingly... Safari doesn't like rotation:-90, but it's fine with rotation:-90.01 so that might be easier. Clearly it's a browser rendering bug that's unrelated to GSAP. So weird. Also, the simplest fix of all is probably just making the <circle> a <path> instead which can be done using MorphSVGPlugin.convertToPath(). If you really don't want to join the club, you could still do that on Codepen (see http://codepen.io/GreenSock/full/OPqpRJ/), have it do the conversion, and copy the path data yourself. Should be pretty quick. 1 Link to comment Share on other sites More sharing options...
Author Share Posted April 28, 2017 I think you're absolutely right Jack - making it a path is the easiest thing to do. Figuring out a solid go-to answer on this was one of the reasons I wrote this post. This question seems to pop up frequently and I want to give the best advice when it does. Converting to a path seems to be the best, but we have a fallback with the extra attributes in IE and Edge and -90.01 rotation for Safari. Regarding the convert to path, I'm seeing some strange behavior in Edge and wondering if you or anyone else can confirm it? I've made a new little demo that converts a circle to path rotates it -90 degrees, then draws the stroke. It works perfectly in all browsers except Edge. I'm seeing a solid circle with no stroke or animation. Looking at the inspector I see the values animating, but nothing is rendering. It looks like the attribute names for stroke, fill, and stroke-width have been changed to uppercase. I'm not sure if that's what's causing it not to render properly, but it looked odd. I'm not even sure if attribute names are case-sensitive? Anyway, here it is: See the Pen BRWNxN by PointC (@PointC) on CodePen This works fine in IE11 for me. I'm only seeing this in Edge. Link to comment Share on other sites More sharing options...
Share Posted April 28, 2017 Curious, I wanted to see if the same types of issues showed in up canvas. I didn't get a chance to check to Safari yet, but all the other browsers seem to start at 3 o'clock. The orange circle is rotated -90 degrees. See the Pen 2e1d596a62e9b6f8d7caf3dc8dfed45b?editors=0010 by osublake (@osublake) on CodePen Link to comment Share on other sites More sharing options...
Author Share Posted April 28, 2017 Hey Blake. I'm seeing your orange circle start at 3 o'clock in Safari. All other browsers have it starting at 12 o'clock. Link to comment Share on other sites More sharing options...
Share Posted April 29, 2017 Good catch, Craig - Edge is acting super weird but I think I got a workaround in place now... It had to do with the MorphSVGPlugin.convertToPath() and the attributes that were copied from the <circle> to the <path> being uppercase. Apparently if you loop through the attributes and set them exactly as the browser provides them in the list (using the nodeName), Edge reports those in uppercase but chokes when set that way. Go figure! What's even more strange is that if I force them to lowercase when setting, it displays correctly (visually) but if you inspect the DOM you'll see that Edge still shows them as uppercase! Doesn't get much stranger than that. I patched MorphSVGPlugin to work around the Edge bug. Seems to be working well now. The codepen-specific file is updated as well as the club member downloads. 1 Link to comment Share on other sites More sharing options...
Share Posted April 29, 2017 Hey Guys.. is this the MS Edge SVG uppercase bug your referencing: Some SVG attributes won't get recognized if not set in uppercase, causing blank rendering: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10820546/ 1 Link to comment Share on other sites More sharing options...
Share Posted April 29, 2017 Interesting. But in my testing, it was the opposite - setting the attributes with uppercase names resulted in the problem but that bug report seems to indicate that it's broken if lowercase is used. We're getting completely contradictory results. Thanks Microsoft! Link to comment Share on other sites More sharing options...
Share Posted April 29, 2017 Crazy Microsoft indeed Here was another one: Edge's DOMParser.parseFromString converts known SVG attributes to all upper-case https://connect.microsoft.com/IE/feedback/details/2057021/edges-domparser-parsefromstring-converts-known-svg-attributes-to-all-upper-case The DOMParser parses valid svg documents into a DOM that has attributes that are all upper-case for the known SVG attributes. However creating elements like this (e.g. through recursive DOM copying) the attributes aren't recognized anymore and rendering fails Gotta love or actually hate Microsoft 2 Link to comment Share on other sites More sharing options...
Author Share Posted April 29, 2017 Thanks Jack. That seems to all be working correctly in Edge now. Since I'm in Seattle, I suppose I could drive over to the Microsoft campus and start protesting or something. 1 Link to comment Share on other sites More sharing options...
Share Posted April 30, 2017 I'm kind of surprised nobody has run into this issue before. This bug has been in Edge for as long as I have been using it, so for at least a couple of years. And there are several things you should know about the bug. First, it only affects presentation attributes, which are attributes that can be used as CSS properties. The attribute name does not start out in uppercase. It will only get converted to uppercase if the first time the attribute is accessed is by using an index, i.e. looping through the attributes nodes or viewing the element in the dev tools. Look at the following demo. The first time Rect 1 is accessed is through the getAttributeNode method, so its name will not be converted to uppercase. However, the first time Rect 2 is accessed is through an index value, so its name will be converted to uppercase. var rects = document.querySelectorAll("rect"); // RECT 1 rects[0].getAttributeNode("fill").name; // => fill rects[0].attributes[0].name; // => fill // RECT 2 rects[1].attributes[0].name; // => FILL rects[1].getAttributeNode("fill").name; // => FILL See the Pen 73cda5416b011dd2963bceb74da2bd13?editors=1010 by osublake (@osublake) on CodePen Another important thing to note is that even if an attribute name gets converted to uppercase, the mapping with the original lowercase name does not change, so you would still use the lowercase name to get and set the attribute. You can enter this into the console to see how it plays out. And notice the how the outerHTML value does not show the attribute in uppercase. So the big thing to take away from all this is that it only affects presentation attributes, but does not change their usage. The uppercase name only causes problems when you need the correct casing, as is the case with the MorphSVGPlugin when it needs to copy attributes between different elements. I noticed that the current fix seems to set all the attribute names to lowercase, which will work fine presentation attributes as they are all lowercase. However, this will break camel cased attribute names, and SVG has a lot of camel cased attribute names. It will also break any uppercase names that aren't presentation attributes. There's no telling what attributes the user may have put on the element. Custom attributes are used extensively in frameworks like Angular, Vue, and React, and are rarely prefixed with "data-". So it might be better to just limit the check to Edge. And instead of looping through every possible presentation attribute, you might be able to just grab all the attributes from the outerHTML value. The uppercase names do not seem show up on it. . 1 Link to comment Share on other sites More sharing options...
Share Posted May 2, 2017 Hey Blake. I'm seeing your orange circle start at 3 o'clock in Safari. All other browsers have it starting at 12 o'clock. I see. I've never looked into this whole 3 o'clock issue before, but that is quite telling. The same thing used to happen in Firefox. Now take a look at this demo in all the different browsers.... See the Pen ed2f14b6fe1cc612e18b67aea9c68281?editors=0010 by osublake (@osublake) on CodePen Can you tell what's going on? The strokes glitching in the middle have nothing to do SVG. It's a canvas issue. What do I mean? There is no SVG renderer. The way SVGs are implemented in the browser is based on canvas, so that's the source of most rendering issues. However, the actual rendering isn't done on the HTML canvas. That's done on the browser's canvas, like everything else. I don't know what Edge and Safari use, but Chrome and Firefox both use Skia. It's just a more advanced canvas, but the api is very similar. . 1 Link to comment Share on other sites More sharing options...
Share Posted May 2, 2017 Back to the original topic, drawing circles from 12 o'clock. Using the MorphSVGPlugin to convert the circle to a path works, but that requires setting a transform, and doesn't work well with an ellipse. A better approach would be to have the path start where you want it. Here's a function to do that calculation for you. For a circle, just pass in the same radius for the rx and ry parameters. function getArcPath(cx, cy, rx, ry, startAngle) { var theta = startAngle * Math.PI / 180; var dx = rx * Math.cos(theta); var dy = ry * Math.sin(theta); return [ "M", cx + dx, cy + dy, "a", rx, ry, "0 1 1", 2 * -dx, 2 * -dy, "a", rx, ry, "0 1 1", 2 * dx, 2 * dy, "z" ].join(" "); } Here's a demo of its usage. Pretty easy to make an ellipse start at some arbitrary angle. See the Pen VbWKMj by osublake (@osublake) on CodePen That function could be expanded to do other stuff, like making a pie chart. Here's a demo showing how that could be done. See the Pen OmgMNm by osublake (@osublake) on CodePen . 3 Link to comment Share on other sites More sharing options...
Author Share Posted May 2, 2017 Excellent information Blake. Yeah - I've experienced that weird rendering glitch in the middle a few times. In fact, I've made a couple of pie charts into doughnut charts just so I wouldn't have to deal with it. I was never sure why, but Chrome doesn't display that problem while all the other browsers do. Your demos will be quite helpful in future projects. Thank you. I started this topic because I've seen several people try to draw a circle starting at 12 o'clock, but we've found new browser bugs, updated the MorphSVG plugin, got new demos from Blake and learned more about canvas. You just never know where a topic may lead around here. I do love the GreenSock neighborhood. Link to comment Share on other sites More sharing options...
Share Posted May 30, 2017 @OSUblake I was exploring a workaround that takes into consideration the potential problems you noticed with the lowercase attribute names, but it seems like even if I get the "outerHTML" of an element that contains camelCased attributes, they're always converted to be lowercase by the browser. Are you seeing the same thing? I'm wondering if the current solution is actually much more durable than anticipated. Do you still think we need to accommodate various cases? Link to comment Share on other sites More sharing options...
Share Posted May 31, 2017 Hmmm... maybe. I'm seeing other browsers convert camel case names to lowercase too. I'm having a hard time finding a valid, camel cased attribute to test out to see if it would actually affect it. List of list of attributes on MDN. https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute If we can't manually break it, then that's probably a good sign about its effectiveness. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now