SVG to Flutter Path converter
Convert your SVG file directly to Flutter paths and prevent all the messing with bezier curves.
Input
SVG file
Output
Flutter Path()
Added:
13 Jul, 2020
post-image
Tip
I made the code open source. So in case you want to see the code, use it in you CI pipeline or contribute, see the code on GitHub.
Otherwise just use the live functionality on this page.

Convert your SVG file directly to Flutter paths and prevent all the messing with bezier curves.
Just tap on the Convert SVG button, choose your SVG file and you can obtain the resulting Flutter code from the text field below.
If you want to see real world example input and output, hit the respective buttons underneath. The examples are the ones from the howto.

Convert SVG
Example input
Example output
Copy code
    

Flutter code

Howto

This tutorial describes the usage including the SVG creation using an actual example.

Advantages

  • No manual dealing with code that creates bezier paths
  • The code that is being returned from the converter is designed to be rather readable (no long numbers with high precision) and can thus be edited afterwards
  • The converter supports multiple paths at once in the SVG file
  • It softens curves a little
  • The boundaries of the existing paths are detected automatically. So no values except for the SVG file need to be provided
  • Aside from path nodes in the SVG the converter also converts rect and circle nodes
  • Colors are recognized from the shapes and find their representation in the output as well

Caveats

  • For the converter to properly convert the SVG into a Path it is recommended to put everything to (0,0) of the canvas (except for the paths that are supposed to be shifted)
  • If padding is desired, a rect should be wrapped around everything with the respective padding towards every shape
  • Every group in the SVG should be dissolved before the conversion as it can lead to side-effects

Comments (45) ✍️

test

Can you add a copy code button?
Reply to test

Marc
In reply to test's comment

Great suggestion! Just added the respective button to the top right of the code container.
Reply to Marc

Nagaraj Alagusundaram

This is a fantastic tool. Please keep is alive till Flutter dies.
Reply to Nagaraj Alagusundaram

Marc
In reply to Nagaraj Alagusundaram's comment

Well I have no reason to shut it down :) Maybe I could make it open source so that people could also run it offline. Will put this on my list.
Reply to Marc

Nagaraj Alagusundaram
In reply to Marc's comment

If you can share your PayPal email I will sponsor you as much as I could afford.
Reply to Nagaraj Alagusundaram

Wojtek
In reply to Marc's comment

I’m looking for an option to run it offline, i can think of a few potential usages of this tool. Do you still think about going open source with that? :)
Reply to Wojtek

Marc
In reply to Wojtek's comment

Oh yes, thank you for reminding me. I have a lot on my list right now, but I will contact you via e-mail! Kind regards!

Andriy

@marc thanks a lot for such a cool tool. Just have an idea: can you please somehow run MyPainter in inside a Flutter app in the web, so every one can preview result painter on the same page? like here : https://api.flutter.dev/flutter/widgets/Form-class.html (where you have a “Run” button)?
Reply to Andriy

Marc
In reply to Andriy's comment

@Andriy Thank you for your feedback. I will look into that when I’m home. Thank you for your suggestion!
Reply to Marc

Victor

The tool is great!, but it doesn’t seem to account for the height of the canvas, which leads to the correct shape, but smaller than it should be.

 1class MyPainter extends CustomPainter {
 2    @override
 3    void paint(Canvas canvas, Size size) {
 4      Paint paint = Paint();
 5      Path path = Path();
 6  
 7
 8      // Path number 1
 9  
10
11      paint.color = Color(0xff33455B);
12      path = Path();
13      path.lineTo(size.width * 0.41, -0.62);
14      path.cubicTo(size.width * 0.61, -0.61, size.width * 0.59, -0.4, size.width * 0.69, -0.29);
15      path.cubicTo(size.width * 0.74, -0.23, size.width * 0.83, -0.18, size.width * 0.85, -0.11);
16      path.cubicTo(size.width * 0.86, -0.03, size.width * 0.81, size.height * 0.04, size.width * 0.75, size.height * 0.11);
17      path.cubicTo(size.width * 0.66, size.height / 5, size.width * 0.59, size.height * 0.35, size.width * 0.41, size.height * 0.37);
18      path.cubicTo(size.width * 0.22, size.height * 0.4, 0, size.height * 0.35, -0.11, size.height * 0.24);
19      path.cubicTo(-0.21, size.height * 0.14, -0.11, size.height * 0.01, -0.06, -0.11);
20      path.cubicTo(-0.03, -0.19, size.width * 0.04, -0.24, size.width * 0.1, -0.31);
21      path.cubicTo(size.width / 5, -0.42, size.width * 0.22, -0.63, size.width * 0.41, -0.62);
22      path.cubicTo(size.width * 0.41, -0.62, size.width * 0.41, -0.62, size.width * 0.41, -0.62);
23      canvas.drawPath(path, paint);
24    }
25    @override
26    bool shouldRepaint(CustomPainter oldDelegate) {
27      return true;
28    }
29  }
Reply to Victor

