jovial_svg icon indicating copy to clipboard operation
jovial_svg copied to clipboard

Support SVG parsing to/from path.pathData

Open Bindslev opened this issue 9 months ago • 4 comments

In extension to the new awesome feature where you can manipulate the SVG and rebuild it seamlessly by coloring it and other cool stuff, I had this idea that I experimented with a little bit. If you lookup a SvgPath like so:

final lookup = svg.dom.idLookup;
path = lookup['p'] as SvgPath;

You have the path.pathData at disposal which basically tells you how that particular path is shaped. There are libraries out there that can transform this pathData to a dart:ui Path object which you can then change by its various methods, for example the transform method. However, I couldn't find an easy way to transform the Path object back into a string which I could then override the original SVG with and rebuild it to create this illusion that the object was changed. It would be cool, imagine you could click on an object and it would scale up and down or some other effect :)

Here are some stackoverflow posts looking for such feature: flutter-dart-svg-path-to-string is-it-possible-to-get-an-svg-string-from-flutter-path-object

A newly created issue on another library requesting such feature: https://github.com/masterashu/svg_path_parser/issues/9

I don't know if this is out of scope for this library, I don't know if it's even possible to parse that way, so I'm just throwing it out there in case it's in scope and would be fun to implement.

Bindslev avatar Apr 30 '24 18:04 Bindslev

Interesting idea.

Once it's a Dart Path, I'm pretty sure the contents are opaque -- there's no going back to a string, at least not without native code to reconstruct something from an internal (almost certainly binary, and only accessible from native code) representation. However, the DOM API could always be extended to accept a Path object, so one could take the SVG parse graph, parse the Path, manipulate it with the Flutter APIs, and then swap the manipulated Path into the parse graph.

A another way of playing with paths would be to expose the path parser (PathParser in path_noui.dart), and allow programmatic manipulations to be inserted into the String -> Path pipeline. Now that I think about it, the first idea (swapping in a fully-baked Path object) is a subset of this second one.

Maybe a reasonable way to expose all this would be to allow a to-be-defined PathTransformer on SvgDOM.build that gets a chance to manipulate all of the path-producing nodes (SvgPath, SvgRect, etc.).

zathras avatar Apr 30 '24 19:04 zathras

BTW, for the example of scaling a Path, you could always put an appropriate transform on the SvgInheritableAttributesNode that holds the path.

zathras avatar May 01 '24 03:05 zathras

Looking at this some more, I'm not sure how much would be gained by exposing the production of Path objects. It's doable, but a little messy. I guess Path.combine might produce some interesting effects, but treating that as an "edit" of an SVG asset is a stretch.

I'm thinking of leaving any direct production of a Path object out for now. The most sensible way I can think of doing that would be to make a special SvgCustomPath type that just has a Path in the constructor. Users would then insert that into a parse graph (like by adding it to an SvgGroup).

I did expose the path parser, and make a utility that can build up a new path string. This allows editing of a path, with a bit of work. For a transform, there's always adding a transform to the containing node.

See the docs at 1.1.21-rc.4: PathParser and StringPathBuilder.

zathras avatar May 01 '24 20:05 zathras

This is awesome! I think I might try and use this for some cool animations when something is clicked. Always looks good with some animations and it's really fun to play around with. This was just an idea and the fact that you made it possible in such a short time is just amazing... I am running out of ideas on new features. I'll play around with this over the weekend and let you know if I come up with more :)

Bindslev avatar May 04 '24 09:05 Bindslev

Released in 1.1.21

zathras avatar May 12 '24 18:05 zathras