Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please add the option to flatten transforms #624

Open
Emasoft opened this issue Nov 20, 2016 · 38 comments
Open

Please add the option to flatten transforms #624

Emasoft opened this issue Nov 20, 2016 · 38 comments

Comments

@Emasoft
Copy link

Emasoft commented Nov 20, 2016

"Flatten Transforms" option is available in SVG editors like Affinity Designer (~$40 / Mac) and it is very useful. It also improve performances of SVG rendering because coordinate transforms are precalculated.

ppg1q

Please add this option to SVGO.

@GreLI
Copy link
Member

GreLI commented Nov 20, 2016

What does it do? If you mean applying transforms to paths then SVGO already does that when it possible.

@Emasoft
Copy link
Author

Emasoft commented Nov 20, 2016

It flattens the transforms of all elements (including elliptical arcs, gradients, text and tspan) concatenating the cumulative transforms of all parents since the root node and applying the resulting matrix to the leaf elements (rects are converted to polygons to allow that). When not possible to completely eliminate the transform (for edge cases like some filters on groups), the children element is left with a transform matrix that includes all transformations of the parents, so that the matrix multiplications required to get the the element local coordinates are minimized.

@GreLI
Copy link
Member

GreLI commented Nov 20, 2016

Well, SVGO does something of that.

@Emasoft
Copy link
Author

Emasoft commented Nov 20, 2016

It does a very little of this, actually. Transforms in the output file are still too many compared to Affinity Designer exported svg file.

@GreLI
Copy link
Member

GreLI commented Nov 20, 2016

It'd be more helpful if you provide such examples. Also, there was a bunch of bugs with incorrectly moved transforms, so one need to be careful with them.

@steadicat
Copy link

Here's some examples of what I think @Emasoft is talking about:

Input:

<svg>
    <g transform="translate(2.240000, 10.453333)">
        <rect fill="#000" x="210.56" y="94.359" width="22.811" height="33.2" rx="3.733"/>
        <rect fill="#FFF" x="210.56" y="94.359" width="22.811" height="33.2" rx="3.733"/>
    </g>
</svg>

Output:

<svg>
    <g transform="translate(2.24 10.453)">
        <rect x="210.56" y="94.359" width="22.811" height="33.2" rx="3.733"/>
        <rect fill="#FFF" x="210.56" y="94.359" width="22.811" height="33.2" rx="3.733"/>
    </g>
</svg>

Should be:

<svg>
    <rect x="212.80" y="104.812" width="22.811" height="33.2" rx="3.733"/>
    <rect fill="#FFF" x="212.80" y="104.812" width="22.811" height="33.2" rx="3.733"/>
</svg>

Input:

<svg>
    <g transform="translate(2.240000, 10.453333)">
        <rect fill="#000" x="210.56" y="94.359" width="22.811" height="33.2" rx="3.733"/>
    </g>
</svg>

Output:

<svg>
    <rect x="210.56" y="94.359" width="22.811" height="33.2" rx="3.733" transform="translate(2.24 10.453)"/>
</svg>

Should be:

<svg>
    <rect x="212.80" y="104.812" width="22.811" height="33.2" rx="3.733"/>
</svg>

@Emasoft
Copy link
Author

Emasoft commented Mar 10, 2017

Any update on this?
This is a much needed feature because it allows to copy paste any xml node from an svg file to inline html without having to copy all parents nodes.

@GreLI
Copy link
Member

GreLI commented Mar 11, 2017

I'm planning such an operation, but no updates yet.

@mattvenn

This comment was marked as spam.

@Emasoft
Copy link
Author

Emasoft commented Jun 27, 2017

How long before this is implemented? This is a much needed feature. Too much time wasted in doing this manually every day.

@GreLI
Copy link
Member

GreLI commented Jun 29, 2017

I'm afraid not so soon. It's trivial enough, but I have no time for this.

@nashwaan
Copy link