Marc
In reply to Victor's comment

I don’t fully understand your issue. As you can see, size.height does come up in the CustomPainter which means that the height is actually taken into account. You might need to wrap you CustomPaint widget with a SizedBox to control the height. I tried it here: https://imgur.com/Fbq5dXZ - this is height 300 and width 300. If I change the height, the proportions change with it.

Hope that helps!

Reply to Marc

Ahmed Fwela

I think it should use the moveTo instead of lineTo command when translating the M directive in svg
Reply to Ahmed Fwela

Marc
In reply to Ahmed Fwela's comment

You are right. Will change that! Thank you :).
Reply to Marc

jckodel

Doesn’t work for all SVGS. For instance: this simple calendar icon renders completely wrong when converted to Flutter:

svg xmlns=“http://www.w3.org/2000/svg" viewBox=“0 0 512 512” path d=“M446 40h-46V16c0-8.836-7.163-16-16-16s-16 7.164-16 16v24H144V16c0-8.836-7.163-16-16-16s-16 7.164-16 16v24H66C29.607 40 0 69.607 0 106v340c0 36.393 29.607 66 66 66h380c36.393 0 66-29.607 66-66V106c0-36.393-29.607-66-66-66zm34 406c0 18.778-15.222 34-34 34H66c-18.778 0-34-15.222-34-34V181a5 5 0 015-5h438a5 5 0 015 5z” /svg

(removed HTML tags)

Reply to jckodel

Marc
In reply to jckodel's comment

What’s the problem with that? https://ibb.co/MfRYfDR tried it. Looks fine to me
Reply to Marc

Jani

Hello Marc,

This looks awesome, though I have issues with it, my black piano button when converted looks fully gray, lost all 3d defects, here is the svg code:

    image/svg+xml

and here how I implemented it in Flutter:

import ‘package:flutter/material.dart’;

class Test extends StatelessWidget { @override Widget build(BuildContext context) { return Stack( children: [ Align( alignment: Alignment.topLeft, child: CustomPaint( painter: HeaderPainter(), child: SizedBox( width: MediaQuery.of(context).size.width, height: 300))), Align( alignment: Alignment.bottomLeft, child: CustomPaint( painter: FooterPainter(), child: SizedBox( width: MediaQuery.of(context).size.width, height: 300))), ], ); } }

class HeaderPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Paint paint = Paint(); Path path = Path();

// Path number 1

paint.color = Color(0xFFFF5252);
path = Path();
path.lineTo(0, size.height);
path.cubicTo(size.width * 0.09, size.height * 0.93, size.width * 0.11,
    size.height * 0.78, size.width * 0.11, size.height * 0.66);
path.cubicTo(size.width * 0.11, size.height * 0.49, size.width * 0.16,
    size.height * 0.37, size.width / 4, size.height * 0.28);
path.cubicTo(size.width * 0.36, size.height * 0.23, size.width * 0.54,
    size.height * 0.18, size.width * 0.68, size.height * 0.16);
path.cubicTo(size.width * 0.81, size.height * 0.13, size.width * 0.89,
    size.height * 0.07, size.width * 0.98, 0);
path.cubicTo(
    size.width * 0.94, 0, size.width * 0.86, 0, size.width * 0.84, 0);
path.cubicTo(size.width * 0.56, 0, size.width * 0.28, 0, 0, 0);
path.cubicTo(0, 0, 0, size.height, 0, size.height);
canvas.drawPath(path, paint);

}

