Skip to content

[flutter_svg] Change colors for multi color svg #158634

@stuartmorgan-g

Description

@stuartmorgan-g

Imported from dnfield/flutter_svg#372

Original report by @Tonku on Jun 30, 2020

Thanks for the awesome library first!.

I was wondering how can I change colours for a multi color svg for individual segments? Currently only one color is supported.

Thanks


Comment by @Tonku on Jun 30, 2020
See this website, they can change the color of svg
https://undraw.co/illustrations
how can I achieve that in flutter_svg


Comment by @RussellZornes on Jul 19, 2020
You have style css support listed as out of scope.

I hope you will consider at least supporting color styles as shown below. I have a bunch of svgs that are multi-color and the plugin renders them mono-colored. This is blocker for my use of this plugin and I've needed to revert all my svgs back to png 😩

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
<style type="text/css">
	.st0{fill:#333333;}
	.st1{fill:#9AC70A;}
</style>
<g>
	<path class="st0" d="M923.34,449.13v313.23c-58.44-10.63-105.78-53.08-123.25-108.69c-0.08-0.32-0.25-0.63-0.32-0.95
		c-4.57-14.88-7.09-30.63-7.09-47.02c0-16.31,2.52-32.13,7.09-47.02c0.16-0.47,0.32-0.95,0.47-1.42
		c11.03-34.5,33.48-63.95,63.01-83.72c6-4.02,12.21-7.64,18.75-10.87C894.91,456.38,908.77,451.81,923.34,449.13z"/>
	<polygon class="st1" points="744.84,426.1 588.97,471.85 438.61,515.96 198.01,586.53 188.24,553.13 174.34,505.64 182.74,505.17 
		182.81,505.17 296.54,498.86 728.93,372.06 727.9,368.52 	"/>
</g>
</svg>

Comment by @Tonku on Jul 27, 2020
I think probably extract the paths of SVG and convert that to flutter paths and render ?


Comment by @dnfield on Jul 31, 2020
Supporting CSS is, quite frankly, a nightmare and a full time job. It is generally possible to preprocess any CSS away as well.

For the original request of this bug, I don't have any plans to support this but would be open to reviewing patches that added it in some reasonable way. However, in general you should be able to work with the Drawable* classes and transform the styles on them to your liking. It might be easier to do so if we surfaced some ID property on them that corresponded to the id attribute on elements.


Comment by @Tonku on Aug 5, 2020
@dnfield that's what I wanted.. can you suggest a recommended way to hook the style of Drawable* class from outside of flutter_svg ? that's from my own code?


Comment by @dnfield on Aug 5, 2020
From the readme:

import 'package:flutter_svg/flutter_svg.dart';
final String rawSvg = '''...''';
final DrawableRoot svgRoot = await svg.fromSvgString(rawSvg, rawSvg);

// If you only want the final Picture output, just use
final Picture picture = svgRoot.toPicture();

// Otherwise, if you want to draw it to a canvas:
// Optional, but probably normally desirable: scale the canvas dimensions to
// the SVG's viewbox
svgRoot.scaleCanvasToViewBox(canvas);

// Optional, but probably normally desireable: ensure the SVG isn't rendered
// outside of the viewbox bounds
svgRoot.clipCanvasToViewBox(canvas);
svgRoot.draw(canvas, size);


Comment by @Tonku on Aug 15, 2020
Thanks so much


Comment by @rgb1380 on Nov 11, 2020

// outside of the viewbox bounds
svgRoot.clipCanvasToViewBox(canvas);
svgRoot.draw(canvas, size);

Hi, fantastic lib, thanks heaps.

Quick question, I am using svgRoot.draw() and it draws the svg in black. How do we change the color to something else?


Comment by @gimmixAT on Jul 26, 2021
We also came across this issue and solved it for now by loading the svg's markup directly from the DefaultAssetBundle and preprocess it by replacing the color code that should be changed. So you just have to make sure that the fill / stroke is set correctly in your svg. Especially if you want to replace black because many svg optimizers will remove that since it is the svg internal default color.

class Icon extends StatelessWidget {

  Icon(this.icon, {this.color = Colors.black});
  final String icon;
  final Color color;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: DefaultAssetBundle.of(context).loadString("assets/icons/" + icon + ".svg"),
      builder: (context, snapshot) {
        return SvgPicture.string(
          (snapshot.data ?? "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1 1\"></svg>")
            .replaceAll("#000000", '#${this.color.value.toRadixString(16).padLeft(6, '0').toUpperCase()}'),
          width: 32,
        );
      }
    );
  }
}