@GreLI I hope you get time to get this important feature implemented very sooooooooooooon.
😊

@macrozone
Copy link

would also be useful to convert svg graphics to simple paths, which can easily be used in react-native-svg

@irisjae
Copy link

irisjae commented Sep 23, 2017

seems theres an existing package https://github.com/stadline/svg-flatten to do it, maybe someone could transform this into an svgo plugin? btw the package does not seem to handle filters, maybe we should add a clause in the recursion to flatten the transform onto the filter as well. besides filters, are there any other cases where we might need to recurse transform flattening beyond a nodes children? masks maybe?

@steadicat
Copy link

I wrote code to flatten transforms for my own project, in case anyone wants to port it over. It doesn't quite support all possible transforms on all shapes yet, but it's a start.

@lemnis
Copy link

lemnis commented Nov 8, 2017

Another day, another starting point, my fork https://github.com/lemnis/svgo has support of removing translate of a select group of properties. It also has the tests of above mentioned code written by @steadicat, currently my code fails most of the tests and I am not planning to improve my code in the near future.

@nashwaan

This comment was marked as spam.

@lemnis
Copy link

lemnis commented Nov 8, 2017

@nashwaan Be grateful that other people are willing to use their precious time to create and extend code that everybody can use. Otherwise, you have 2 options, pay lots of money more for all software you use or create the code yourself.

Or maybe the last solution is the best for you, keep waiting patiently. 😉

@nashwaan
Copy link

nashwaan commented Nov 8, 2017

@lemnis Thank you for educating me and telling me I should be grateful to the open source community.

@saivan
Copy link

saivan commented May 13, 2018

I've had the same issue, it would be really nice to be able to flatten everything.

@cheshrkat
Copy link

+1 this would be awesome.

@morewry
Copy link

morewry commented Aug 17, 2018

I have this issue too, and I'd swear it used to work better. But currently SVGO doesn't "flatten" or precalculate even very simple transforms. I have examples where there's a transform translate of 1,1 on a group and even that isn't recalculated.

One very common source of unnecessary transformations stems from the behavior of design software for working with SVGs. They tend to be very literal. If you click the "path" tool, you get a path. If you click the "circle" tool, you get a circle. And if you draw an icon with some shapes, group them, then move it down with the arrow key 4 times and to the right 8 times, you'll end up with a group that has a transform translate of 8, 4. (This is true of every single editor I've used: Illustrator, Sketch, Inkscape, etc--though some of them offer ways to flatten the transforms. Sketch, however, [which we use] doesn't.)

As the OP mentions, this is just noise--there's no reason whatsoever to preserve a transformation of that kind and so files that preserve this are missing an obvious if relatively minor optimization.

But in my situation this leads to real issues. I have a use case where we need to convert our icons to Android's Vector Drawable format. We work with SVG as the "origin" format and convert to Vector Drawable after optimizing with SVGO. Vector Drawables are a little touchy, it seems (we had issues if we optimized away leading 0s), and there aren't many tools available to automate this conversion.

And, it turns out, these preserved translations also cause issues. They're unsupported or just ignored in the conversion process and result in the icon being mis-aligned and cut off relative to the viewbox.

Example SVGs, before and after

Before

<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 51 (57462) - http://www.bohemiancoding.com/sketch -->
    <title>icon/UI 24px/Vision Small (eye)</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="icon/UI-24px/Vision-Small-(eye)" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linejoin="round">
        <g id="Export" transform="translate(0.750000, 6.000000)" stroke="#000000" stroke-width="1.5">
            <circle id="Oval" cx="11.1290323" cy="5.93548387" r="5.86870968"></circle>
            <path d="M11.25,2.69999981 C13.0693329,2.69999981 14.5441935,4.1748605 14.5441935,5.99419336" id="Shape"></path>
            <path d="M22.25,6 C19.7671057,2.32106779 15.5674223,0.0515191927 11.1290323,0.0515191927 C6.69064219,0.0515191927 2.54224915,2.25655166 0.0593548387,5.93548387 C2.34284932,9.31404472 6.0448217,11.4641714 10.110942,11.7735029 C14.1770623,12.0828345 18.0141602,10.4943237 20.93,7.52322581 C21.3881491,7.05639433 21.8281491,6.5486524 22.25,6 Z" id="Shape"></path>
        </g>
    </g>