@override bool shouldRepaint(CustomPainter oldDelegate) { return true; } }

class FooterPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { Paint paint = Paint(); Path path = Path();

paint.color = Color(0xFFFFAB40).withOpacity(1);
path = Path();
path.lineTo(size.width, size.height / 5);
path.cubicTo(size.width, size.height / 5, size.width * 0.94,
    size.height * 0.88, size.width * 0.65, size.height * 0.93);
path.cubicTo(size.width * 0.36, size.height * 0.97, size.width / 5,
    size.height, size.width / 5, size.height);
path.cubicTo(size.width / 5, size.height, size.width, size.height,
    size.width, size.height);
path.cubicTo(size.width, size.height, size.width, size.height / 5,
    size.width, size.height / 5);
canvas.drawPath(path, paint);

}

@override bool shouldRepaint(CustomPainter oldDelegate) { return true; } }

Further more, white piano key that should be easier as it doesn’t have any 3d effects, doesn’t work at all…

Here is the code:

    image/svg+xml

https://imgur.com/a/wKPrlzR On the image you can see keys on right are ones I imported as svg in flutter and one on right is what I get when using your converter

Hope you could help me out figure what is wrong and if it is possible at all to have 3d effects using your tool, I guess maybe your converter works just with one layer? and in order to get 3d effect, your converter should be able to convert svg into multiple layers?

Something like this guy is doing when writing by hand 3d looking buttons? https://www.youtube.com/watch?v=2iMswlPVHFY

Happy holidays

Reply to Jani

Marc
In reply to Jani's comment

Layers should not be a problem. Gradients though, as I only extract the fill color. Also, groups are a problem. If you ungroup everything, it should work. You can set gradients afterwards.
Reply to Marc

ch rohith

hii i am trying some complex svgs to convert but its not giving proper paths can you help me with this?? thanks
Reply to ch rohith

Marc
In reply to ch rohith's comment

Hey! Sorry for the late response. Sure, just mail me the SVG file and we have a look at what’s the problem.
Reply to Marc

Carl2393

It’s not works. The SVG file is there:

https://pastebin.com/L1arSQ2x

Reply to Carl2393

Marc
In reply to Carl2393's comment

You SVG code is very messy. A transformation of -402.445, 166.218. I cleaned up the file and uploaded it: https://pastebin.com/18uGQhfJ. The respective Dart code is also in there.
Reply to Marc

Su

hello marc Doesn’t work for all SVGS. the SVG here: https://pastebin.com/shDF02s0
Reply to Su

pierre

Hi, i don’t understand what i do wrong in svg, could you tell me plz?

Regards

    image/svg+xml
Reply to pierre

Victor

Hi !

Love your work i’d like to support but it seems like it’s not working for even some simple svgs ?

I tried to convert

But it does not seem like it’s working

Reply to Victor

Victor
In reply to Victor's comment

Reply to Victor

Leptopoda

Hi there, still playing around a bit … why not make the colors const likepaint.color = const Color(0xffffffff); and also giving the class a const constructor?

you also wanted to make this open source¿? what happened to those plans? I’m thinking of integrating this into my buildrunner 🙃

Reply to Leptopoda

kherel

Facing error, TypeError: undefined is not an object (evaluating ’t.node.attributes.x.value')
Reply to kherel

kherel
In reply to kherel's comment

my bad, everything is fine
Reply to kherel

Ankit Sagar

This tool doesn’t work with SVG’s exported from FIGMA
Reply to Ankit Sagar

PK

Hi there, Thank you for this great tool! The following snippet however does not generate the correct Dart code it seems.

https://pastebin.com/VWGXHtui

Perhaps some SVG issue?

Reply to PK

Joran

Thanks for this amazing tool. For me it threw an error in the browser console when I defined the fill tag on a path. It would be nice if that got fixed.

After figuring that out I was able to use the tool normally.

Reply to Joran

Martin

Useful, but I needed to hack it a little.

Great tool, but… What if I want to preserve the position and proportion of my path?

I figured out how to do it with your tool, but I think it’s dumb luck that it worked as I intended.

Let’s say this is the desired outcome: https://i.ibb.co/vVyR1x7/2022-02-11-17-52-00.jpg

1.) I create a CustomPaint widget inside a Container of width:300,height:300,color: Colors.amberAccent, 2.) I create an inkscape drawing with dimensions larger than what I need 3.) I drag guide lines to the 300/300 marks 4.) I draw the path that I need

