2

Let's say I have this svg path (some icon) as a string:

"M16,1.466C7.973,1.466,1.466,7.973,1.466,16c0,8.027,6.507,14.534,14.534,14.534c8.027,0,14.534-6.507,14.534-14.534C30.534,7.973,24.027,1.466,16,1.466zM16,28.792c-1.549,0-2.806-1.256-2.806-2.806s1.256-2.806,2.806-2.806c1.55,0,2.806,1.256,2.806,2.806S17.55,28.792,16,28.792zM16,21.087l-7.858-6.562h3.469V5.747h8.779v8.778h3.468L16,21.087z"

I can scale it up (e.g. using raphael.js) like so:

icon = paper.path("M16,1.466C7.973,...").attr({fill: "#000", stroke: "none"});
icon.transform("s4T50,50");

This last line scale the image x4, and moves the whole thing down and to the right.

So far so good, but I need the resulting path for use in an svg file.

So my question: how can I get the resulting or computed path back after the transformation has been done?

Hoff
  • 38,776
  • 17
  • 74
  • 99
  • 1
    Raphael 1.x used to compute the paths when you transformed them, if you get ahold of this version you will be able to achieve what you want. – methodofaction Jul 17 '12 at 18:10
  • Also see http://stackoverflow.com/questions/8350254/how-to-apply-transform-matrix-to-path-coordinates-in-raphael-js-2 – methodofaction Jul 17 '12 at 18:12
  • thanks Duopixel, I managed to get a hold of raphael 1.5.2 from here: http://code.google.com/p/jsplumb/source/browse/trunk/js/lib/raphael-1.5.2-min.js?r=859 - this seems to work though results are not 100% what I predict. I'll post a complete answer once I have sorted it out. Cheers! – Hoff Jul 17 '12 at 23:19

3 Answers3

2

Please check my answer here and the testbed here.

There is a function flatten_transformations() which can bake (or apply) transforms to paths. It can handle all path segments (also arcs). You can select whether all path segments are converted to M:s and C:s or are they left as they were. H and V are the only ones that cannot remain, they have to be converted to L:s, because transforms can make vertical and horizontal lines to non-vertical and non-horizontal. You can also select whether coordinates are converted to relative or absolute and the precision of conversion.

It would be nice if this like flattening function were part of Raphaël.

Community
  • 1
  • 1
Timo Kähkönen
  • 11,962
  • 9
  • 71
  • 112
1

The path stays exactly the same, so you can't get what you want here.

You are assuming that Raphael cycles through points and scales coordinates up when you transform it. However, it does not do that- instead, it applies a transformation function to the renderer.

For example, after your .transform("s4T50,50"); your resulting path is this in the DOM:

<path 
    style="" 
    fill="#000000" 
    stroke="none" 
    d="M16,1.466...39V14.525H23.858L16,21.087Z" 
    transform="matrix(4,0,0,4,2,2)" 
    stroke-width="0.25"
/>

Now, I shudder to even try to imagine how this works in VML, but, c'est la vie. Anyhow, what you can get is a different bounding box with icon.getBBox() -- that part is true to the screen-pixel coordinate system. Primitive information, but helps:

        before transform       after icon.transform()

height  29.067999999999998     116.27199999999999
width   29.067999999999998     116.27199999999999
x        1.466                   7.864000000000014
x2      30.534                 124.13600000000001
y        1.466                   7.864000000000014
y2      30.534                 124.13600000000001
pp19dd
  • 3,625
  • 2
  • 16
  • 21
1

The function Raphael.transformPath seems to be what you're looking for.

icon = paper.path(Raphael.transformPath("M16,1.466C7.973,...", "s4T50,50")).attr({fill: "#000", stroke: "none"});
Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139