Comment by @Zujaj on May 17, 2022

See this website, they can change the color of svg https://undraw.co/illustrations how can I achieve that in flutter_svg

Do you mean something like this? I call it SVG colorization.

This is an image

This tutorial can help to solve your issue. Not only does it changes the color, but also allows the user to download the manipulated SVG code.


Comment by @ultraon on Jan 27, 2023
Found great answer here https://stackoverflow.com/questions/73034225/flutter-svg-gradient-is-not-rendered-failed-to-find-definition-for-url :
Just move <def> block to the top (just under <svg> element.


Comment by @Chonli on Jul 6, 2023
You can create a custom ColorMapper supported many colors (see dnfield/flutter_svg#856 (comment))
And juste use it in

SvgPicture(
      SvgAssetLoader(
        path,
        colorMapper: MyColorMapper(
          primaryColor: primaryColor,
          secondaryColor: secondaryColor,
        ),
      ),

Comment by @Sumit258000 on Sep 21, 2023

SVG colorization

What if we want to change color of particular classes in svg depending upon user selection? is there any short usefull function for that or the only possibility is searching class in long svg string and than change fill property? @Zujaj @dnfield


Comment by @Zujaj on Sep 21, 2023

SVG colorization

What if we want to change color of particular classes in svg depending upon user selection? is there any short usefull function for that or the only possibility is searching class in long svg string and than change fill property? @Zujaj @dnfield

Can you provide any working example?


Comment by @Sumit258000 on Sep 21, 2023
Thanks for your message but I found the workaround by setting condition and changing color dynamically something like this.
<g id="Mask_Group_533" data-name="Midfield" transform="translate(193.433 1654.703)" clip-path="url(#clip-path)"> <g id="Group_19878" data-name="Group 19878"> <ellipse id="Ellipse_1188" data-name="Ellipse 1188" cx="8.215" cy="8.215" rx="8.215" ry="8.215" fill='${position == "Midfield" ? "#3968FF" : "#b2b2b2"}' /> </g> </g>
By this I am able to change color separately in full svg string depending upon condition.


Comment by @RahaKmi on Jan 25, 2024
Widget build(BuildContext context) {

return FutureBuilder<String>(
    future: DefaultAssetBundle.of(context).loadString("packages/../assets/icons/${svgIcon.assetName}"),
    builder: (context, snapshot) {
      final String svgContent = snapshot.data ?? '';
      final String modifiedSvgContent = svgContent.replaceAll('#4e737a', Theme.of(context).primaryColor.toHexColor())
      .replaceAll('#f19926', 'red');
      return SvgPicture.string(
        modifiedSvgContent,
        height: size,
        width: size,
      );
    },
);

}

extension ColorHex on Color {
String toHexColor() {
return '#${value.toRadixString(16).substring(2)}';
}
}


Comment by @RahaKmi on Jan 25, 2024
enum MyIcons {
icon1(assetName: "icon1.svg"),
icon2(assetName: "icon2.svg"),

const MyIcons ({required this.assetName});

final String assetName;
}

class MyIcons extends Icon {
final MyIcons svgIcon;

const MyIcons (
this.svgIcon, {
super.key,
super.size = 24.0,
}) : super(null);

Metadata

Metadata

Assignees

No one assigned

    Labels

    p: flutter_svgThe Flutter SVG drawing packagespackageflutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions