How to Color Specific Parts of SVG Image using Flutter and flutter_svg?

224 Views Asked by At

I am developing a Flutter application where I need to display a human body silhouette with muscles, and I want users to dynamically color specific muscles based on their input. I am using the flutter_svg package to work with SVG images.

Here is a simplified version of the SVG representing the human body silhouette:

 <path
         id="muscle1"
         style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
         d="M 5000,0 H 0 V 5000 H 5000 V 0" />

and more like this.

In my Flutter app, I want to use SvgPicture to display this SVG image, and I want users to select a muscle (identified by its unique ID, e.g., "muscle1") and choose a color to fill that specific muscle.

I have considered using the SvgPicture.string method and applying color filters, but I'm uncertain about the best approach for dynamically coloring specific parts of the SVG.

Could someone provide guidance on how to achieve this in Flutter using the flutter_svg package? What is the recommended way to dynamically color specific muscles in a human body silhouette SVG based on user input?

Thank you for your assistance!


1

There are 1 best solutions below

0
KeroJohn97 On

Just modify the content of your SVG file

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  Color _color = Colors.red;
  String svgContent = '';

  @override
  void initState() {
    super.initState();
    loadSvgFromAsset();
  }

  Future<void> loadSvgFromAsset() async {
    String svgAssetPath = 'assets/images/winter_city.svg';

    // Read SVG content from asset file
    String rawSvgContent = await rootBundle.loadString(svgAssetPath);

    // Modify SVG content
    String modifiedSvgContent = modifySvgContent(rawSvgContent);

    // Display the new file
    setState(() {
      svgContent = modifiedSvgContent;
    });
  }

  String modifySvgContent(String rawSvgContent) {
    final int abc = Random().nextInt(5);
    switch (abc) {
      case 0:
        _color = Colors.red;
        break;
      case 1:
        _color = Colors.orange;
        break;
      case 2:
        _color = Colors.yellow;
        break;
      case 3:
        _color = Colors.green;
        break;
      case 4:
        _color = Colors.blue;
        break;
    }
    rawSvgContent = rawSvgContent.replaceAll('fill="#86F5FE"',
        'fill="#${_color.value.toRadixString(16).substring(2)}"');
    return rawSvgContent;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('SVG Modification Example'),
      ),
      body: Center(
        child: svgContent.isEmpty
            ? const CircularProgressIndicator()
            : SvgPicture.string(svgContent),
      ),
    );
  }
}