We are now at this point in inkscape: https://i.ibb.co/Wc1Wy2B/2022-02-11-17-59-22.jpg

If I save that and use your converter I don’t get what I need. But if I..

5.) Add an extra line from top left to bottom right of the 300x300 space I want to reference: https://i.ibb.co/DgW6TP6/2022-02-11-18-02-29.jpg

Now your converter will respect to relative position and relative size of my path: https://i.ibb.co/r5jFLtg/2022-02-11-18-10-06.jpg

All I have to do is change the first part of the generated flutter-path from lineTo to moveTo

As I said: Now it works for me! But maybe you would like to add something to support “relative proportions”/“relative position”

Reply to Martin

Marc
In reply to Martin's comment

Hey Martin, you’re correct with what you’re saying. That’s why I had stated this in the caveats:

If padding is desired, a rect should be wrapped around everything with the respective padding towards every shape So instead of creating a line, you might as well go for a white or transparent background rectangle.

Other than that, you are correct and I might as well update the tool.

Cheers!

Reply to Marc

Atish Paul

Hi, first of all thanks for this handy tool. further can we animate the svg with this tool? because flutter does not support animated svg.
Reply to Atish Paul

Joao

Not working. I exported from Photoshop, but when open in the tool, neither code is generated. Is a simple svg
Reply to Joao

Marc
In reply to Joao's comment

Hey there, Joao.

Without having seen your SVG file, it’s hard for me to find out why it didn’t work. Have you followed the instructions listed under caveats? If you have and it still does not work, please contact me. I will respond and you can send me the file via SVG. Optionally, you might want to share the file on pastebin as response to this comment.

Reply to Marc

hagen

why f* the html / js demo page not?
Reply to hagen

Marc
In reply to hagen's comment

Hi hagen,

I’m having a hard time following what you want to say. Do you mean to say the conversion on this page is not working for you?

Reply to Marc

Kamil

Hi Marc,

Please check your convert.js script. I noticed shapesToFlutterCodeConverter() doesn’t give all mandatory params: width, height, and config. So… the converter at a website not working correctly but locally, after applying these changes everything is fine.

Reply to Kamil

Marc
In reply to Kamil's comment

Hey Kamil,

thank you for mentioning. I fixed it in the latest commit as I have mentioned here: https://github.com/flutter-clutter/svg-to-flutter-path-converter/issues/5. I hope it works for you now :).

Reply to Marc

Oleksii

Is it still working? Cause nothing happens after I upload SVG
Reply to Oleksii

Gil

Hi, this online tool is using the same updated version from github? I get some SVGs converted with some glitches (some curves are not correct mapped from svg to flutter). I make sure svg is closed as well
Reply to Gil

Marc
In reply to Gil's comment

Hey Gil,

no, actually the version here is rather old and differs from the other version. The other version uses node packages whereas here on the website I use the CDN version of certain packages.

Reply to Marc

Marwin Lebensky

Hey Marc, awesome tool! Used it 2 years ago and now here I am again. But this time i noticed some visual issues.

#1 I found out that when you have more than 2 decimals this tool rounds them to max 2 decimals. It would be great if there would be an option to allow e.g. 3 or more decimal places to be parsed. The asset I use as an input gets weird roundness shapes due to the relatively unprecise decimal places. Especially if the tool outputs cubitTo this visual bug occurs.

#2 Most of the assets I want to convert are compound. By default, this tool uses “lineTo” instead of “moveTo” when there are jumps between points. This should be defaulted to “moveTo” in order to not draw lines between shapes that should not exist.

You can also invite me to your repo (if possible), I could help fixing the issue.

Still a great and loved tool! Cheers

Reply to Marwin Lebensky

Marc
In reply to Marwin Lebensky's comment

Hey Marwin,

These are totally valid points. Would you mind creating the respective PRs in my GitHub Repo? I will gladly merge them if they fix the mentioned issues.

Reply to Marc

Comment this 🤌

You are replying to 's commentRemove reference