newsdev / ai2html

A script for Adobe Illustrator that converts your Illustrator artwork into an html page.
http://ai2html.org
Other
897 stars 145 forks source link

Add option to include SVG output inline #87

Closed mbloch closed 6 years ago

mbloch commented 6 years ago

... instead of including as <img> elements.

This would permit targeting SVG content with CSS and JavaScript.

mbloch commented 6 years ago

v0.68.0 adds the inline_svg option. Not thoroughly tested yet.

cedricsam commented 6 years ago

This is pretty cool. We'll give it a try when we have a chance.

mbloch commented 6 years ago

A note about using this option:

This option affects both SVG that is output as the background image (i.e. image_format: svg) and SVG overlay layers, which are created from Illustrator layers with names that end with :svg).

Illustrator assigns an "id" property to SVG objects that have names in the Illustrator document. In theory you could target SVG objects using these ids. This seems unreliable though, because Illustrator modifies the names in ways that are hard to predict.

It might be possible to rewrite the output SVG with better ids, add class names, or do something else to make it easier to target individual objects.

cedricsam commented 6 years ago

We did notice that they append a _n_ (where n is a number), and have stripped that before browser events are attached, in our use case. But it's not a sustainable solution indeed, because IDs should be unique (and who knows, might change depending on the Illustrator version.

I don't know the proper way to rewrite the SVG though... Do you think it would be too much heavy lifting to either re-parse and re-write the SVG file before inlining it? (I see that the options causes the script to read the SVG file and print its contents straight per https://github.com/newsdev/ai2html/blob/master/ai2html.js#L2724-L2729)

Or, other maintenance/dev-heavy option, read the Illustrator element tree, print the SVG on our own...

mbloch commented 6 years ago

I'm inclined to start by rewriting the ids using str.replace(regexp, function). The replacement function would try to restore the original object names and prevent duplicate ids within a single document. To prevent collisions on the html page, we could do what we did with mapshaper (remember?) and add an "id_prefix" option. Does this sound workable as a solution?

cedricsam commented 6 years ago

Yes -- referring to this: https://github.com/mbloch/mapshaper/pull/246

So, it sounds like good idea overall for avoiding collisions across the HTML page to have the namespace solution like for mapshaper.

How would you restore the original name and prevent duplicate ids at the same time though?

I like the regexp idea though, and we could perhaps get the original object name, and then use it for a data attribute? I think our main use case (could be others) is to attach the same event listener to the same element (or types of elements) across responsive versions, so targeting ids might be unpractical. This is the particular use case: https://www.bloomberg.com/graphics/2018-brexit-portraits/ (top map of this link)

mbloch commented 6 years ago

Duplicate ids (caused by duplicate Illustrator object names) could be handled by printing a warning and/or appending a number (e.g. dot, dot2, dot3).

If you want to target multiple instances, it might be preferable to translate object names to something other than ids, say, classnames or data-<varname> attributes.

cedricsam commented 6 years ago

I'd go with preserving the way Illustrator adds those _n_ at the end of the IDs then. What do you think?

And yes, it makes sense to translate the object names to class names or data-<varname> data attributes.

mbloch commented 6 years ago

Hey... I pushed a commit that de-mangles inline svg ids.

I'm only rewriting the ids of inline svg, because external svg files get loaded as images, which makes the contents unreachable by CSS and JS on the page, as far as I know.

There's also a new svg_id_prefix option for namespacing.

I thought for this version I'd leave the first occurrence of an id unchanged, and apply a suffix only to subsequent colliding ids.

... ai2html should also print a warning for every duplicate SVG id that it finds

cedricsam commented 6 years ago

Oh cool, LGTM! So it'll clean those ugly Illustrator ids up.

Can we hack https://github.com/newsdev/ai2html/blob/9e26ecf0f603d031409d7ad38731bf1f9dc5fd56/ai2html.js#L2756 to:

return 'id="' + prefix + uniqId + '" data-someattribute="' + prefix + fixedId + '"';

data-someattribute could be data-illustrator-name (or something that reflects what it is in the Illustrator API?)

Will the warnings be printed in the end-of-script dialog box? I think most of the times, having duplicate element names in Illustrator is a deliberate choice for the use we make of inline SVGs... So it would feel a big overwhelming to see the warning pop in the box. I saw you had a bunch of warn/warnings-related changes though, but didn't navigate the code fully to see what it did. Does it change the dialog box behavior?

mbloch commented 6 years ago

I just noticed that the SVG generated using the Illustrator GUI via File > Export As is much cleaner that what you get via the JavaScript API that ai2html uses. The SVG from "Export As" doesn't mangle id names and generates unique ids basically the same way that I am (first one is unchanged, then -2, -3, etc are appended). Also, they're adding a 'data-name' attribute containing the original name (but only when the id is modified).

I propose adding 'data-name=' next to every object with an id -- that should help with your use case.

Would it be ok if we left the prefix off of the data-name values?

I'd like to run your request to leave the warnings off by Archie -- he asked me to put the warnings in.

cedricsam commented 6 years ago

Re: warnings, sounds good with keeping the warnings, especially if Archie asked for it! We don't have a real-life use case with SVG/ai2html in the near future, although I'll encourage our people to try it in the next few weeks / months (surely simpler than exporting SVGs individually).

As for the IDs, I actually went back and tried to export through the two ways on Illustrator (Export As, and Export for Screens). My colleague was on CC 2015, but I'm on CC 2018 (22.0.1), and the IDs are clean, the way you see them, with the -2 and data-name.

My colleague's on 2015, and she was getting the weird _n_ and other characters.

So yes, I agree with adding it as data-name. And yes too with not including the prefix -- sounds cleaner, more sustainable if the prefix gets changed. :)

Do you think it's worth revisiting uniqify to (try to) mirror how newer Illustrator GUI exports?

mbloch commented 6 years ago

Hey, commit a5695d2e95d81fe238a34e99eae9508c2a585b84 adds data-name= attributes and tames the duplicate warnings a bit.

You asked about the warning related changes... there's no change in functionality, just trying to switch to using functions for logging messages.

re: uniqify -- I changed to using hyphens in the suffix, to match Illustrator's GUI output.

cedricsam commented 6 years ago

Can close, I guess. Thanks! I can leave some comments here if we encounter practical problems with inline SVGs.

cedricsam commented 6 years ago

Here’s our first SVG exported with inline_svg: https://www.bloomberg.com/graphics/2018-russian-billionaires-british-assets/

I didn’t realize that the feature also meant that only vector-based elements are rendered in the inline SVG, while the text still gets converted to HTML elements. It’s a really nice behavior and preferred. :)

mbloch commented 6 years ago

Nice-looking treemap :)

mbloch commented 6 years ago

We've used inline svg a few times too... guess it's far enough along to close this issue.