Flutter Multi-Wayed SVG Styling

Flutter Multi-Wayed SVG Styling

Multiple approaches to styling SVGs in Flutter.

·

6 min read

Introduction

Yes, it never gets as basic as this. However, while working with SVGs can seem simple enough, can you tell me 4 different ways of styling an SVG?

I like the way you are looking to the ceiling to try and think of the possible ways to style an SVG. I'll make it easier for you in this article :)

In this article, we'll work with the SVG image below gotten from undraw.co and try to style it by changing its color properties using different methods.


1. Flutter SVG Package

You would have come across this package before as it's quite popular in the Flutter world. The flutter_svg package allows us to work with SVGs in our app in an easy and straight forward manner.

Setup

SVG Assets Folder

Add an assets folder in your root project directory. Next, add a sub folder called images and add the SVG image of your liking inside this folder as below.

Pubspec.yaml

Next, add the flutter_svg package to your pubspec.yaml file and import your assets in the pubspec.yaml file as shown below.

flutter_svg: ^2.0.9
flutter:

  uses-material-design: true

  assets:
    - assets/images/

Home.dart

FInally, we can now work with our SVG image. The flutter_svg package comes in-built with powerful attributes such as semanticLabel, colorFilter, width, height etc. For this tutorial, we'll focus on the colorFilter attribute to help us change the SVG colour.

return Scaffold(
  body: Center(
    child: SvgPicture.asset(
      'assets/images/undraw_pancakes.svg',
      colorFilter: const ColorFilter.mode(Colors.red, BlendMode.srcIn),
      semanticsLabel: 'Sweet Pancakes',
      width: 200,
      height: 200,
    ),
  ),
);

Here is the result of this code:

Yeah I know, not as pleasing as you had hoped. Well, that's one of the limitations of using the flutter_svg package. Whereas working with simple SVGs such as Icons is simple enough to add a color and style them, more complex SVGs like this one could really pose a huge problem to achieve a more fine-tuned styling.

Let's proceed and try find a solution for this.

GitHub Snippet


2. Flutter ColorFiltered Widget

Similar to the colorFilter attribute of the flutter_svg package, you can also wrap your SvgPicture.asset widget with the ColorFiltered widget. This will still achieve the same results as above.

Home.dart

return Scaffold(
  body: Center(
    child: ColorFiltered(
      colorFilter: const ColorFilter.mode(Colors.red, BlendMode.srcIn),
      child: SvgPicture.asset(
        'assets/images/undraw_pancakes.svg',
        semanticsLabel: 'Sweet Pancakes',
        width: 200,
        height: 200,
      ),
    ),
  ),
);

Here is our result

However, this is a bit more flexible as you can wrap the ColorFIltered widget around most Widgets in flutter to apply a color to them.

It's a matter of preference really :)

GitHub Snippet


3.Flutter Shape Maker

When working with simpler SVGs such as icons, the ColorFiltered widget and the colorFilter attribute of the flutter_svg package work absolutely great!

However, more complex SVGs like the one we are working with require a more fine-tuned approach to achieve beautiful results. That's where Flutter Shape Maker comes into play!!

hmm...What is Flutter Shape Maker??

Well, to answer this... Remember that one time you tried making a custom shape using Flutter's canvas and CustomPaint class and you ended up wondering how the lines and bezier curves all connect to form a nice image?

Yeah, I remember crying too. The feeling is mutual :)

Flutter Shape Maker helps you Auto-Generate Responsive code for Flutter Custom Paint Widget directly from Canvas or SVGs.

Setup

Flutter Shape Maker Website

Firstly, visit the Flutter Shape Maker website and click on the icon on the top right to start generating Custom Paint code from your SVG image.

Click on the SVG To Custom Paint <> button to open a popup window to help you import your SVG image.

Import SVG Image

Click on Pick SVG File button at the bottom left to pick your SVG image.

Click on Generate Code and make sure to make it Responsive for the best results :)

Finally, you can copy the Generated code and paste it into your Flutter code as shown below.

Custom Paint Class

In our Flutter code, copy the generated code in a new dart file. Below is just a snippet of the generated class.

Here is the full code of the custom paint class:

GitHub Snippet

Home.dart

Next, let's create our custom paint widget and call this class to get our SVG image.

return Scaffold(
  body: Container(
    width: double.infinity,
    height: double.infinity,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        CustomPaint(
          size: Size(WIDTH, (WIDTH * 0.7894034777284248).toDouble()),
          painter: FlutterShapeMakerCustomPaint(),
        ),
        const SizedBox(height: 24),
        const Text("SVG Using Canvas")
      ],
    ),
  ),
);

Notice how the Custom Paint widget has placeholders for the Widths? DO NOT modify the weird looking double digit since this is what Flutter Shape Maker uses to calculate the height of the SVG image!

As the Custom Paint widget code is also generated by Flutter Shape Maker, the double value will vary depending on the image. Mine is unique to the SVG image I used.

With this in mind, we are only changing the width of our SVG. from this.

CustomPaint(
   size: Size(WIDTH, (WIDTH * 0.7894034777284248).toDouble()),
   painter: FlutterShapeMakerCustomPaint(),
),

To this.

CustomPaint(
   size: Size(250, (250 * 0.7894034777284248).toDouble()),
   painter: FlutterShapeMakerCustomPaint(),
),

Changing SVG Color

The custom paint class is flexible enough to allow us modify only specific parts of our SVG.

To do this:

Go to the custom paint class and find parts in the code with a line like this that contains the colour you would like to modify:

For this example, any part of the code that contains this piece of code with the colour property set to 0xff6c63ff, will be changed to Colors.red

This is the now modified code:

Make sure to do this for all occurrences of the colors to achieve the desired effect.

Here is our final result. Isn't it just crazy how cool this looks?


4. SVG + Shader Mask

Congrats, you made it to this point! It only gets cooler!!

So far we have seen how to add single solid colors to an SVG. However, one may ask, what of Gradient colors? Well, that's the work of a Shader Mask widget in Flutter

We shall use the Shader Mask Widget to add a gradient to our pancakes SVG and make them look even more delicious!

Home.dart

ShaderMask(
  shaderCallback: (bounds) {
    return const LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: [Colors.red, Colors.blue]).createShader(bounds);
  },
  child: SvgPicture.asset(
    'assets/images/undraw_pancakes.svg',
    semanticsLabel: 'Sweet Pancakes',
    width: 200,
    height: 200,
  ),
)

The ShaderMask comes with the following properties:

  1. shaderCallback - Where we can return our gradient that we want to apply to our image e.g SweepGradient, LinearGradient and RadialGradient .

  2. bounds - The bounds property is used to help determine the size constraints of the child which we want to apply the gradient to. in this case, our SVG has the width and height of 200.

  3. createShader - This method created a shader from our gradient and passes it to the shaderCallback.

  4. child - This is the widget you would like to apply the gradient to. It could be any widget not necessarily SVGs only.

For a more in-depth understanding of the Shader Mask widget, read this Medium Article.

Result

Yes, I was amazed myself :)


Conclusion

There you go, here are the multiple ways of working and styling SVG images in your Flutter application. Each method has is advantages and disadvantages so it all trickles down to your own personal preference.

Feel free to leave a comment on what other cool way we can use to style our SVGs. It's never one way!

Stay safe, and thanks for reading :)

Here is the full code:

GitHub SVG Styling