</svg>

After

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" display="block" pointer-events="none" viewBox="0 0 24 24">
  <g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linejoin="round" stroke-width="1.5" transform="translate(.75 6)">
    <circle cx="11.129" cy="5.935" r="5.869"/>
    <path d="M11.25 2.7a3.294 3.294 0 0 1 3.294 3.294M22.25 6C19.767 2.321 15.567.052 11.129.052A13.355 13.355 0 0 0 .059 5.935a13.355 13.355 0 0 0 10.052 5.839c4.066.309 7.903-1.28 10.819-4.25.458-.468.898-.975 1.32-1.524z"/>
  </g>
</svg>

Before

<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 51 (57462) - http://www.bohemiancoding.com/sketch -->
    <title>icon/Display 32px/Vision (eye)</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="icon/Display-32px/Vision-(eye)" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linejoin="round">
        <g id="Export" transform="translate(1.000000, 8.000000)" stroke="#000000" stroke-width="1.5">
            <circle id="Oval" cx="15" cy="8" r="7.91"></circle>
            <path d="M15,3.56 C17.4521443,3.56 19.44,5.54785571 19.44,8" id="Shape"></path>
            <path d="M30.3862847,8.58371311 C30.3073441,8.50705295 30.2439761,8.42555519 30.1961806,8.33921984 C30.1483851,8.25288448 30.0563249,8.1398112 29.92,8 C26.5734903,3.04143919 20.9821779,0.0694389119 15,0.0694389119 C9.01782208,0.0694389119 3.42650973,3.04143919 0.08,8 C3.15775344,12.5537124 8.14736837,15.4517092 13.6277914,15.8686344 C19.1082144,16.2855596 24.4788024,14.175719 28.21,10.14 C28.2774066,10.0677786 28.3279616,10.0136126 28.3616649,9.97750186 C28.3901838,9.94694589 28.4422526,9.89716988 28.5178711,9.82817383" id="Shape"></path>
        </g>
    </g>
</svg>

After

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" display="block" pointer-events="none" viewBox="0 0 32 32">
  <g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linejoin="round" stroke-width="1.5" transform="translate(1 8)">
    <circle cx="15" cy="8" r="7.91"/>
    <path d="M15 3.56A4.44 4.44 0 0 1 19.44 8m10.946.584a1.052 1.052 0 0 1-.19-.245c-.048-.086-.14-.2-.276-.339A18 18 0 0 0 .08 8a18 18 0 0 0 28.13 2.14l.152-.162c.028-.031.08-.08.156-.15"/>
  </g>
</svg>

Before

<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 51 (57462) - http://www.bohemiancoding.com/sketch -->
    <title>icon/UI 24px/Pin (map marker, location)</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="icon/UI-24px/Pin-(map-marker,-location)" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Export" transform="translate(4.125000, 1.750000)" stroke="#000000" stroke-width="1.5">
            <path d="M15.75,7.875 C15.75,14.625 7.875,20.25 7.875,20.25 C7.875,20.25 0,14.625 0,7.875 C0,3.4875 3.4875,0 7.875,0 C12.2625,0 15.75,3.4875 15.75,7.875 Z" id="Shape"></path>
            <circle id="Oval" cx="7.875" cy="7.75" r="3.25"></circle>
        </g>
    </g>
</svg>

