最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Color filter does not work in flutter web iOS - Safari - Stack Overflow

programmeradmin2浏览0评论

I use flutter_svg on my flutter project, and i have a function which return the SvgPicture Widget with a specific color:

static Widget icon({double? width, double? height, Color? color}) {
    return SvgPicture.asset(
      'assets/icon.svg',
      width: width,
      height: height,
      colorFilter:
          color != null ? ColorFilter.mode(color, BlendMode.srcIn) : null,
    );
}

It works great on other platforms but only on Iphone - Safari browser, when rendering with html, the color option does not work. The issue is not with flutter, package or html. The Safari does not support the color filter as mentioned here.

How to make it work?

Edit

This issue appears to be on Android - Firefox too.

I use flutter_svg on my flutter project, and i have a function which return the SvgPicture Widget with a specific color:

static Widget icon({double? width, double? height, Color? color}) {
    return SvgPicture.asset(
      'assets/icon.svg',
      width: width,
      height: height,
      colorFilter:
          color != null ? ColorFilter.mode(color, BlendMode.srcIn) : null,
    );
}

It works great on other platforms but only on Iphone - Safari browser, when rendering with html, the color option does not work. The issue is not with flutter, package or html. The Safari does not support the color filter as mentioned here.

How to make it work?

Edit

This issue appears to be on Android - Firefox too.

Share Improve this question edited Mar 20 at 7:28 VLAZ 29.1k9 gold badges63 silver badges84 bronze badges asked Mar 17 at 20:25 MahseinMahsein 1729 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Solutions

CanvasKit

use CanvasKit for rendering web: flutter build web --web-renderer canvaskit

SvgPicture.string()

instead of using SvgPicture.asset(), load the svg as text, change the color, use SvgPicture.string(). but I suggest doing it only on Iphone - Safari. here is how:

import 'package:flutter/foundation.dart';
import 'dart:html' as html;

bool get isIosSafari {
  if (!kIsWeb) return false;
  final ua = html.window.navigator.userAgent.toLowerCase();
  final isIos = ua.contains('iphone') || ua.contains('ipad') || ua.contains('ipod');
  // Ensure it's Safari and not another browser on iOS (like Chrome or Firefox)
  final isSafari = ua.contains('safari') && !ua.contains('crios') && !ua.contains('fxios');
  return isIos && isSafari;
}
static Widget icon({double? width, double? height, Color? color}) {
  if (isIosSafari && color != null) {
    return FutureBuilder<String>(
      future: rootBundle.loadString('assets/icon.svg'),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
          String svgStr = snapshot.data!;
          final hexColor =
              '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}';
          svgStr = svgStr.replaceAll(RegExp(r'fill="[^"]*"'), 'fill="$hexColor"');
          return SvgPicture.string(svgStr, width: width, height: height);
        }
        // return empty box until ready
        return SizedBox(width: width, height: height);
      },
    );
  } else {
    return SvgPicture.asset(
      'assets/icon.svg',
      width: width,
      height: height,
      colorFilter: color != null ? ColorFilter.mode(color, BlendMode.srcIn) : null,
    );
  }
}

Edit

solution for Android - Firefox is the same (but obviously the isIosSafari part is going to change).

发布评论

评论列表(0)

  1. 暂无评论