2

There are three basic ways to move a path in Raphael.

If that path has a fill image that has PNG transparency, and you need IE8 (VML), all three are flawed.

JSBin demo


If you use a simple transform...

path1.animate({transform: 't20,100'},1000);

...then in IE8, the png transparency in the fill breaks and translucent pixels turn black. Edges become pixelated and ugly, and depending on the image you might get a scuffy black outline around the translucent edge of the image. Not good, and there doesn't seem to be any reliable way to fix this after the event.

Sometimes, inconsistently, the background image also doesn't stay relative to the element (more on that below).


If you animate the path attribute, for example like this:

path2.animate({path: Raphael.transformPath( path2.attr('path'), 't100,20') },1000);

...IE8 doesn't wreck the image background. However, the fix for making background images relative to the element not the paper does not work with this method (and various ways I've tried to bodge it using improved background image offset with an additional "M-20,-20" element don't seem to work), and I can't find any way to make that work either.

Also, just having lots of transformations on the go can break the delicate IE8 bug the background image fix depends on in VML mode, causing the background to move. This seems to be inconsistent - with the JSBin above, in IE8, sometimes they all move, sometimes only the top one moves.


If you use translate...

path3.translate(42,42);

...the results are the same as transform (presumably both use the same translate functions).


With Raphael image elements, it's possible to fix this broken alpha by applying opacity with the transform in an attr or animate call. This doesn't work with path fills. Also, turning off the fill and resetting it from the original URL string doesn't remove the broken alpha contamination. You can see this in this demo.


So, I'm looking for a way to move a Raphael path that has a background image that has PNG transparency that a) keeps the image relative to the element, consistently and b) doesn't wreck the PNG transparency in IE8 by turning partial transparency into pixelated black.


Similar problems occur with any form of transformation - such as scale, rotate etc.

Community
  • 1
  • 1
user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125

1 Answers1

1

I can't find any good answer to this: the closest I've found is an ugly but functional workaround for IE8 transform (wrapped in if(Raphael.type=='VML')s so you don't spoil things for real browsers):

  • Before doing any transform to anything that has an alpha transparency PNG / pattern fill, remove the pattern fill (path.attr({fill:'none'});), storing the fill setting like path.data('fill',path.attr('fill'));
  • After the transform, asynchronously (e.g. wrapped in setTimeout(function(){ })) re-apply the fill e.g. path.attr({fill: path.data('fill')});

The crucial thing seems to be: the fill must not be applied when the transform occurs, else it'll be ruined forever, even if you remove and re-apply it. Be careful with the timing on this - it mustn't be possible for the fill to re-apply before the transform completes (e.g. watch out for race conditions with animations or other async processes).


If you're animating a transform, your options seem to be to either:

  • Clear the fill before the animation, just accept that there will be no fill while the animation takes place, and re-set in a callback after the animation completes
  • Implement your own animation handler than removes and re-applies the fill before and after every frame (this, of course, risks being a performance nightmare).
user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125