After

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" display="block" pointer-events="none" viewBox="0 0 24 24">
  <g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-width="1.5" transform="translate(4.125 1.75)">
    <path d="M15.75 7.875c0 6.75-7.875 12.375-7.875 12.375S0 14.625 0 7.875A7.827 7.827 0 0 1 7.875 0a7.827 7.827 0 0 1 7.875 7.875z"/>
    <circle cx="7.875" cy="7.75" r="3.25"/>
  </g>
</svg>

Before

<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 51 (57462) - http://www.bohemiancoding.com/sketch -->
    <title>icon/Display 32px/Prescription Generic (pharmacy, medicine, bottle, Rx)</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="icon/Display-32px/Prescription-Generic-(pharmacy,-medicine,-bottle,-Rx)" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Export" transform="translate(6.000000, 1.750000)" stroke="#000000" stroke-width="1.5">
            <path d="M2.06,0.08 L17.94,0.08 C18.4253462,0.08 18.8908138,0.272803018 19.2340054,0.61599459 C19.577197,0.959186163 19.77,1.42465382 19.77,1.91 L19.77,5 L0.229972639,5 L0.23,1.92 C0.22733834,1.43292351 0.4189657,0.964882708 0.762446184,0.619525281 C1.10592667,0.274167854 1.57291623,0.0799927277 2.06,0.08 Z" id="Shape" stroke-linejoin="round"></path>
            <path d="M0.23,13 L19.77,13" id="Shape" stroke-linejoin="round"></path>
            <path d="M19.77,24.5 L0.23,24.5" id="Shape" stroke-linejoin="round"></path>
            <path d="M2.75,7.24 L2.75,7.95 C2.75114043,8.94951168 2.22325652,9.89667602 1.45,10.53 C0.679451144,11.1611045 0.231855477,12.1039905 0.23,13.1 L0.23,28.5 L19.7700022,28.5 L19.77,13.1 C19.7711404,12.1004883 19.3232565,11.153324 18.55,10.52 C17.7767435,9.88667602 17.2488596,8.93951168 17.25,7.94 L17.25,7.24" id="Shape" stroke-linejoin="round"></path>
            <circle id="Oval-3" cx="10" cy="18.75" r="2.75"></circle>
        </g>
    </g>
</svg>

After

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" display="block" pointer-events="none" viewBox="0 0 32 32">
  <g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-width="1.5" transform="translate(6 1.75)">
    <path stroke-linejoin="round" d="M2.06.08h15.88a1.83 1.83 0 0 1 1.83 1.83V5H.23V1.92A1.83 1.83 0 0 1 2.06.08zM.23 13h19.54m0 11.5H.23M2.75 7.24v.71c.001 1-.527 1.947-1.3 2.58A3.33 3.33 0 0 0 .23 13.1v15.4h19.54V13.1a3.33 3.33 0 0 0-1.22-2.58c-.773-.633-1.301-1.58-1.3-2.58v-.7"/>
    <circle cx="10" cy="18.75" r="2.75"/>
  </g>
</svg>

Before

<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Generator: Sketch 51 (57462) - http://www.bohemiancoding.com/sketch -->
    <title>icon/UI 24px/Search (magnifying glass, find, discover)</title>
    <desc>Created with Sketch.</desc>
    <defs></defs>
    <g id="icon/UI-24px/Search-(magnifying-glass,-find,-discover)" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Export" transform="translate(1.000000, 1.000000)" stroke="#000000" stroke-width="1.5">
            <circle id="Oval" cx="8.5" cy="8.5" r="7.75"></circle>
            <path d="M21,21 L13.9821656,13.9821656" id="Shape"></path>
        </g>
    </g>
</svg>

After

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" display="block" pointer-events="none" viewBox="0 0 24 24">
  <g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-width="1.5" transform="translate(1 1)">
    <circle cx="8.5" cy="8.5" r="7.75"/>
    <path d="M21 21l-7.018-7.018"/>
  </g>
</svg>

SVGO config
const hash = require('string-hash');

