如何在Flutter Web中使用SVG?

14
Flutter_web文档中提到了dart:svg被移植了,但是如何在flutter资产/小部件系统中使用呢?

2
我不知道如何使用dart:svg,但我创建了一个示例项目,使用HtmlElementView在移动设备和Web上显示svg:https://github.com/masewo/flutter_svg_web_example - masewo
1
flutter_svg是一个选项,但它只适用于Android/iOS,websafe_svg也适用于Web,但在Firefox上的效果不如预期。 - silexcorp
1
看起来websafe_svg中的Firefox问题最近已经得到解决,现在可以安全使用它了。https://github.com/peiffer-innovations/websafe_svg/issues/7 - Andrei Aulaska
5个回答

16

说实话,我发现最好的解决办法是通过网络加载图像。在CDN上存储资产,在Web版中从CDN获取它,并在iOS / Android上从本地资产中检索它。

我使用这个库创建了一个CrossPlatformSvg小部件:https://pub.dev/packages/flutter_svg,类似于:

class CrossPlatformSvg {
  static Widget asset(
    String assetPath, {
    double width,
    double height,
    BoxFit fit = BoxFit.contain,
    Color color,
    alignment = Alignment.center,
    String semanticsLabel,
  }) {
    // `kIsWeb` is a special Flutter variable that just exists
    // Returns true if we're on web, false for mobile
    if (kIsWeb) {
      return Image.network(
        assetPath,
        width: width,
        height: height,
        fit: fit,
        color: color,
        alignment: alignment,
      );
    } else {
      return SvgPicture.network(
        assetPath,
        width: width,
        height: height,
        fit: fit,
        color: color,
        alignment: alignment,
        placeholderBuilder: (_) => Container(
          width: 30,
          height: 30,
          padding: EdgeInsets.all(30),
          child: CircularIndicator(),
        ),
      );
    }
  }
}


5
即使将您的SVG置于资产目录下并调用Image.network,它也能正常工作。 - atereshkov
2
在 Web 上以调试模式运行时,我遇到了以下错误。因此我认为 Image.network 不支持 SVG。已在 1.26.0-8.0.pre • channel dev 进行测试。 解析图像编解码器时抛出了以下 ImageCodecException: 无法解码图像数据。 - Gpack
2
Flutter似乎放弃了对SVG的支持,请参见:https://github.com/flutter/flutter/issues/74489 - jeiea

8

@aterenshkov的方法对我很有效(请参阅Jack答案下方的评论)。以下是实现细节...

iOS/Android

child: SvgPicture.asset('assets/yourimage.svg')

网络

// remove assets folder reference
child: SvgPicture.asset('yourimage.svg')

将这两者合并在一起...

import 'package:flutter/foundation.dart'; // provides kIsWeb property
...
child: kIsWeb ? SvgPicture.asset('yourimage.svg') : SvgPicture.asset('assets/yourimage.svg')

5

我的Flutter Web应用程序可以在桌面Web浏览器中呈现SVG,但在移动Web浏览器中不能使用 flutter_svg。我发现必须构建Canvaskit支持,才能使SVG在移动设备上呈现:

flutter build web --web-renderer canvaskit

然而,文档指出Canvaskit会增加大约2MB的下载大小,这对我来说是个致命伤。很遗憾,直到这个问题得以解决之前,我将使用光栅图像。

2
自2021年12月2日起,flutter_svg版本1.0.0已发布,其中包括Web支持。因此,在Flutter项目中使用SVG图像不再受阻。请注意保留HTML标签。

1

@RumbleFish的代码虽然使用三元操作符很好,但是在许多情况下会使代码变得混乱。

我的解决方法是:

  • 创建一个字符串扩展函数,用于替换路径中的assets/
extension ForWeb on String {
  String forWeb({required bool web}) => web ? this.replaceFirst('assets/','') : this;
}
  • 现在的代码:

SvgPicture.asset("assets/images/logo.png".forWeb(web: kIsWeb));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接