你如何在 Flutter Web 上使用 SVG?
How do you use SVG's on Flutter Web?
flutter_web docos 说 dart:svg 已移植,但如何将其与 flutter 资产/小部件系统一起使用?
老实说,我找到的最佳解决方案是通过网络为网络加载图像。将资产存储在某个 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(),
),
);
}
}
}
@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')
我的 Flutter 网络应用程序会在桌面网络浏览器中呈现 SVG,但不会使用 flutter_svg 在移动网络浏览器中呈现。我发现有必要构建 canvaskit 支持,以便 SVG 在移动设备上呈现:
flutter build web --web-renderer canvaskit
但是,docs 指出 canvaskit 增加了大约 2MB 的下载大小,这对我来说是一个破坏因素。很遗憾,但在解决此问题之前我将使用光栅图像。
@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));
flutter_svg 版本 1.0.0 于 2021 年 12 月 2 日发布,包括网络支持。因此不再有在 Flutter 项目中使用 svg 图像的障碍。
flutter_web docos 说 dart:svg 已移植,但如何将其与 flutter 资产/小部件系统一起使用?
老实说,我找到的最佳解决方案是通过网络为网络加载图像。将资产存储在某个 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(),
),
);
}
}
}
@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')
我的 Flutter 网络应用程序会在桌面网络浏览器中呈现 SVG,但不会使用 flutter_svg 在移动网络浏览器中呈现。我发现有必要构建 canvaskit 支持,以便 SVG 在移动设备上呈现:
flutter build web --web-renderer canvaskit
但是,docs 指出 canvaskit 增加了大约 2MB 的下载大小,这对我来说是一个破坏因素。很遗憾,但在解决此问题之前我将使用光栅图像。
@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));
flutter_svg 版本 1.0.0 于 2021 年 12 月 2 日发布,包括网络支持。因此不再有在 Flutter 项目中使用 svg 图像的障碍。