piqnt / svgexport

SVG to PNG/JPEG command-line tool and Node.js module
927 stars 85 forks source link

Suggestion: Add classname to outer element #23

Open littlefyr opened 8 years ago

littlefyr commented 8 years ago

While its interesting that you could add inline style in the commandline arguments, I'm not sure how practically useful it would be.

What would be useful, however, is the ability to add className values to some container (either the outer SVG, or the parent of the SVG if that's how you're doing the rendering).

The main usecase being icons or buttons. Say "enabled" or "selected" or "over important"

shakiba commented 8 years ago

Could you please elaborate an example? I guess I have not yet understand your suggestion.

littlefyr commented 8 years ago

Sure.

If you're using SVG for icons, you are likely going to use the same icon in a number of different contexts. take a look at Bootstrap http://getbootstrap.com/components/#glyphicons-examples. So you need a way to say "I want the icon for primary button" vs "I want the icon for a disabled line item". While the common situation is "I want to change the colour", if you look at how Iconic handles responsive icons (see https://useiconic.com#responsive) one may also want change more than just the colour.

shakiba commented 8 years ago

I see. Isn't it possible to just pass different styles to the command each time? That is, instead of using class-names to select styles to apply, only pass those styles which should be applied.

littlefyr commented 8 years ago

Its possible but its hardly efficient or desirable. Its far easier to simply use a CSS file referenced in the SVG. If you're matching web and native app, you'd have to duplicate all that style, once in the build script and once in the CSS for the site. Ongoing maintenance will be a mess.

If you're modifying the markup to add CSS, its not much more difficult to add a class name. I think that something like the following should be sufficient (if you call it similar to how you call injectCSS(page, style)

function addClassNames(page, classNames) {
  page.evaluate(function(classNames) {
    var svg = document.documentElement;
    var classes = svg.getAttibute('class') + ' ' + classNames;
    svg.setAttribute('class', classes);
  }, classNames);
}

I haven't tested that but its probably close

shakiba commented 8 years ago

Ok, I understand. However, in order to cover your use-case I prefer to implement something which would cover a wider range of functionalities, for example injecting JS (which would allow any manipulation including adding a class-name) or piping svg through a user code, etc. I guess it will take me a little time to evaluate different solutions but I will add something to cover this.

littlefyr commented 8 years ago

Sure, but I think in the real world, this is going to be a far more common use case than wanting to make the sorts of changes that usercode would be ideal for (or even adding CSS snippets, for that matter).