Compare commits

...

3 Commits

Author SHA1 Message Date
478bd27e89 Support latest version of the characters package (#76) 2020-06-10 16:15:07 +02:00
ef06d63040 Disable merge paths by default (#72) 2020-06-01 16:41:10 +02:00
0715f6a402 Export the Marker class (#63)
And add an example to play the animation between 2 markers
2020-05-19 22:22:27 +02:00
76 changed files with 119367 additions and 47 deletions

View File

@ -1,3 +1,22 @@
## [0.4.0+1]
- Support latest version of the `characters` package
## [0.4.0]
- Disable "Merge paths" by default and provide an option to enable them.
This is the same behavior as in Lottie-android.
Merge paths currently don't work if the the operand shape is entirely contained within the
first shape. If you need to cut out one shape from another shape, use an even-odd fill type
instead of using merge paths.
Merge paths can be enabled with:
```dart
Lottie.asset('file.json', options: LottieOptions(enableMergePaths: true));
```
## [0.3.6]
- Export the `Marker` class
## [0.3.5] ## [0.3.5]
- Fix a bug with a wrongly clipped rectangle. - Fix a bug with a wrongly clipped rectangle.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,833 @@
{
"v": "5.6.9",
"fr": 25,
"ip": 0,
"op": 75,
"w": 1200,
"h": 1200,
"nm": "Character-side v1",
"ddd": 0,
"assets": [
{
"id": "image_0",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_0.png",
"e": 0
},
{
"id": "image_1",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_1.png",
"e": 0
},
{
"id": "image_2",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_2.png",
"e": 0
},
{
"id": "image_3",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_3.png",
"e": 0
},
{
"id": "image_4",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_4.png",
"e": 0
},
{
"id": "image_5",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_5.png",
"e": 0
},
{
"id": "image_6",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_6.png",
"e": 0
},
{
"id": "image_7",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_7.png",
"e": 0
},
{
"id": "image_8",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_8.png",
"e": 0
},
{
"id": "image_9",
"w": 1200,
"h": 1200,
"u": "images/",
"p": "img_9.png",
"e": 0
}
],
"layers": [
{
"ddd": 0,
"ind": 2,
"ty": 2,
"nm": "F ARM Up",
"parent": 8,
"refId": "image_0",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 1,
"k": [
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 0,
"s": [
0
]
},
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 25,
"s": [
67
]
},
{
"t": 50,
"s": [
0
]
}
],
"ix": 10
},
"p": {
"a": 0,
"k": [
623.019,
296.734,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
623.019,
296.734,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 3,
"ty": 2,
"nm": "F ARM Low",
"parent": 2,
"refId": "image_1",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 1,
"k": [
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 0,
"s": [
43
]
},
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 25,
"s": [
0
]
},
{
"t": 50,
"s": [
43
]
}
],
"ix": 10
},
"p": {
"a": 0,
"k": [
623.019,
439.113,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
623.019,
439.113,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 4,
"ty": 2,
"nm": "F Hand",
"parent": 3,
"refId": "image_2",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 1,
"k": [
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 0,
"s": [
41
]
},
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 25,
"s": [
0
]
},
{
"t": 50,
"s": [
41
]
}
],
"ix": 10
},
"p": {
"a": 0,
"k": [
623.019,
584.501,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
623.019,
584.501,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 5,
"ty": 2,
"nm": "F LEG Up",
"refId": "image_3",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 90,
"ix": 10
},
"p": {
"a": 0,
"k": [
604.854,
589.662,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
604.854,
589.662,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 6,
"ty": 2,
"nm": "F LEG Low",
"parent": 5,
"refId": "image_4",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": -90,
"ix": 10
},
"p": {
"a": 0,
"k": [
608.016,
829.202,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
608.016,
829.202,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 7,
"ty": 2,
"nm": "F Foot",
"parent": 6,
"refId": "image_5",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
608.863,
1058.742,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
608.863,
1058.742,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 8,
"ty": 2,
"nm": "Body",
"parent": 11,
"refId": "image_6",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
605.434,
468.468,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
605.434,
468.468,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 9,
"ty": 2,
"nm": "Head",
"parent": 8,
"refId": "image_7",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
623.019,
263.511,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
623.019,
263.511,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 10,
"ty": 2,
"nm": "Hair",
"parent": 9,
"refId": "image_8",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
600,
600,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
600,
600,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
},
{
"ddd": 0,
"ind": 11,
"ty": 2,
"nm": "Waist",
"refId": "image_9",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 1,
"k": [
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 0,
"s": [
0
]
},
{
"i": {
"x": [
0.333
],
"y": [
1
]
},
"o": {
"x": [
0.667
],
"y": [
0
]
},
"t": 25,
"s": [
-70
]
},
{
"t": 50,
"s": [
0
]
}
],
"ix": 10
},
"p": {
"a": 0,
"k": [
604.854,
589.662,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
604.854,
589.662,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"ip": 0,
"op": 250,
"st": 0,
"bm": 0
}
],
"markers": [
{
"tm": 25,
"cm": "9",
"dr": 0
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1200 1200" style="enable-background:new 0 0 1200 1200;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFA913;}
</style>
<path class="st0" d="M641.59,439.11l7.69-142.38c0-14.5-11.76-26.26-26.26-26.26c-14.5,0-26.26,11.76-26.26,26.26l7.69,142.38
c0,10.26,8.31,18.57,18.57,18.57C633.28,457.68,641.59,449.37,641.59,439.11z"/>
</svg>

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

118232
example/assets/playing.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -5,23 +5,15 @@ void main() async {
runApp(App()); runApp(App());
} }
class App extends StatefulWidget { class App extends StatelessWidget {
const App({Key key}) : super(key: key); const App({Key key}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> with TickerProviderStateMixin {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
color: Colors.lightBlue, color: Colors.lightBlue,
home: Scaffold( home: Scaffold(
backgroundColor: Colors.lightBlue, backgroundColor: Colors.lightBlue,
appBar: AppBar(
title: Text(''),
),
body: Center( body: Center(
child: SizedBox( child: SizedBox(
width: 300, width: 300,

View File

@ -0,0 +1,122 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
/// This example shows how to play the animation between two markers.
/// It is based on this article for lottie-ios:
/// https://medium.com/swlh/controlling-lottie-animation-with-markers-5e9035d94623
void main() async {
runApp(App());
}
class App extends StatefulWidget {
const App({Key key}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> with TickerProviderStateMixin {
Future<LottieComposition> _composition;
@override
void initState() {
super.initState();
_composition = AssetLottie('assets/TwitterHeartButton.json').load();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text('Markers'),
),
body: FutureBuilder<LottieComposition>(
future: _composition,
builder: (context, snapshot) {
if (snapshot.hasError) return ErrorWidget(snapshot.error);
if (!snapshot.hasData) return CircularProgressIndicator();
return _LottieDetails(snapshot.data);
},
),
),
);
}
}
class _LottieDetails extends StatefulWidget {
final LottieComposition composition;
const _LottieDetails(this.composition, {Key key}) : super(key: key);
@override
_LottieDetailsState createState() => _LottieDetailsState();
}
class _LottieDetailsState extends State<_LottieDetails>
with TickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListView(
children: [
Lottie(
composition: widget.composition,
controller: _controller,
height: 150,
),
ListTile(
title: Text('Composition start frame'),
trailing: Text(widget.composition.startFrame.toStringAsFixed(1)),
),
ListTile(
title: Text('Composition duration'),
trailing: Text(widget.composition.durationFrames.toStringAsFixed(1)),
),
RaisedButton(
child: Text('touchDownEnd - touchUpCancel'),
onPressed: () => _playBetween('touchDownEnd', 'touchUpCancel'),
),
RaisedButton(
child: Text('touchDownStart - touchDownEnd'),
onPressed: () => _playBetween('touchDownStart', 'touchDownEnd'),
),
RaisedButton(
child: Text('touchDownEnd - touchUpEnd'),
onPressed: () => _playBetween('touchDownEnd', 'touchUpEnd'),
),
for (var marker in widget.composition.markers)
ListTile(
title: Text(marker.name),
subtitle: Text(
'${marker.startFrame.toStringAsFixed(1)} ${marker.durationFrames.toStringAsFixed(1)}'),
trailing: Text(
'[${marker.start.toStringAsFixed(2)}-${marker.end.toStringAsFixed(2)}]'),
),
],
);
}
void _playBetween(String marker1, String marker2) {
var start = widget.composition.getMarker(marker1).start;
var end = widget.composition.getMarker(marker2).start;
_controller.value = start;
_controller.animateTo(end,
duration: widget.composition.duration * (end - start).abs());
}
}

View File

@ -1,6 +1,7 @@
// Generated from tool/generate_file_list.dart // Generated from tool/generate_file_list.dart
final files = [ final files = [
'assets/14595-thumbs-up.json', 'assets/14595-thumbs-up.json',
'assets/17297-fireworks.json',
'assets/AndroidWave.json', 'assets/AndroidWave.json',
'assets/DynamicGradient.json', 'assets/DynamicGradient.json',
'assets/HamburgerArrow.json', 'assets/HamburgerArrow.json',
@ -106,6 +107,10 @@ final files = [
'assets/Tests/dalek_converted.json', 'assets/Tests/dalek_converted.json',
'assets/Tests/hd.json', 'assets/Tests/hd.json',
'assets/Tests/map.zip', 'assets/Tests/map.zip',
'assets/TwitterHeartButton.json',
'assets/_loading_indicator.json',
'assets/bluetoothscanning.json',
'assets/example_with_images/data.json',
'assets/lf20_w2Afea.json', 'assets/lf20_w2Afea.json',
'assets/lottiefiles/100_percent.json', 'assets/lottiefiles/100_percent.json',
'assets/lottiefiles/Plane.json', 'assets/lottiefiles/Plane.json',
@ -340,4 +345,11 @@ final files = [
'assets/lottiefiles/xuanwheel_logo.json', 'assets/lottiefiles/xuanwheel_logo.json',
'assets/lottiefiles/yoga_carpet.json', 'assets/lottiefiles/yoga_carpet.json',
'assets/lottiefiles/youtube_icon_reveal.json', 'assets/lottiefiles/youtube_icon_reveal.json',
'assets/playing.json',
'assets/weather/_hurricane.json',
'assets/weather/fog.json',
'assets/weather/hurricane.json',
'assets/weather/thunder-storm.json',
'assets/weather/tornado.json',
'assets/weather/windy.json',
]; ];

View File

@ -35,7 +35,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.0" version: "1.0.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -70,7 +70,7 @@ packages:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "2.1.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -78,6 +78,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -101,7 +108,7 @@ packages:
name: golden_toolkit name: golden_toolkit
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.2" version: "0.4.0"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -116,6 +123,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.4" version: "3.1.4"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -129,7 +143,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.3.4" version: "0.4.0+1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -157,14 +171,21 @@ packages:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.8" version: "1.6.10"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+1"
path_provider_macos: path_provider_macos:
dependency: transitive dependency: transitive
description: description:
name: path_provider_macos name: path_provider_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+2" version: "0.0.4+3"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -193,6 +214,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.13"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -254,6 +282,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.0.8"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
sdks: sdks:
dart: ">=2.7.0 <3.0.0" dart: ">=2.7.0 <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0" flutter: ">=1.12.13+hotfix.5 <2.0.0"

View File

@ -35,6 +35,8 @@ flutter:
- assets/Images/ - assets/Images/
- assets/Images/WeAccept/ - assets/Images/WeAccept/
- assets/Weather/ - assets/Weather/
- assets/example_with_images/
- assets/example_with_images/images/
fonts: fonts:
- family: Comic Neue - family: Comic Neue

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -4,6 +4,8 @@ export 'src/lottie_builder.dart' show LottieBuilder;
export 'src/lottie_delegates.dart' show LottieDelegates; export 'src/lottie_delegates.dart' show LottieDelegates;
export 'src/lottie_drawable.dart' show LottieDrawable, LottieFontStyle; export 'src/lottie_drawable.dart' show LottieDrawable, LottieFontStyle;
export 'src/lottie_image_asset.dart' show LottieImageAsset; export 'src/lottie_image_asset.dart' show LottieImageAsset;
export 'src/model/marker.dart' show Marker;
export 'src/options.dart' show LottieOptions;
export 'src/providers/asset_provider.dart' show AssetLottie; export 'src/providers/asset_provider.dart' show AssetLottie;
export 'src/providers/file_provider.dart' show FileLottie; export 'src/providers/file_provider.dart' show FileLottie;
export 'src/providers/lottie_provider.dart' show LottieProvider; export 'src/providers/lottie_provider.dart' show LottieProvider;

View File

@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
import '../lottie.dart'; import '../lottie.dart';
import 'l.dart'; import 'l.dart';
import 'lottie_builder.dart'; import 'lottie_builder.dart';
import 'options.dart';
import 'providers/load_image.dart'; import 'providers/load_image.dart';
/// A widget to display a loaded [LottieComposition]. /// A widget to display a loaded [LottieComposition].
@ -25,6 +26,7 @@ class Lottie extends StatefulWidget {
bool repeat, bool repeat,
bool reverse, bool reverse,
this.delegates, this.delegates,
this.options,
}) : animate = animate ?? true, }) : animate = animate ?? true,
reverse = reverse ?? false, reverse = reverse ?? false,
repeat = repeat ?? true, repeat = repeat ?? true,
@ -37,6 +39,7 @@ class Lottie extends StatefulWidget {
bool repeat, bool repeat,
bool reverse, bool reverse,
LottieDelegates delegates, LottieDelegates delegates,
LottieOptions options,
void Function(LottieComposition) onLoaded, void Function(LottieComposition) onLoaded,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
Key key, Key key,
@ -54,6 +57,7 @@ class Lottie extends StatefulWidget {
repeat: repeat, repeat: repeat,
reverse: reverse, reverse: reverse,
delegates: delegates, delegates: delegates,
options: options,
imageProviderFactory: imageProviderFactory, imageProviderFactory: imageProviderFactory,
onLoaded: onLoaded, onLoaded: onLoaded,
key: key, key: key,
@ -74,6 +78,7 @@ class Lottie extends StatefulWidget {
bool repeat, bool repeat,
bool reverse, bool reverse,
LottieDelegates delegates, LottieDelegates delegates,
LottieOptions options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
void Function(LottieComposition) onLoaded, void Function(LottieComposition) onLoaded,
Key key, Key key,
@ -90,6 +95,7 @@ class Lottie extends StatefulWidget {
repeat: repeat, repeat: repeat,
reverse: reverse, reverse: reverse,
delegates: delegates, delegates: delegates,
options: options,
imageProviderFactory: imageProviderFactory, imageProviderFactory: imageProviderFactory,
onLoaded: onLoaded, onLoaded: onLoaded,
key: key, key: key,
@ -108,6 +114,7 @@ class Lottie extends StatefulWidget {
bool repeat, bool repeat,
bool reverse, bool reverse,
LottieDelegates delegates, LottieDelegates delegates,
LottieOptions options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
void Function(LottieComposition) onLoaded, void Function(LottieComposition) onLoaded,
Key key, Key key,
@ -124,6 +131,7 @@ class Lottie extends StatefulWidget {
repeat: repeat, repeat: repeat,
reverse: reverse, reverse: reverse,
delegates: delegates, delegates: delegates,
options: options,
imageProviderFactory: imageProviderFactory, imageProviderFactory: imageProviderFactory,
onLoaded: onLoaded, onLoaded: onLoaded,
key: key, key: key,
@ -142,6 +150,7 @@ class Lottie extends StatefulWidget {
bool repeat, bool repeat,
bool reverse, bool reverse,
LottieDelegates delegates, LottieDelegates delegates,
LottieOptions options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
void Function(LottieComposition) onLoaded, void Function(LottieComposition) onLoaded,
Key key, Key key,
@ -158,6 +167,7 @@ class Lottie extends StatefulWidget {
repeat: repeat, repeat: repeat,
reverse: reverse, reverse: reverse,
delegates: delegates, delegates: delegates,
options: options,
imageProviderFactory: imageProviderFactory, imageProviderFactory: imageProviderFactory,
onLoaded: onLoaded, onLoaded: onLoaded,
key: key, key: key,
@ -229,13 +239,17 @@ class Lottie extends StatefulWidget {
/// relative to text direction. /// relative to text direction.
final AlignmentGeometry alignment; final AlignmentGeometry alignment;
/// A group of options to further customize the lottie animation. /// A group of callbacks to further customize the lottie animation.
/// - A [text] delegate to dynamically change some text displayed in the animation /// - A [text] delegate to dynamically change some text displayed in the animation
/// - A value callback to change the properties of the animation at runtime. /// - A value callback to change the properties of the animation at runtime.
/// - A text style factory to map between a font family specified in the animation /// - A text style factory to map between a font family specified in the animation
/// and the font family in your assets. /// and the font family in your assets.
final LottieDelegates delegates; final LottieDelegates delegates;
/// Some options to enable/disable some feature of Lottie
/// - enableMergePaths: Enable merge path support
final LottieOptions options;
static bool get traceEnabled => L.traceEnabled; static bool get traceEnabled => L.traceEnabled;
static set traceEnabled(bool enabled) { static set traceEnabled(bool enabled) {
L.traceEnabled = enabled; L.traceEnabled = enabled;
@ -295,6 +309,7 @@ class _LottieState extends State<Lottie> with TickerProviderStateMixin {
builder: (context, _) => RawLottie( builder: (context, _) => RawLottie(
composition: widget.composition, composition: widget.composition,
delegates: widget.delegates, delegates: widget.delegates,
options: widget.options,
progress: _progressAnimation.value, progress: _progressAnimation.value,
width: widget.width, width: widget.width,
height: widget.height, height: widget.height,

View File

@ -40,6 +40,7 @@ class LottieBuilder extends StatefulWidget {
this.reverse, this.reverse,
this.repeat, this.repeat,
this.delegates, this.delegates,
this.options,
this.onLoaded, this.onLoaded,
this.frameBuilder, this.frameBuilder,
this.width, this.width,
@ -58,6 +59,7 @@ class LottieBuilder extends StatefulWidget {
this.reverse, this.reverse,
this.repeat, this.repeat,
this.delegates, this.delegates,
this.options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
this.onLoaded, this.onLoaded,
Key key, Key key,
@ -87,6 +89,7 @@ class LottieBuilder extends StatefulWidget {
this.reverse, this.reverse,
this.repeat, this.repeat,
this.delegates, this.delegates,
this.options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
this.onLoaded, this.onLoaded,
Key key, Key key,
@ -106,6 +109,7 @@ class LottieBuilder extends StatefulWidget {
this.reverse, this.reverse,
this.repeat, this.repeat,
this.delegates, this.delegates,
this.options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
this.onLoaded, this.onLoaded,
Key key, Key key,
@ -130,6 +134,7 @@ class LottieBuilder extends StatefulWidget {
this.reverse, this.reverse,
this.repeat, this.repeat,
this.delegates, this.delegates,
this.options,
LottieImageProviderFactory imageProviderFactory, LottieImageProviderFactory imageProviderFactory,
this.onLoaded, this.onLoaded,
Key key, Key key,
@ -180,6 +185,10 @@ class LottieBuilder extends StatefulWidget {
/// and the font family in your assets. /// and the font family in your assets.
final LottieDelegates delegates; final LottieDelegates delegates;
/// Some options to enable/disable some feature of Lottie
/// - enableMergePaths: Enable merge path support
final LottieOptions options;
/// A builder function responsible for creating the widget that represents /// A builder function responsible for creating the widget that represents
/// this lottie animation. /// this lottie animation.
/// ///
@ -379,6 +388,7 @@ class _LottieBuilderState extends State<LottieBuilder> {
reverse: widget.reverse, reverse: widget.reverse,
repeat: widget.repeat, repeat: widget.repeat,
delegates: widget.delegates, delegates: widget.delegates,
options: widget.options,
width: widget.width, width: widget.width,
height: widget.height, height: widget.height,
fit: widget.fit, fit: widget.fit,

View File

@ -15,10 +15,13 @@ class LottieDrawable {
final Size size; final Size size;
LottieDelegates _delegates; LottieDelegates _delegates;
bool _isDirty = true; bool _isDirty = true;
final bool enableMergePaths;
LottieDrawable(this.composition, {LottieDelegates delegates}) LottieDrawable(this.composition,
{LottieDelegates delegates, bool enableMergePaths})
: size = Size(composition.bounds.width.toDouble(), : size = Size(composition.bounds.width.toDouble(),
composition.bounds.height.toDouble()) { composition.bounds.height.toDouble()),
enableMergePaths = enableMergePaths ?? false {
this.delegates = delegates; this.delegates = delegates;
_compositionLayer = CompositionLayer( _compositionLayer = CompositionLayer(
this, LayerParser.parse(composition), composition.layers, composition); this, LayerParser.parse(composition), composition.layers, composition);

View File

@ -1,5 +1,6 @@
import '../../animation/content/content.dart'; import '../../animation/content/content.dart';
import '../../animation/content/merge_paths_content.dart'; import '../../animation/content/merge_paths_content.dart';
import '../../logger.dart';
import '../../lottie_drawable.dart'; import '../../lottie_drawable.dart';
import '../layer/base_layer.dart'; import '../layer/base_layer.dart';
import 'content_model.dart'; import 'content_model.dart';
@ -15,6 +16,10 @@ class MergePaths implements ContentModel {
@override @override
Content /*?*/ toContent(LottieDrawable drawable, BaseLayer layer) { Content /*?*/ toContent(LottieDrawable drawable, BaseLayer layer) {
if (!drawable.enableMergePaths) {
logger.warning('Animation contains merge paths but they are disabled.');
return null;
}
return MergePathsContent(this); return MergePathsContent(this);
} }

View File

@ -1,26 +1,23 @@
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import '../../lottie.dart';
class Marker { class Marker {
static const String _carriageReturn = '\r'; final LottieComposition _composition;
final String name; final String name;
final double startFrame; final double startFrame;
final double durationFrames; final double durationFrames;
Marker(this.name, {@required this.startFrame, @required this.durationFrames}); Marker(this._composition, this.name,
{@required this.startFrame, @required this.durationFrames});
bool matchesName(String name) { bool matchesName(String name) {
if (this.name.toLowerCase() == name.toLowerCase()) { return this.name.trim().toLowerCase() == name.toLowerCase();
return true;
}
// It is easy for a designer to accidentally include an extra newline which will cause the name to not match what they would
// expect. This is a convenience to precent unneccesary confusion.
if (this.name.endsWith(_carriageReturn) &&
this.name.substring(0, this.name.length - 1).toLowerCase() ==
name.toLowerCase()) {
return true;
}
return false;
} }
double get start =>
(startFrame - _composition.startFrame) / _composition.durationFrames;
double get end =>
(startFrame + durationFrames - _composition.startFrame) /
_composition.durationFrames;
} }

11
lib/src/options.dart Normal file
View File

@ -0,0 +1,11 @@
class LottieOptions {
/// Enable merge path support.
///
/// Merge paths currently don't work if the the operand shape is entirely contained within the
/// first shape. If you need to cut out one shape from another shape, use an even-odd fill type
/// instead of using merge paths.
final bool enableMergePaths;
LottieOptions({bool enableMergePaths})
: enableMergePaths = enableMergePaths ?? false;
}

View File

@ -85,6 +85,8 @@ class ContentModelParser {
break; break;
case 'mm': case 'mm':
model = MergePathsParser.parse(reader); model = MergePathsParser.parse(reader);
composition.addWarning('Animation contains merge paths. '
'Merge paths must be manually enabled by settings enableMergePaths.');
break; break;
case 'rp': case 'rp':
model = RepeaterParser.parse(reader, composition); model = RepeaterParser.parse(reader, composition);

View File

@ -122,6 +122,7 @@ class LayerParser {
if (layerTypeInt < LayerType.unknown.index) { if (layerTypeInt < LayerType.unknown.index) {
layerType = LayerType.values[layerTypeInt]; layerType = LayerType.values[layerTypeInt];
} else { } else {
print('Unknown $layerTypeInt');
layerType = LayerType.unknown; layerType = LayerType.unknown;
} }
break; break;

View File

@ -254,8 +254,8 @@ class LottieCompositionParser {
} }
} }
reader.endObject(); reader.endObject();
markers.add( markers.add(Marker(composition, comment,
Marker(comment, startFrame: frame, durationFrames: durationFrames)); startFrame: frame, durationFrames: durationFrames));
} }
reader.endArray(); reader.endArray();
} }

View File

@ -13,6 +13,7 @@ class RawLottie extends LeafRenderObjectWidget {
Key key, Key key,
this.composition, this.composition,
this.delegates, this.delegates,
this.options,
double progress, double progress,
this.width, this.width,
this.height, this.height,
@ -28,6 +29,8 @@ class RawLottie extends LeafRenderObjectWidget {
/// Allows to modify the Lottie animation at runtime /// Allows to modify the Lottie animation at runtime
final LottieDelegates delegates; final LottieDelegates delegates;
final LottieOptions options;
/// The progress of the Lottie animation (between 0.0 and 1.0). /// The progress of the Lottie animation (between 0.0 and 1.0).
final double progress; final double progress;
@ -71,6 +74,7 @@ class RawLottie extends LeafRenderObjectWidget {
return RenderLottie( return RenderLottie(
composition: composition, composition: composition,
delegates: delegates, delegates: delegates,
enableMergePaths: options?.enableMergePaths,
progress: progress, progress: progress,
width: width, width: width,
height: height, height: height,
@ -82,7 +86,10 @@ class RawLottie extends LeafRenderObjectWidget {
@override @override
void updateRenderObject(BuildContext context, RenderLottie renderObject) { void updateRenderObject(BuildContext context, RenderLottie renderObject) {
renderObject renderObject
..setComposition(composition, progress: progress, delegates: delegates) ..setComposition(composition,
progress: progress,
delegates: delegates,
enableMergePaths: options?.enableMergePaths)
..width = width ..width = width
..height = height ..height = height
..alignment = alignment ..alignment = alignment

View File

@ -11,6 +11,7 @@ class RenderLottie extends RenderBox {
RenderLottie({ RenderLottie({
LottieComposition composition, LottieComposition composition,
LottieDelegates delegates, LottieDelegates delegates,
bool enableMergePaths,
double progress = 0.0, double progress = 0.0,
double width, double width,
double height, double height,
@ -19,7 +20,7 @@ class RenderLottie extends RenderBox {
}) : assert(alignment != null), }) : assert(alignment != null),
assert(progress != null && progress >= 0.0 && progress <= 1.0), assert(progress != null && progress >= 0.0 && progress <= 1.0),
_drawable = composition != null _drawable = composition != null
? (LottieDrawable(composition) ? (LottieDrawable(composition, enableMergePaths: enableMergePaths)
..setProgress(progress) ..setProgress(progress)
..delegates = delegates) ..delegates = delegates)
: null, : null,
@ -32,7 +33,11 @@ class RenderLottie extends RenderBox {
LottieComposition get composition => _drawable?.composition; LottieComposition get composition => _drawable?.composition;
LottieDrawable _drawable; LottieDrawable _drawable;
void setComposition(LottieComposition composition, void setComposition(LottieComposition composition,
{@required double progress, @required LottieDelegates delegates}) { {@required double progress,
@required LottieDelegates delegates,
bool enableMergePaths}) {
enableMergePaths ??= false;
var needsLayout = false; var needsLayout = false;
var needsPaint = false; var needsPaint = false;
if (composition == null) { if (composition == null) {
@ -40,8 +45,11 @@ class RenderLottie extends RenderBox {
needsPaint = true; needsPaint = true;
needsLayout = true; needsLayout = true;
} else { } else {
if (_drawable?.composition != composition) { if (_drawable == null ||
_drawable = LottieDrawable(composition); _drawable.composition != composition ||
_drawable.enableMergePaths != enableMergePaths) {
_drawable =
LottieDrawable(composition, enableMergePaths: enableMergePaths);
needsLayout = true; needsLayout = true;
needsPaint = true; needsPaint = true;
} }

View File

@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.0" version: "4.0.0"
analyzer: analyzer:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.39.8" version: "0.39.10"
archive: archive:
dependency: "direct main" dependency: "direct main"
description: description:
@ -49,7 +49,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.0" version: "1.0.0"
charcode: charcode:
dependency: "direct main" dependency: "direct main"
description: description:
@ -84,7 +84,7 @@ packages:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "2.1.5"
csslib: csslib:
dependency: transitive dependency: transitive
description: description:
@ -136,7 +136,7 @@ packages:
name: js name: js
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.1+1" version: "0.6.2"
logging: logging:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -1,6 +1,6 @@
name: lottie name: lottie
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player. description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
version: 0.3.5 version: 0.4.0+1
homepage: https://github.com/xvrh/lottie-flutter homepage: https://github.com/xvrh/lottie-flutter
environment: environment:
@ -10,7 +10,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
archive: ^2.0.0 archive: ^2.0.0
characters: ^0.5.0 characters: '>=0.5.0 <2.0.0'
charcode: ^1.0.0 charcode: ^1.0.0
collection: ^1.14.0 collection: ^1.14.0
logging: ^0.11.0 logging: ^0.11.0