Bake all path transform attributes into path data instead
HTML
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewbox="0 0 100 100"
id="expandSVG"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="shrink.svg">
<metadata
id="metadata15">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs13" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1286"
inkscape:window-height="713"
id="namedview11"
showgrid="false"
inkscape:zoom="2.36"
inkscape:cx="50"
inkscape:cy="50"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="expandSVG" />
<polygon
points="75,0 100,0 100,25 90,15 69,37 64,30 84,10 "
id="polygon3"
transform="matrix(-1,0,0,-1,164,37)"
style="fill:#000000" />
<polygon
points="75,100 100,100 100,75 90,85 69,63 64,70 84,90 "
id="polygon5"
transform="matrix(-1,0,0,-1,164,163)"
style="fill:#000000" />
<polygon
points="25,0 0,0 0,25 10,15 31,37 36,30 16,10 "
id="polygon7"
transform="matrix(-1,0,0,-1,36,37)"
style="fill:#000000" />
<polygon
points="25,100 0,100 0,75 10,85 31,63 36,70 16,90 "
id="polygon9"
transform="matrix(-1,0,0,-1,36,163)"
style="fill:#000000" />
</svg>
JavaScript
// Helper tool to piece together Raphael's paths into strings again
Array.prototype.flatten || (Array.prototype.flatten = function() {
return this.reduce(function(a, b) {
return a.concat('function' === typeof b.flatten ? b.flatten() : b);
}, []);
});
// Bake the transforms into all path nodes and remove the transform attributes
var paths = [].slice.call(document.querySelectorAll('path'), 0);
paths.forEach(function bake(p) {
var before = p.getAttribute('d'), after = applyTransforms(p);
console.log('before/after path #'+arguments[1]+':\n', before, '\n', after);
p.setAttribute('d', after);
});
paths.forEach(function removeTransforms(p) {
do {
p.removeAttribute('transform');
p = p.parentNode;
} while (!/^svg$/i.test(p.nodeName)); // walk to the SVG root, to catch <g>s
});
// done!
// Uses Raphael.path2curve and Raphael.pathToRelative
//
// Calculates a new <path d> attribute relative to a given root (<svg>) element,
// folding in all the transforms into the path data itself so it can move there,
// and get rid of its transform attribute.
function applyTransforms(path, root) {
function point(x, y) { var p = svg.createSVGPoint(); p.x=x; p.y=y; return p; }
// add a copy of the path at the same level of the hierarchy to see transforms
path = path.parentElement.appendChild(path.cloneNode(false));
// turn all arc commands into splines so we can transform them even with skews
path.setAttribute('d', path2curve(path));
var svg = path.ownerSVGElement
, normal = (root||svg).getScreenCTM().inverse() // compensation for root
, matrix = normal.multiply(path.getCTM()) // transform, relative to svg root
, _ = ''
, coords = [_, 1, 2] // main and optional handle 1 and 2 coordinates
, segs = path.pathSegList
, len = segs.numberOfItems
, x = { 0: 0, '': 0, 1: 0, 2: 0 }
, y = { 0: 0, '': 0, 1: 0, 2: 0 }
, i = -1
, seg, cmd
;
// simplify the logic by normalizing to...