Skip to content

Use .vec SVG class for vector_graphics_compiler transformed assets #685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,10 @@ flutter:
- assets/images/
- assets/images/chip3/chip.jpg
- assets/images/chip4/chip.jpg
- assets/images/icons/paint.svg
- path: assets/images/icons/paint.svg
- path: assets/images/icons/transformed.svg
transformers:
- package: vector_graphics_compiler
- assets/images/icons/[email protected]
- assets/json/fruits.json
- assets/flare/Penguin.flr
Expand Down Expand Up @@ -380,7 +383,7 @@ flutter_gen:
image: false
```

If you are using SVG images with [flutter_svg](https://pub.dev/packages/flutter_svg) you can use the integration feature.
If you are using SVG images with [flutter_svg](https://pub.dev/packages/flutter_svg) you can use the integration feature. This feature also supports using `vector_graphics_compiler` transformer and the produced code will use the `AssetBytesLoader` for such transformed assets.

```yaml
# pubspec.yaml
Expand All @@ -391,6 +394,9 @@ flutter_gen:
flutter:
assets:
- assets/images/icons/paint.svg
- path: assets/images/icons/transformed.svg
transformers:
- package: vector_graphics_compiler
```

```dart
Expand Down
40 changes: 32 additions & 8 deletions packages/core/lib/generators/assets_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,32 +176,45 @@ List<FlavoredAsset> _getAssetRelativePathList(
) {
// Normalize.
final normalizedAssets = <Object>{...assets.whereType<String>()};
final normalizingMap = <String, Set<String>>{};
// Resolve flavored assets.
final normalizingMap =
<String, ({Set<String> flavors, Set<String> transformers})>{};
// Resolve flavored or transformed assets.
for (final map in assets.whereType<YamlMap>()) {
final path = (map['path'] as String).trim();
final flavors =
(map['flavors'] as YamlList?)?.toSet().cast<String>() ?? <String>{};
final transformers = (map['transformers'] as YamlList?)
?.map(((t) => (t as YamlMap)['package'] as String))
.toSet() ??
{};
if (normalizingMap.containsKey(path)) {
// https://github.com/flutter/flutter/blob/5187cab7bdd434ca74abb45895d17e9fa553678a/packages/flutter_tools/lib/src/asset.dart#L1137-L1139
throw StateError(
'Multiple assets entries include the file "$path", '
'but they specify different lists of flavors.',
'but they specify different lists of flavors or transformers.',
);
}
normalizingMap[path] = flavors;
normalizingMap[path] = (flavors: flavors, transformers: transformers);
}
for (final entry in normalizingMap.entries) {
normalizedAssets.add(
YamlMap.wrap({'path': entry.key, 'flavors': entry.value}),
YamlMap.wrap({
'path': entry.key,
'flavors': entry.value.flavors,
'transformers': entry.value.transformers,
}),
);
}

final assetRelativePathList = <FlavoredAsset>[];
for (final asset in normalizedAssets) {
final FlavoredAsset tempAsset;
if (asset is YamlMap) {
tempAsset = FlavoredAsset(path: asset['path'], flavors: asset['flavors']);
tempAsset = FlavoredAsset(
path: asset['path'],
flavors: asset['flavors'],
transformers: asset['transformers'],
);
} else {
tempAsset = FlavoredAsset(path: (asset as String).trim());
}
Expand Down Expand Up @@ -238,14 +251,24 @@ AssetType _constructAssetTree(
) {
// Relative path is the key
final assetTypeMap = <String, AssetType>{
'.': AssetType(rootPath: rootPath, path: '.', flavors: {}),
'.': AssetType(
rootPath: rootPath,
path: '.',
flavors: {},
transformers: {},
),
};
for (final asset in assetRelativePathList) {
String path = asset.path;
while (path != '.') {
assetTypeMap.putIfAbsent(
path,
() => AssetType(rootPath: rootPath, path: path, flavors: asset.flavors),
() => AssetType(
rootPath: rootPath,
path: path,
flavors: asset.flavors,
transformers: asset.transformers,
),
);
path = dirname(path);
}
Expand Down Expand Up @@ -462,6 +485,7 @@ Future<String> _flatStyleDefinition(
rootPath: config.rootPath,
path: assetPath.path,
flavors: assetPath.flavors,
transformers: assetPath.transformers,
),
)
.mapToUniqueAssetType(style)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,15 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''}
@override
String get className => 'SvgGenImage';

static const vectorCompileTransformer = 'vector_graphics_compiler';

@override
String classInstantiate(AssetType asset) {
// Query extra information about the SVG.
final info = parseMetadata ? _getMetadata(asset) : null;
final buffer = StringBuffer(className);
if (asset.extension == '.vec') {
if (asset.extension == '.vec' ||
asset.transformers.contains(vectorCompileTransformer)) {
buffer.write('.vec');
}
buffer.write('(');
Expand Down
10 changes: 8 additions & 2 deletions packages/core/lib/settings/asset_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ class AssetType {
required this.rootPath,
required this.path,
required this.flavors,
required this.transformers,
});

final String rootPath;
final String path;
final Set<String> flavors;
final Set<String> transformers;

final List<AssetType> _children = List.empty(growable: true);
late final children = _children.sortedBy((e) => e.path);
Expand Down Expand Up @@ -55,7 +57,8 @@ class AssetType {
String toString() => 'AssetType('
'rootPath: $rootPath, '
'path: $path, '
'flavors: $flavors'
'flavors: $flavors, '
'transformers: $transformers'
')';
}

Expand All @@ -74,6 +77,7 @@ class UniqueAssetType extends AssetType {
rootPath: assetType.rootPath,
path: assetType.path,
flavors: assetType.flavors,
transformers: assetType.transformers,
);

/// Convert the asset name to a correctly styled name, e.g camelCase or
Expand Down Expand Up @@ -113,7 +117,9 @@ class UniqueAssetType extends AssetType {
'path: $path, '
'style: $style, '
'needExtension: $needExtension, '
'suffix: $suffix}';
'suffix: $suffix, '
'flavors: $flavors, '
'transformers: $transformers}';
}
}

Expand Down
12 changes: 10 additions & 2 deletions packages/core/lib/settings/flavored_asset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@ class FlavoredAsset {
const FlavoredAsset({
required this.path,
this.flavors = const {},
this.transformers = const {},
});

final String path;
final Set<String> flavors;
final Set<String> transformers;

FlavoredAsset copyWith({String? path, Set<String>? flavors}) {
FlavoredAsset copyWith({
String? path,
Set<String>? flavors,
Set<String>? transformers,
}) {
return FlavoredAsset(
path: path ?? this.path,
flavors: flavors ?? this.flavors,
transformers: transformers ?? this.transformers,
);
}

@override
String toString() => 'FlavoredAsset(path: $path, flavors: $flavors)';
String toString() =>
'FlavoredAsset(path: $path, flavors: $flavors, transformers: $transformers)';
}
63 changes: 62 additions & 1 deletion packages/core/test/assets_gen_integrations_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ void main() {
test('Integration.classInstantiate', () {
expect(
TestIntegration().classInstantiate(
AssetType(rootPath: resPath, path: 'assets/path', flavors: {'test'}),
AssetType(
rootPath: resPath,
path: 'assets/path',
flavors: {'test'},
transformers: {},
),
),
'TestIntegration(\'assets/path\', flavors: {\'test\'},)',
);
Expand All @@ -63,6 +68,7 @@ void main() {
rootPath: resPath,
path: 'assets/path',
flavors: {},
transformers: {},
),
),
'SvgGenImage(\'assets/path\')',
Expand All @@ -73,26 +79,62 @@ void main() {
rootPath: resPath,
path: 'assets/path',
flavors: {'test'},
transformers: {},
),
),
'SvgGenImage(\'assets/path\', flavors: {\'test\'},)',
);
expect(
integration.classInstantiate(
AssetType(
rootPath: resPath,
path: 'assets/path/dog.svg',
flavors: {},
transformers: {},
),
),
'SvgGenImage(\'assets/path/dog.svg\')',
);
expect(
integration.classInstantiate(
AssetType(
rootPath: resPath,
path: 'assets/path/dog.vec',
flavors: {},
transformers: {},
),
),
'SvgGenImage.vec(\'assets/path/dog.vec\')',
);
expect(
integration.classInstantiate(
AssetType(
rootPath: resPath,
path: 'assets/path/dog.svg',
flavors: {},
transformers: {'test'},
),
),
'SvgGenImage(\'assets/path/dog.svg\')',
);
expect(
integration.classInstantiate(
AssetType(
rootPath: resPath,
path: 'assets/path/dog.svg',
flavors: {},
transformers: {'vector_graphics_compiler'},
),
),
'SvgGenImage.vec(\'assets/path/dog.svg\')',
);
expect(
integration.isSupport(
AssetType(
rootPath: resPath,
path: 'assets/path/dog.svg',
flavors: {},
transformers: {},
),
),
isTrue,
Expand All @@ -103,6 +145,18 @@ void main() {
rootPath: resPath,
path: 'assets/path/dog.vec',
flavors: {},
transformers: {},
),
),
isTrue,
);
expect(
integration.isSupport(
AssetType(
rootPath: resPath,
path: 'assets/path/dog.svg',
flavors: {},
transformers: {'test'},
),
),
isTrue,
Expand All @@ -113,6 +167,7 @@ void main() {
rootPath: resPath,
path: 'assets/path/dog.png',
flavors: {},
transformers: {},
),
),
isFalse,
Expand Down Expand Up @@ -147,6 +202,7 @@ void main() {
rootPath: resPath,
path: 'assets/path',
flavors: {},
transformers: {},
),
),
'RiveGenImage(\'assets/path\')',
Expand All @@ -157,6 +213,7 @@ void main() {
rootPath: resPath,
path: 'assets/path/dog.riv',
flavors: {},
transformers: {},
),
),
isTrue,
Expand All @@ -167,6 +224,7 @@ void main() {
rootPath: resPath,
path: 'assets/path/dog.json',
flavors: {},
transformers: {},
),
),
isFalse,
Expand Down Expand Up @@ -194,6 +252,7 @@ void main() {
rootPath: resPath,
path: 'assets/lottie',
flavors: {},
transformers: {},
),
),
'LottieGenImage(\'assets/lottie\')',
Expand All @@ -204,6 +263,7 @@ void main() {
rootPath: resPath,
path: 'assets/lottie/hamburger_arrow.json',
flavors: {},
transformers: {},
),
),
isTrue,
Expand All @@ -214,6 +274,7 @@ void main() {
rootPath: resPath,
path: 'assets/lottie/hamburger_arrow_without_version.json',
flavors: {},
transformers: {},
),
),
isFalse,
Expand Down
9 changes: 8 additions & 1 deletion packages/core/test/assets_gen_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,14 @@ void main() {

final List<AssetType> assets = tests.keys
.sorted()
.map((e) => AssetType(rootPath: '', path: e, flavors: {}))
.map(
(e) => AssetType(
rootPath: '',
path: e,
flavors: {},
transformers: {},
),
)
.toList();

final got = assets.mapToUniqueAssetType(camelCase);
Expand Down
Loading
Loading