Wednesday, January 15, 2014

SVGs in browsers (Firefox is the new IE)


SVGs in browsers are fun, and if you say goodbye to IE8 and older, it is almost working cross-browser.

I'm working on a basic editor-like application that involves a lot of SVG hacking, but it's quite fun due to the great Snap.svg lib by Dmitry Baranovskiy (working for Adobe).

My main development browser is Chrome, due to the powerful debugging features, and everything works quite well. I wrote a lot of tests, and I was going to fire them up i Firefox, and expected them to work. 5 out of 43 tests passsed, where 43 of 43 passwed in Chrome, Safari, IE10, IE11 and Opera.

I told myself: keep calm, it's probably nothing.

After digging further into SVG in Firefox, there are some issues specific to Firefox.
  1. Mouse coordinates relative to the SVG
  2. getIntersectionList and getEnclosureList is not implemented
  3. getBoundingClientRect

Mouse coordinates

The usual hack for not having offsetX and offsetY in events in FF is something like this:
offsetXY = function(event) {
  var br;
  var evt = event;
  if (evt.offsetY !== void 0 && evt.offsetX !== void 0) {
    return evt
  } else {
    var br =;
    evt.offsetX = evt.pageX - br.left;
    evt.offsetY = evt.pageY -;
  return evt;

However, when you are using SVG's, getBoundingClientRect does NOT provide the actual box around the SVG DOM element, but instead it gives a "close-bounding-box" around the elements inside the SVG. Basically the usual FF hack to get offsetX/Y does not work.

Create a svg like this:
<svg id="testsvg" style="height: 500px; width: 500px;">
    <rect height="100%" id="mouse_calc" width="100%" x="0" y="0"></rect>

You now have a rectangle where you can find the correct coordinates calling getBoundingClientRect on the rectangle By putting the element in the defs area, it's hidden from view, but not clickable, so you still need to do the click handler on the actual SVG. The new code will look like this:
offsetXYSVG = function(event) {
  var br;
  var evt = event;
  if (evt.offsetY !== void 0 && evt.offsetX !== void 0) {
    return evt
  } else {
    var br = document.getElementByID("mouse_calc").getBoundingClientRect();
    evt.offsetX = evt.pageX - br.left;
    evt.offsetY = evt.pageY -;
  return evt;

Nice one FF, two different hacks to get correct offsets...

Note: layerX and layerY does NOT give you the correct values for the mouse click on SVG, due to getBoundingClientRect working differently than in the rest of the current browsers. 

getIntersectionList and getEnclosureList

These to functions are essential to figure out if any objects are intersecting or if one object is within an enclosure when working with selections of gui elements. getIntersectionList can be implemented using the Separating Axis Theorem and getEnclosureList can be implemented with simple checking of x/y and x+width/y+height is within a given rectangle. However, performance for getIntersectionList in JS compared to Separating Axis Theorem implemented directly in the C++ core of the browser is a performance killer when working with many objects.


As mentioned, this basically fails for SVG elements.
Here is how the bounding rect is calculated for a svg with elements going outside forced 500x500 px svg size: The dotted line shows what FF gives as getBoundingClientRect, and the red line shows the actual SVG. Chrome, Safari, IE 11 and Opera gives the red line for both.

 Same as above, but without the two circles on the outside:
As you can see, the problem for calculating your SVG size and therefore finding mouse coords in FF is currently a bit "hackish".

Even though this might be correct when reading the W3C standard for SVG, I think it is better to do the same as all the other browsers to make it easier to develop SVG based applications for the browser.


For SVG, Firefox is the new IE, and that is not a good thing.

Wednesday, January 8, 2014

iTunes connect screenshot and icon details

Some simple guidelines on the sizes/resolution for screenshots and icons for iTunes connect, when you submit your app.

For all images

  • Minimum 72 DPI
  • RGB color space

Large app icon

  • 1024x1024 (cannot be scaled up, but can be scaled down)
  • File format: jpg tif or png 
  • Keep it "flat" as in the new guidelines. Avoid rounded corners.

3.5" Retina Screenshots

  • Portrait: 960x640 or 960x600
  • Landscape: 640x960 or 640x920
  • File format: jpg or png

4" Retina Sreenshots 

iPhone 5/iPod touch (5th gen)
  • Portrait: 1136x640 or 1136x600
  • Landscape: 640x1136 or 640x1096
  • File format: jpg or png

iPad Screenshots

  • Portrait: 1024x768, 1024x748, 2048x1536 or 2048x1496 
  • Landscape: 768x1024, 768x1004, 1536x2048, or 1536x2008
  • File format: jpg or png
Do the screenshots on a device and you should be all good to go.