module.exports = {
  full: true,
  multipass: true,
  precision: 3,
  // order of plugins is important to correct functionality
  plugins: [
    { removeDoctype: true },
    { removeXMLProcInst: true },
    { removeComments: true },
    { removeMetadata: true },
    { removeXMLNS: false },
    { removeEditorsNSData: true },
    { cleanupAttrs: true },
    { inlineStyles: true },
    { minifyStyles: true },
    { convertStyleToAttrs: true },
    { cleanupIDs: true },
    {
      prefixIds: {
        prefix: function(element, filePath) {
          const fileNameId = hash(
            filePath
              .split('/')
              .slice(-2)
              .join('/')
          );
          return `i${fileNameId}`;
        }
      }
    },
    { removeRasterImages: true },
    { removeUselessDefs: true },
    { cleanupNumericValues: true },
    { cleanupListOfValues: true },
    { convertColors: { currentColor: true } },
    { removeUnknownsAndDefaults: true },
    { removeNonInheritableGroupAttrs: true },
    { removeUselessStrokeAndFill: true },
    { removeViewBox: false },
    { cleanupEnableBackground: true },
    { removeHiddenElems: true },
    { removeEmptyText: true },
    { convertShapeToPath: true },
    { moveElemsAttrsToGroup: true },
    { moveGroupAttrsToElems: true },
    { collapseGroups: true },
    { convertPathData: true },
    { convertTransform: true },
    { removeEmptyAttrs: true },
    { removeEmptyContainers: true },
    { mergePaths: true },
    { removeUnusedNS: true },
    { sortAttrs: true },
    { removeTitle: true },
    { removeDesc: true },
    { removeDimensions: false },
    { removeAttrs: false },
    { removeElementsByAttr: false },
    { addClassesToSVGElement: false },
    { removeStyleElement: true },
    { removeScriptElement: true },
    {
      addAttributesToSVGElement: {
        attributes: [{ display: 'block' }, { 'pointer-events': 'none' }]
      }
    }
  ],
  js2svg: {
    pretty: false,
    indent: ''
  }
};

Could be this works better with some configurations than others, but I'm sure we're all aware that SVGO can be a bit challenging to configure, so if anyone has some tips on that, please share, it could help in some cases.

