Skip to content

Commit 9e10a6e

Browse files
wasabeefnova8yte
andauthored
Add Lottie integration (#298)
* Add lottie integration * example & test asset * auto strip "lottie" from final asset var name * Update README.md * Update lottie integration * dropped support for '*_lottie.json' per #70 PR * include root path for tests * update example * set: min lottie version * rename resourcesPath for better code readability * fix: version must be equals or more than 4.4.0 * fix merge * support semver * change custom semver to pub_sem_ver * chore: add some usecases files * refactor: change to named constructor * test: add wrong test case Co-authored-by: Alexandra Kovaleva <[email protected]>
1 parent 7735309 commit 9e10a6e

22 files changed

+496
-16
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ flutter_gen:
124124
flutter_svg: true
125125
flare_flutter: true
126126
rive: true
127+
lottie: true
127128

128129
colors:
129130
inputs:
@@ -225,6 +226,8 @@ Widget build(BuildContext context) {
225226
|[flutter_svg](https://pub.dev/packages/flutter_svg)|.svg| `flutter_svg: true` |Assets.images.icons.paint.**svg()**|
226227
|[flare_flutter](https://pub.dev/packages/flare_flutter)|.flr| `flare_flutter: true` |Assets.flare.penguin.**flare()**|
227228
|[rive](https://pub.dev/packages/rive)|.flr| `rive: true` |Assets.rive.vehicles.**rive()**|
229+
|[lottie](https://pub.dev/packages/lottie)|_lottie.json| `lottie: true` |Assets.lottie.hamburgerArrow.**lottie()**|
230+
228231

229232
<br/>
230233

@@ -725,6 +728,7 @@ flutter_gen:
725728
flutter_svg: false
726729
flare_flutter: false
727730
rive: false
731+
lottie: false
728732
729733
assets:
730734
# Optional

example/assets/lottie/alarm-clock-lottie-v440.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

example/assets/lottie/geometrical-animation.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"assets":[],"layers":[{"ddd":0,"ind":0,"ty":3,"nm":"Rotator","ks":{"o":{"k":0},"r":{"k":[{"i":{"x":[0.56],"y":[1]},"o":{"x":[0.634],"y":[0]},"n":["0p56_1_0p634_0"],"t":19,"s":[0],"e":[190.7]},{"i":{"x":[0.562],"y":[1]},"o":{"x":[0.398],"y":[0]},"n":["0p562_1_0p398_0"],"t":33,"s":[190.7],"e":[176.1]},{"i":{"x":[0.684],"y":[1]},"o":{"x":[0.31],"y":[0]},"n":["0p684_1_0p31_0"],"t":40.5,"s":[176.1],"e":[181.8]},{"i":{"x":[0.684],"y":[1]},"o":{"x":[0.438],"y":[0]},"n":["0p684_1_0p438_0"],"t":55,"s":[181.8],"e":[180]},{"i":{"x":[0.733],"y":[0.733]},"o":{"x":[0.385],"y":[0.385]},"n":["0p733_0p733_0p385_0p385"],"t":71,"s":[180],"e":[180]},{"i":{"x":[0.092],"y":[1]},"o":{"x":[0.406],"y":[0]},"n":["0p092_1_0p406_0"],"t":111,"s":[180],"e":[167.9]},{"i":{"x":[0.341],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p341_1_0p6_0"],"t":116,"s":[167.9],"e":[363]},{"i":{"x":[0.462],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p462_1_0p167_0"],"t":134,"s":[363],"e":[360]},{"t":141}]},"p":{"k":[200.5,149.375,0]},"a":{"k":[60,60,0]},"s":{"k":[100,100,100]}},"ao":0,"ip":0,"op":180,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"A1","parent":0,"ks":{"o":{"k":100},"r":{"k":[{"i":{"x":[0.56],"y":[1]},"o":{"x":[0.634],"y":[0]},"n":["0p56_1_0p634_0"],"t":19,"s":[0],"e":[-45]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[-45],"e":[-45]},{"i":{"x":[0.341],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p341_1_0p6_0"],"t":116,"s":[-45],"e":[0]},{"t":134}]},"p":{"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.634,"y":0},"n":"0p56_1_0p634_0","t":19,"s":[94.5,82.875,0],"e":[96.2,57.055,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":33,"s":[96.2,57.055,0],"e":[96.2,57.055,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.341,"y":1},"o":{"x":0.6,"y":0},"n":"0p341_1_0p6_0","t":116,"s":[96.2,57.055,0],"e":[94.5,82.875,0],"to":[0,0,0],"ti":[0,0,0]},{"t":134}]},"a":{"k":[35,22.25,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,22.25],[35,22.25]],"c":false}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.4,0.16,0.7,1]},"o":{"k":100},"w":{"k":10},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1"},{"ty":"tm","s":{"k":[{"i":{"x":[0.56],"y":[1]},"o":{"x":[0.634],"y":[0]},"n":["0p56_1_0p634_0"],"t":19,"s":[0],"e":[26]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[26],"e":[26]},{"i":{"x":[0.341],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p341_1_0p6_0"],"t":116,"s":[26],"e":[0]},{"t":134}],"ix":1},"e":{"k":[{"i":{"x":[0.56],"y":[0.56]},"o":{"x":[0.634],"y":[0.634]},"n":["0p56_0p56_0p634_0p634"],"t":19,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[100],"e":[100]},{"i":{"x":[0.341],"y":[0.341]},"o":{"x":[0.6],"y":[0.6]},"n":["0p341_0p341_0p6_0p6"],"t":116,"s":[100],"e":[100]},{"t":134}],"ix":2},"o":{"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1"}],"ip":0,"op":180,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"A2","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[60,60.625,0]},"a":{"k":[0.5,0,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,0],[35,0]],"c":false}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.4,0.16,0.7,1]},"o":{"k":100},"w":{"k":10},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1"}],"ip":0,"op":180,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"A3","parent":0,"ks":{"o":{"k":100},"r":{"k":[{"i":{"x":[0.56],"y":[1]},"o":{"x":[0.634],"y":[0]},"n":["0p56_1_0p634_0"],"t":19,"s":[0],"e":[45]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[45],"e":[45]},{"i":{"x":[0.341],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p341_1_0p6_0"],"t":116,"s":[45],"e":[0]},{"t":134}]},"p":{"k":[{"i":{"x":0.56,"y":1},"o":{"x":0.634,"y":0},"n":"0p56_1_0p634_0","t":19,"s":[94.5,37.125,0],"e":[96.2,64.045,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0,"y":0},"o":{"x":0.167,"y":0.167},"n":"0_0_0p167_0p167","t":33,"s":[96.2,64.045,0],"e":[96.2,64.045,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.341,"y":1},"o":{"x":0.6,"y":0},"n":"0p341_1_0p6_0","t":116,"s":[96.2,64.045,0],"e":[94.5,37.125,0],"to":[0,0,0],"ti":[0,0,0]},{"t":134}]},"a":{"k":[35,-23.5,0]},"s":{"k":[100,100,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-23.5],[35,-23.5]],"c":false}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.4,0.16,0.7,1]},"o":{"k":100},"w":{"k":10},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[0,0],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1"},{"ty":"tm","s":{"k":[{"i":{"x":[0.56],"y":[1]},"o":{"x":[0.634],"y":[0]},"n":["0p56_1_0p634_0"],"t":19,"s":[0],"e":[26]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[26],"e":[26]},{"i":{"x":[0.341],"y":[1]},"o":{"x":[0.6],"y":[0]},"n":["0p341_1_0p6_0"],"t":116,"s":[26],"e":[0]},{"t":134}],"ix":1},"e":{"k":[{"i":{"x":[0.56],"y":[0.56]},"o":{"x":[0.634],"y":[0.634]},"n":["0p56_0p56_0p634_0p634"],"t":19,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[100],"e":[100]},{"i":{"x":[0.341],"y":[0.341]},"o":{"x":[0.6],"y":[0.6]},"n":["0p341_0p341_0p6_0p6"],"t":116,"s":[100],"e":[100]},{"t":134}],"ix":2},"o":{"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1"}],"ip":0,"op":180,"st":0,"bm":0,"sr":1}],"v":"4.4.26","ddd":0,"ip":0,"op":180,"fr":30,"w":400,"h":300}

example/assets/lottie/wrong/rocket-lottie-v439.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

example/lib/gen/assets.gen.dart

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:flutter/services.dart';
1313
import 'package:flare_flutter/flare_actor.dart';
1414
import 'package:flare_flutter/flare_controller.dart';
1515
import 'package:rive/rive.dart';
16+
import 'package:lottie/lottie.dart';
1617

1718
class $AssetsFlareGen {
1819
const $AssetsFlareGen();
@@ -62,6 +63,28 @@ class $AssetsJsonGen {
6263
List<String> get values => [fruits];
6364
}
6465

66+
class $AssetsLottieGen {
67+
const $AssetsLottieGen();
68+
69+
/// File path: assets/lottie/alarm-clock-lottie-v440.json
70+
LottieGenImage get alarmClockLottieV440 =>
71+
const LottieGenImage('assets/lottie/alarm-clock-lottie-v440.json');
72+
73+
/// File path: assets/lottie/geometrical-animation.json
74+
LottieGenImage get geometricalAnimation =>
75+
const LottieGenImage('assets/lottie/geometrical-animation.json');
76+
77+
/// File path: assets/lottie/hamburger_arrow.json
78+
LottieGenImage get hamburgerArrow =>
79+
const LottieGenImage('assets/lottie/hamburger_arrow.json');
80+
81+
$AssetsLottieWrongGen get wrong => const $AssetsLottieWrongGen();
82+
83+
/// List of all assets
84+
List<LottieGenImage> get values =>
85+
[alarmClockLottieV440, geometricalAnimation, hamburgerArrow];
86+
}
87+
6588
class $AssetsMovieGen {
6689
const $AssetsMovieGen();
6790

@@ -130,12 +153,23 @@ class $AssetsImagesIconsGen {
130153
List<SvgGenImage> get values => [dartTest, fuchsia, kmm, paint];
131154
}
132155

156+
class $AssetsLottieWrongGen {
157+
const $AssetsLottieWrongGen();
158+
159+
/// File path: assets/lottie/wrong/rocket-lottie-v439.json
160+
String get rocketLottieV439 => 'assets/lottie/wrong/rocket-lottie-v439.json';
161+
162+
/// List of all assets
163+
List<String> get values => [rocketLottieV439];
164+
}
165+
133166
class MyAssets {
134167
MyAssets._();
135168

136169
static const $AssetsFlareGen flare = $AssetsFlareGen();
137170
static const $AssetsImagesGen images = $AssetsImagesGen();
138171
static const $AssetsJsonGen json = $AssetsJsonGen();
172+
static const $AssetsLottieGen lottie = $AssetsLottieGen();
139173
static const $AssetsMovieGen movie = $AssetsMovieGen();
140174
static const $AssetsRiveGen rive = $AssetsRiveGen();
141175
static const $AssetsUnknownGen unknown = $AssetsUnknownGen();
@@ -328,3 +362,59 @@ class RiveGenImage {
328362

329363
String get path => _assetName;
330364
}
365+
366+
class LottieGenImage {
367+
const LottieGenImage(this._assetName);
368+
369+
final String _assetName;
370+
371+
LottieBuilder lottie({
372+
Animation<double>? controller,
373+
bool? animate,
374+
FrameRate? frameRate,
375+
bool? repeat,
376+
bool? reverse,
377+
LottieDelegates? delegates,
378+
LottieOptions? options,
379+
void Function(LottieComposition)? onLoaded,
380+
LottieImageProviderFactory? imageProviderFactory,
381+
Key? key,
382+
AssetBundle? bundle,
383+
Widget Function(BuildContext, Widget, LottieComposition?)? frameBuilder,
384+
ImageErrorWidgetBuilder? errorBuilder,
385+
double? width,
386+
double? height,
387+
BoxFit? fit,
388+
AlignmentGeometry? alignment,
389+
String? package,
390+
bool? addRepaintBoundary,
391+
FilterQuality? filterQuality,
392+
void Function(String)? onWarning,
393+
}) {
394+
return Lottie.asset(
395+
_assetName,
396+
animate: animate,
397+
frameRate: frameRate,
398+
repeat: repeat,
399+
reverse: reverse,
400+
delegates: delegates,
401+
options: options,
402+
onLoaded: onLoaded,
403+
imageProviderFactory: imageProviderFactory,
404+
key: key,
405+
bundle: bundle,
406+
frameBuilder: frameBuilder,
407+
errorBuilder: errorBuilder,
408+
width: width,
409+
height: height,
410+
fit: fit,
411+
alignment: alignment,
412+
package: package,
413+
addRepaintBoundary: addRepaintBoundary,
414+
filterQuality: filterQuality,
415+
onWarning: onWarning,
416+
);
417+
}
418+
419+
String get path => _assetName;
420+
}

example/lib/main.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,27 @@ void main() async {
4343
fit: BoxFit.contain,
4444
),
4545
),
46+
SizedBox(
47+
width: 200,
48+
height: 200,
49+
child: MyAssets.lottie.hamburgerArrow.lottie(
50+
fit: BoxFit.contain,
51+
),
52+
),
53+
SizedBox(
54+
width: 200,
55+
height: 200,
56+
child: MyAssets.lottie.geometricalAnimation.lottie(
57+
fit: BoxFit.contain,
58+
),
59+
),
60+
SizedBox(
61+
width: 200,
62+
height: 200,
63+
child: MyAssets.lottie.alarmClockLottieV440.lottie(
64+
fit: BoxFit.contain,
65+
),
66+
),
4667
MyAssets.images.chip1.image(),
4768
Container(
4869
height: 400,

example/pubspec.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ dependencies:
5757
flutter_secure_storage: 5.0.2
5858
auto_route: 3.2.4
5959
gap: 2.0.0
60-
lottie: 1.3.0
60+
lottie: 1.4.1
6161
flutter_layout_grid: 2.0.0
6262
video_player: 2.4.0
6363
audio_service: 0.18.4
@@ -119,6 +119,7 @@ flutter_gen:
119119
flutter_svg: true
120120
flare_flutter: true
121121
rive: true
122+
lottie: true
122123

123124
assets:
124125
enabled: true
@@ -169,6 +170,8 @@ flutter:
169170
- pictures/chip5.jpg
170171
- assets/flare/
171172
- assets/rive/
173+
- assets/lottie/
174+
- assets/lottie/wrong/
172175
- assets/movie/
173176
- assets/unknown/
174177
fonts:

packages/core/example/lib/main.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ void main() {
3838
fit: BoxFit.contain,
3939
),
4040
),
41+
SizedBox(
42+
width: 200,
43+
height: 200,
44+
child: Assets.lottie.hamburgerArrow.lottie(
45+
fit: BoxFit.contain,
46+
),
47+
),
4148
Image(image: Assets.images.chip1),
4249
Assets.images.icons.kmm.svg(key: const Key("kmm_svg")),
4350
Assets.images.icons.fuchsia.svg(),

packages/core/lib/generators/assets_generator.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import 'integrations/flare_integration.dart';
1717
import 'integrations/integration.dart';
1818
import 'integrations/rive_integration.dart';
1919
import 'integrations/svg_integration.dart';
20+
import 'integrations/lottie_integration.dart';
2021

2122
class AssetsGenConfig {
2223
AssetsGenConfig._(
@@ -29,7 +30,7 @@ class AssetsGenConfig {
2930

3031
factory AssetsGenConfig.fromConfig(File pubspecFile, Config config) {
3132
return AssetsGenConfig._(
32-
pubspecFile.parent.path,
33+
pubspecFile.parent.absolute.path,
3334
config.pubspec.packageName,
3435
config.pubspec.flutterGen,
3536
config.pubspec.flutter.assets,
@@ -66,6 +67,7 @@ String generateAssets(
6667
SvgIntegration(config.packageParameterLiteral),
6768
if (config.flutterGen.integrations.flareFlutter) FlareIntegration(),
6869
if (config.flutterGen.integrations.rive) RiveIntegration(),
70+
if (config.flutterGen.integrations.lottie) LottieIntegration(),
6971
];
7072

7173
// TODO: This code will be removed.
@@ -213,15 +215,17 @@ List<String> _getAssetRelativePathList(
213215
.toList();
214216
}
215217

216-
AssetType _constructAssetTree(List<String> assetRelativePathList) {
218+
AssetType _constructAssetTree(
219+
List<String> assetRelativePathList, String rootPath) {
217220
// Relative path is the key
218221
final assetTypeMap = <String, AssetType>{
219-
'.': AssetType('.'),
222+
'.': AssetType(rootPath: rootPath, path: '.'),
220223
};
221224
for (final assetPath in assetRelativePathList) {
222225
var path = assetPath;
223226
while (path != '.') {
224-
assetTypeMap.putIfAbsent(path, () => AssetType(path));
227+
assetTypeMap.putIfAbsent(
228+
path, () => AssetType(rootPath: rootPath, path: path));
225229
path = dirname(path);
226230
}
227231
}
@@ -309,7 +313,7 @@ String _dotDelimiterStyleDefinition(
309313
final assetsStaticStatements = <_Statement>[];
310314

311315
final assetTypeQueue = ListQueue<AssetType>.from(
312-
_constructAssetTree(assetRelativePathList).children);
316+
_constructAssetTree(assetRelativePathList, config.rootPath).children);
313317

314318
while (assetTypeQueue.isNotEmpty) {
315319
final assetType = assetTypeQueue.removeFirst();
@@ -404,7 +408,7 @@ String _flatStyleDefinition(
404408
)
405409
.distinct()
406410
.sorted()
407-
.map((relativePath) => AssetType(relativePath))
411+
.map((assetPath) => AssetType(rootPath: config.rootPath, path: assetPath))
408412
.mapToIsUniqueWithoutExtension()
409413
.map(
410414
(e) => _createAssetTypeStatement(

0 commit comments

Comments
 (0)