7

I am looking for a possibly fast way to apply all transform matrices of a given svg-graphic. In other words: the algorithm should remove all "transform" attributes and transform all coordinates of the graphic to absolute coordinates.

Is their any library that can do this, or is their any SVGDomInterface method that coulld do that?

EDIT::

If I call the consolidate method like this:

$.each( svg.find( 'path' ), function( i ){
        this.transform.baseVal.consolidate();
});

nothing happens, if i call it like this:

$.each( svg.find( 'path' ), function( i ){
        this.transform.animVal.consolidate();
});

i get this error:

error

So, how should i use the "consolidate" method, on which elements shall I call it?

Greetings philipp

philipp
  • 15,947
  • 15
  • 61
  • 106
  • What is the purpose of removing the coordinates? if you are doing it "in browser", I assume that you are trying to move the viewBox of an SVG container, or otherwise discover the relative positions / sizes of two parts of the SVG – Jay Day Zee May 07 '16 at 08:02

5 Answers5

8

Here's a jsFiddle with some javascript library code (based in part on Raphael.js) to bake the transforms into all paths' data:

http://jsfiddle.net/ecmanaut/2Wez8/

(Not sure what's up with Opera here, though; it's usually best in class on SVG. I may be stumbling in some way the other browsers are more forgiving about.)

ecmanaut
  • 5,030
  • 2
  • 44
  • 66
  • Looks good, but not working -> Uncaught TypeError: Cannot read property 'numberOfItems' of undefined at applyTransforms ((index):76) at bake ((index):44) at Array.forEach () at window.onload ((index):43) – ejectamenta May 07 '19 at 13:10
7

The consolidate method only reduces the list of matrices to a single matrix. And the error you get on the animVal example is because you are not allowed to modify the animated values (consolidate destructively modifies the transform list).

To answer your question, no there's no existing method in SVG DOM that applies the transforms by modifying the values of paths etc. There are options in Inkscape (and Illustrator too IIRC) for applying transforms like that.

If you're looking for a library or utility that does this you can try SVG Cleaner.

Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
6

SVG Cleaner didn't seem to apply all transforms for me, but Inkscape does. Here's the command line I use when I need to apply one:

inkscape copy-of-file.svg --select=id-of-node \
         --verb=EditCut --verb=EditPaste \
         --verb=FileSave --verb=FileClose

Assuming you have "Transforms -> Store transformation" set to "Optimized" in inkscape's prefs (I believe it is on by default), this will apply it and produce the wanted result. Be sure you operate on a copy of your input file, as the operation replaces your original file!

If you are running this on a mac, you may want to first do this in your shell:

alias inkscape=/Applications/Inkscape.app/Contents/Resources/bin/inkscape
ecmanaut
  • 5,030
  • 2
  • 44
  • 66
0

Better use EditPasteInPlace instead of EditPaste. EditPaste pastes at the mouse location, which is not the location of the node.

madibb
  • 1
0

In order to retreive the path relative to some other, parent DOM node (e.g. the SVG root container), you can use the technique here.

It uses SVG.getTransformToElement which calculates the transform between a parent and some node on the SVG tree. The returned object contains methods to return the inverse of the transform, etc, to do practical things with it.

How to determine size of Raphael object after scaling & rotating it?

I dont know exactly what you are trying to achieve, but this has the power to do it.

Community
  • 1
  • 1
Jay Day Zee
  • 602
  • 6
  • 8