(One configuration possibility that I tried was not doubling up on moveElemsAttrsToGroup and moveGroupAttrsToElems, but enabling either option alone didn't help flatten any of these. I don't 100% guarantee I didn't make a mistake on that experiment, because all 3 ways ended up with the transform on the group [though other attributes did move], which strikes me as a little odd.)

@upendra-web
Copy link

@Emasoft, recently I made this repo, just like SVGOMG but with Vue. I added flatten svg option, whose code was provided by Timo in his gist (with some modifications). It is still in experimental stage. It worked on the transforms of most of the paths (except some text and clipaths). So can anyone check that option and give your opinions.

Thank you all.

@andrewrcollins
Copy link

@upendra-web Superb work with lean-SVG !

@upendra-web
Copy link

@upendra-web Superb work with lean-SVG !

Thank you very much @andrewrcollins

@MarkJeronimus
Copy link

MarkJeronimus commented Oct 22, 2019

Lean-SVG still doesn't work with rect and circle.
It's been 3 years, and I can see you put an enormous amount of effort in SVGO, so why not finish it with transform applying?

@maxwell8888
Copy link

maxwell8888 commented Feb 5, 2020

If you are using Inkscape:

  1. Select everything and ungroup
  2. Save as "Optimised Svg (*.svg)"

In all cases I have tried, this has removed any transform attributes, then I can run through SVGO without having to worry about transforms. Not sure if it works for all SVG, but certainly the ones I have tried so far.

@user98765446
Copy link

@maxwell8888 this works well for some elements, but not all unfortunately.

Some very tricky ones are:

  • linear gradients
  • masks
  • clones (sometimes it is preferable to maintain as clones)

I realise that the status of this is not likely to change, but I would love to know if it does (or if anyone finds a suitable workaround).

@specious
Copy link

specious commented Jul 12, 2021

I've been able to apply transforms to path elements manually using stadline/svg-flatten provided that the transform attribute was associated with the path element itself (and not a group) by running in the nodejs interpreter (inside the project directory):

var flatten = require('./')
var svg = fs.readFileSync('./logo.svg')

flatten(svg).transform().value().toString()

However, this doesn't work as far as preserving the gradients if they have been defined with gradientUnits="userSpaceOnUse". If such a gradient is specified as a fill then the gradient also needs to have the transform applied to it. I imagine this applies to patterns as well.

@davidwebca
Copy link

I really hope this eventually comes in SVGO, I'm relying on Lean-SVG for my day-to-day work right now, but I'd love SVGO to handle everything. I think most of the debate earlier was about the reliability of the transforms, but as long as it's clear that it's an opt-in one, I can't see why not.

@ghost
Copy link

ghost commented Sep 13, 2021

Could we perhaps use Inkscape CLI to ungroup elements with a transform attribute on the group, then regroup them without the transform? That should help remove the transforms.

@milesrichardson
Copy link

I had an auto-generated svg with a transform="matrix(1.5,0,0,1.5,0,0)" on the outer group with only paths inside it. I was looking for a way to perform that translation on each path ahead of time so I could remove the transform, which is how I found this thread.

I was able to accomplish this manually by using either of these tools:

If you don't need an automated solution, these both offer a quick way to apply computations to path data.

@GreLI
Copy link
Member

GreLI commented Oct 14, 2021

BTW, it's good starter task, if someone would like to help.

tillprochaska added a commit to alephdata/followthemoney that referenced this issue Oct 26, 2022
Most of the raw SVG files have translations applied to groups of paths. During the build process, only paths are extracted. As a result, many icons are misaligned. Unfortunately, svgo [doesn't support flattening transforms](svg/svgo#624) yet, so I’ve done this manually.
tillprochaska added a commit to alephdata/followthemoney that referenced this issue Oct 27, 2022
Most of the raw SVG files have translations applied to groups of paths. During the build process, only paths are extracted. As a result, many icons are misaligned. Unfortunately, svgo [doesn't support flattening transforms](svg/svgo#624) yet, so I’ve done this manually.
pudo pushed a commit to alephdata/followthemoney that referenced this issue Nov 2, 2022
Most of the raw SVG files have translations applied to groups of paths. During the build process, only paths are extracted. As a result, many icons are misaligned. Unfortunately, svgo [doesn't support flattening transforms](svg/svgo#624) yet, so I’ve done this manually.
@folsze
Copy link

folsze commented Apr 8, 2023

I just thought about solving this here:
https://stackoverflow.com/a/75964763/20009330

I am not saying that this solves this problem for svgo.
But maybe writing a quick script (like mentioned at the bottom of the answer)
to edit the svg is a workaround for some of you that come here?

@folsze
Copy link

folsze commented Apr 21, 2023

The solution above only works with translate transforms...

A better solution, also for matrix transforms:
maybe think: how do they even appear? Maybe prevent them from entering your svg in the first place?

Inkscape:
in Inkscape, if you select all elements, it'll select groups and not all single elements. Then if you scale etc., it'll likely apply a matrix transform (to the group). We do not want this!

Solution:
Select all single elements without their group folders. And then apply the transform, you'll see, Inkscape will directly apply any transforms if you do the transform operation on the children elements themselves.
So, how to select ALL single elements?

GPT-4 told me this:
ctrl. + f to find all.

THEN:
deselect group elements in advanced search options

then just search with empty input, it'll select all

Here is a screenshot:
image

@mattsputnikdigital
Copy link

Has this been solved now?

@GreLI
Copy link
Member

GreLI commented Oct 17, 2023

@mattsputnikdigital PRs are welcome

@Airkro
Copy link

Airkro commented Jan 22, 2024

#1854 may handle this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests