Compare commits

..

15 Commits

Author SHA1 Message Date
d0edd1b3ee Fix web version (#135) 2021-02-22 08:42:09 +01:00
6831f475d4 Add an image delegate to dynamically change images (#130)
And allow to use an imageProviderFactory with a zip file.
2021-02-08 22:25:58 +01:00
bbfe04f00d Remove prints (#129) 2021-02-06 14:42:46 +01:00
5b7fde198a Fix bounds calculation bug (#128) 2021-02-06 09:32:25 +01:00
fe8847a5ba Fix publish action 2021-01-23 11:26:38 +01:00
2360f643b7 Migrate to null safety (#127) 2021-01-23 11:09:32 +01:00
1146e1f01d Add bad golden tests (#118) 2020-12-29 19:07:10 +01:00
ba0bfcd126 Fix crash when path.computeMetrics returns empty list (#116) 2020-12-12 22:41:38 +01:00
cb8006d362 Fix Flutter web compilation error (#109) 2020-10-23 23:13:53 +02:00
bf7d0ebf05 Increase version to 0.7.0 (#107) 2020-10-23 18:43:56 +02:00
57faea6f5e Fill Performance Improvements and other fixes (#100)
This PR improves some fill performance issues I found with various Lottie animations.
I think the real issue comes down to the render performance of Path.addPath(). The performance issue happens in the Render thread and seems directly related to how large the animation is on-screen. Flutter might be caching pre-rendered textures and running out of memory.

I've changed how Path.addPath() is called and how the path is rendered for fill_content.dart and gradient_fill_content.dart.

Just as an example, the example/assets/Tests/bm.json animation gets ~60 fps with this fix, compared to 34-52 fps with the lottie-flutter 0.6.0 release. (This is on a Pixel 3 XL)

There are a couple of other changes:

- I fixed a bug with the casing of "weather" in pubspec.yaml. Without this fix, the examples don't build on Ubuntu Linux.
The debugging class MeanCalculator wasn't initializing its fields, causing a null pointer exception when debugging.
- I added antiAliasingSuggested to LottieDrawable to allow fill paints to be anti-aliased. It is off by default. It also provides some minor performance improvements without any noticeable loss in quality. It is only applied to fills right now.
- I added PathFactory to create Paths rather than just new-ing them. path_factory.dart allows you to switch out the normal Path creation with a debug logging implementation so you can see all of the Path calls that are performed during a frame. Just create a DebugPath in the factory rather than Path.
2020-09-10 14:18:56 +02:00
548c77dc45 Add FrameRate and improve performance (#93)
- Run the animation at the exported frame rate
- Wrap the animation in a RepaintBoundary
- Don't paint during "static" periods
2020-08-04 22:02:02 +02:00
45a4c0b981 Remove direct dependency on dart:io (#90) 2020-07-26 23:09:58 +02:00
32b1181dad Matrix translation bug (#89) 2020-07-26 15:22:18 +02:00
fcfe54686d Improve web support (#88)
- Fix a couple of bug with JSON decoding with Dart Dev Compiler
- Support loading animation from network in the web version
2020-07-25 23:54:50 +02:00
383 changed files with 16208 additions and 1805 deletions

View File

@ -10,7 +10,7 @@ jobs:
name: Flutter analyze name: Flutter analyze
strategy: strategy:
matrix: matrix:
flutter: ['stable', 'dev'] flutter: ['beta']
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -32,4 +32,18 @@ jobs:
|| (echo "##[error] found changed files after build. please run 'dart tool/prepare_submit.dart'" \ || (echo "##[error] found changed files after build. please run 'dart tool/prepare_submit.dart'" \
"and check in all changes" \ "and check in all changes" \
&& exit 1) && exit 1)
shell: bash shell: bash
build_web_version:
name: Check that the web version compile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v1
with:
channel: 'beta'
- run: flutter config --enable-web
- run: flutter precache web
- run: flutter pub get
working-directory: example
- run: flutter build web
working-directory: example

View File

@ -10,12 +10,11 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: subosito/flutter-action@v1 - uses: subosito/flutter-action@v1
with: with:
channel: 'stable' channel: 'beta'
- run: flutter pub get - run: flutter pub get
- run: flutter pub run tool/publish/comment_dependency_overrides.dart - run: flutter pub run tool/publish/comment_dependency_overrides.dart
- run: flutter pub get - run: flutter pub get
- run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF} - run: flutter pub run tool/publish/check_version.dart ${GITHUB_REF}
- run: flutter pub run tool/publish/check_version.dart ${{ env.RELEASE_VERSION }}
- name: Setup credentials - name: Setup credentials
run: | run: |
mkdir -p $FLUTTER_HOME/.pub-cache mkdir -p $FLUTTER_HOME/.pub-cache

View File

@ -1,3 +1,34 @@
## [0.8.0]
- Migrate to null safety
- Fix some rendering bugs
## [0.7.1]
- Fix a crash for some lottie file with empty paths.
## [0.7.0+1]
- Fix Flutter Web compilation error
## [0.7.0]
- Performance improvement for complex animations.
## [0.6.0]
- Runs the animation at the frame rate specified in the json file (ie. An animation encoded with a 20 FPS will only
be paint 20 times per seconds even though the AnimationController will invalidate the widget 60 times per seconds).
A new property `frameRate` allows to opt-out this behavior and have the widget to repaint at the device frame rate
(`FrameRate.max`).
- Automatically add a `RepaintBoundary` around the widget. Since `Lottie` animations are generally complex to paint, a
`RepaintBoundary` will separate the animation with the rest of the app and improve performance. A new property `addRepaintBoundary`
allows to opt-out this behavior.
- Fix a bug where we would call `markNeedPaint` when the animation was not changing. This removes unnecessary paints in
animations with static periods.
## [0.5.1]
- Remove direct dependencies on dart:io to support Flutter Web
## [0.5.0]
- Support loading animation from network in a web app
- Fix a couple of bugs with the web dev compiler
## [0.4.1] ## [0.4.1]
- Support color value stored as RGB, not RGBA - Support color value stored as RGB, not RGBA

View File

@ -3,12 +3,12 @@
[![](https://github.com/xvrh/lottie-flutter/workflows/Lottie%20Flutter/badge.svg?branch=master)](https://github.com/xvrh/lottie-flutter) [![](https://github.com/xvrh/lottie-flutter/workflows/Lottie%20Flutter/badge.svg?branch=master)](https://github.com/xvrh/lottie-flutter)
[![pub package](https://img.shields.io/pub/v/lottie.svg)](https://pub.dev/packages/lottie) [![pub package](https://img.shields.io/pub/v/lottie.svg)](https://pub.dev/packages/lottie)
Lottie is a mobile library for Android and iOS that parses [Adobe After Effects](http://www.adobe.com/products/aftereffects.html) Lottie is a mobile library for Android and iOS that parses [Adobe After Effects](https://www.adobe.com/products/aftereffects.html)
animations exported as json with [Bodymovin](https://github.com/airbnb/lottie-web) and renders them natively on mobile! animations exported as json with [Bodymovin](https://github.com/airbnb/lottie-web) and renders them natively on mobile!
This repository is a unofficial conversion of the [Lottie-android](https://github.com/airbnb/lottie-android) library in pure Dart. This repository is a unofficial conversion of the [Lottie-android](https://github.com/airbnb/lottie-android) library in pure Dart.
It works on Android, iOS and macOS. ([Web support is coming](https://github.com/xvrh/lottie-flutter#flutter-web)) It works on Android, iOS, macOS, linux, windows and web.
## Usage ## Usage
@ -64,7 +64,7 @@ class MyApp extends StatefulWidget {
} }
class _MyAppState extends State<MyApp> with TickerProviderStateMixin { class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController _controller; late final AnimationController _controller;
@override @override
void initState() { void initState() {
@ -122,13 +122,14 @@ Lottie.asset(
animation. animation.
### Custom loading ### Custom loading
This example shows how to load and parse a Lottie composition from a json file.
The `Lottie` widget has several convenient constructors (`Lottie.asset`, `Lottie.network`, `Lottie.memory`) to load, parse and The `Lottie` widget has several convenient constructors (`Lottie.asset`, `Lottie.network`, `Lottie.memory`) to load, parse and
cache automatically the json file. cache automatically the json file.
Sometime you may prefer to have full control over the loading of the file. Use `LottieComposition.fromByteData` to Sometime you may prefer to have full control over the loading of the file. Use `LottieComposition.fromByteData` to
parse the file from a list of bytes. parse the file from a list of bytes.
This example shows how to load and parse a Lottie composition from a json file.
```dart ```dart
class MyWidget extends StatefulWidget { class MyWidget extends StatefulWidget {
@override @override
@ -136,7 +137,7 @@ class MyWidget extends StatefulWidget {
} }
class _MyWidgetState extends State<MyWidget> { class _MyWidgetState extends State<MyWidget> {
Future<LottieComposition> _composition; late final Future<LottieComposition> _composition;
@override @override
void initState() { void initState() {
@ -175,7 +176,7 @@ a specific position and size.
class CustomDrawer extends StatelessWidget { class CustomDrawer extends StatelessWidget {
final LottieComposition composition; final LottieComposition composition;
const CustomDrawer(this.composition, {Key key}) : super(key: key); const CustomDrawer(this.composition, {Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -245,17 +246,13 @@ class _Animation extends StatelessWidget {
```` ````
## Limitations ## Limitations
This is a new library so usability, documentation and performance are still work in progress.
Only the [supported features of Lottie Android](https://airbnb.io/lottie/#/supported-features) Only the [supported features of Lottie Android](https://airbnb.io/lottie/#/supported-features)
are supported in this port. are supported in this port.
## Flutter Web ## Flutter Web
Run the app with `flutter run -d Chrome --dart-define=FLUTTER_WEB_USE_SKIA=true --release` Run the app with `flutter run -d Chrome --dart-define=FLUTTER_WEB_USE_SKIA=true --release`
The performance are not great and some features are missing.
See a preview here: https://xvrh.github.io/lottie-flutter/index.html See a preview here: https://xvrh.github.io/lottie-flutter/index.html
## Complete example ## More examples
See the Sample app (in the `example` folder) for a complete example of the various possibilities. See the `example` folder for more code samples of the various possibilities.

View File

@ -3,12 +3,12 @@
[![](https://github.com/xvrh/lottie-flutter/workflows/Lottie%20Flutter/badge.svg?branch=master)](https://github.com/xvrh/lottie-flutter) [![](https://github.com/xvrh/lottie-flutter/workflows/Lottie%20Flutter/badge.svg?branch=master)](https://github.com/xvrh/lottie-flutter)
[![pub package](https://img.shields.io/pub/v/lottie.svg)](https://pub.dev/packages/lottie) [![pub package](https://img.shields.io/pub/v/lottie.svg)](https://pub.dev/packages/lottie)
Lottie is a mobile library for Android and iOS that parses [Adobe After Effects](http://www.adobe.com/products/aftereffects.html) Lottie is a mobile library for Android and iOS that parses [Adobe After Effects](https://www.adobe.com/products/aftereffects.html)
animations exported as json with [Bodymovin](https://github.com/airbnb/lottie-web) and renders them natively on mobile! animations exported as json with [Bodymovin](https://github.com/airbnb/lottie-web) and renders them natively on mobile!
This repository is a unofficial conversion of the [Lottie-android](https://github.com/airbnb/lottie-android) library in pure Dart. This repository is a unofficial conversion of the [Lottie-android](https://github.com/airbnb/lottie-android) library in pure Dart.
It works on Android, iOS and macOS. ([Web support is coming](https://github.com/xvrh/lottie-flutter#flutter-web)) It works on Android, iOS, macOS, linux, windows and web.
## Usage ## Usage
@ -17,7 +17,7 @@ This example shows how to display a Lottie animation in the simplest way.
The `Lottie` widget will load the json file and run the animation indefinitely. The `Lottie` widget will load the json file and run the animation indefinitely.
```dart ```dart
import 'example/lib/examples/main.dart'; import 'example/lib/main.dart';
``` ```
### Specify a custom `AnimationController` ### Specify a custom `AnimationController`
@ -48,13 +48,14 @@ Lottie.asset(
animation. animation.
### Custom loading ### Custom loading
This example shows how to load and parse a Lottie composition from a json file.
The `Lottie` widget has several convenient constructors (`Lottie.asset`, `Lottie.network`, `Lottie.memory`) to load, parse and The `Lottie` widget has several convenient constructors (`Lottie.asset`, `Lottie.network`, `Lottie.memory`) to load, parse and
cache automatically the json file. cache automatically the json file.
Sometime you may prefer to have full control over the loading of the file. Use `LottieComposition.fromByteData` to Sometime you may prefer to have full control over the loading of the file. Use `LottieComposition.fromByteData` to
parse the file from a list of bytes. parse the file from a list of bytes.
This example shows how to load and parse a Lottie composition from a json file.
```dart ```dart
import 'example/lib/examples/custom_load.dart#example'; import 'example/lib/examples/custom_load.dart#example';
``` ```
@ -77,17 +78,13 @@ import 'example/lib/examples/simple_dynamic_properties.dart#example';
```` ````
## Limitations ## Limitations
This is a new library so usability, documentation and performance are still work in progress.
Only the [supported features of Lottie Android](https://airbnb.io/lottie/#/supported-features) Only the [supported features of Lottie Android](https://airbnb.io/lottie/#/supported-features)
are supported in this port. are supported in this port.
## Flutter Web ## Flutter Web
Run the app with `flutter run -d Chrome --dart-define=FLUTTER_WEB_USE_SKIA=true --release` Run the app with `flutter run -d Chrome --dart-define=FLUTTER_WEB_USE_SKIA=true --release`
The performance are not great and some features are missing.
See a preview here: https://xvrh.github.io/lottie-flutter/index.html See a preview here: https://xvrh.github.io/lottie-flutter/index.html
## Complete example ## More examples
See the Sample app (in the `example` folder) for a complete example of the various possibilities. See the `example` folder for more code samples of the various possibilities.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

7280
example/assets/envelope.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

3133
example/assets/tent.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"

View File

@ -23,7 +23,7 @@ class __PageState extends State<_Page> {
void initState() { void initState() {
super.initState(); super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) => _showLoader()); SchedulerBinding.instance!.addPostFrameCallback((_) => _showLoader());
} }
void _showLoader() { void _showLoader() {

View File

@ -6,7 +6,7 @@ void main() async {
} }
class App extends StatelessWidget { class App extends StatelessWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -9,7 +9,7 @@ class MyApp extends StatefulWidget {
} }
class _MyAppState extends State<MyApp> with TickerProviderStateMixin { class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController _controller; late final AnimationController _controller;
@override @override
void initState() { void initState() {

View File

@ -17,7 +17,7 @@ class MyApp extends StatefulWidget {
} }
class _MyAppState extends State<MyApp> with TickerProviderStateMixin { class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController _controller; late final AnimationController _controller;
@override @override
void initState() { void initState() {
@ -86,7 +86,7 @@ class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
], ],
), ),
const SizedBox(height: 30), const SizedBox(height: 30),
RaisedButton( ElevatedButton(
child: Text('Loop between frames'), child: Text('Loop between frames'),
onPressed: () { onPressed: () {
// Loop between 2 specifics frames // Loop between 2 specifics frames
@ -97,7 +97,7 @@ class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
min: start, min: start,
max: stop, max: stop,
reverse: true, reverse: true,
period: _controller.duration * (stop - start), period: _controller.duration! * (stop - start),
); );
}, },
), ),

View File

@ -22,7 +22,7 @@ class MyWidget extends StatefulWidget {
} }
class _MyWidgetState extends State<MyWidget> { class _MyWidgetState extends State<MyWidget> {
Future<LottieComposition> _composition; late final Future<LottieComposition> _composition;
@override @override
void initState() { void initState() {
@ -57,7 +57,7 @@ class _MyWidgetState extends State<MyWidget> {
class CustomDrawer extends StatelessWidget { class CustomDrawer extends StatelessWidget {
final LottieComposition composition; final LottieComposition composition;
const CustomDrawer(this.composition, {Key key}) : super(key: key); const CustomDrawer(this.composition, {Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -23,7 +23,7 @@ class MyWidget extends StatefulWidget {
} }
class _MyWidgetState extends State<MyWidget> { class _MyWidgetState extends State<MyWidget> {
Future<LottieComposition> _composition; late final Future<LottieComposition> _composition;
@override @override
void initState() { void initState() {

View File

@ -8,7 +8,7 @@ void main() async {
} }
class App extends StatefulWidget { class App extends StatefulWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
_AppState createState() => _AppState(); _AppState createState() => _AppState();
@ -50,7 +50,7 @@ class _AppState extends State<App> with TickerProviderStateMixin {
value: _useDelegates, value: _useDelegates,
onChanged: (newValue) { onChanged: (newValue) {
setState(() { setState(() {
_useDelegates = newValue; _useDelegates = newValue!;
}); });
}, },
), ),

View File

@ -7,14 +7,14 @@ void main() async {
} }
class App extends StatefulWidget { class App extends StatefulWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
_AppState createState() => _AppState(); _AppState createState() => _AppState();
} }
class _AppState extends State<App> with TickerProviderStateMixin { class _AppState extends State<App> with TickerProviderStateMixin {
TextEditingController _textController; late final TextEditingController _textController;
@override @override
void initState() { void initState() {

View File

@ -6,14 +6,14 @@ void main() async {
} }
class App extends StatefulWidget { class App extends StatefulWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
_AppState createState() => _AppState(); _AppState createState() => _AppState();
} }
class _AppState extends State<App> with TickerProviderStateMixin { class _AppState extends State<App> with TickerProviderStateMixin {
AnimationController _animationController; late final AnimationController _animationController;
bool _showAnimation = true; bool _showAnimation = true;
@override @override

View File

@ -1,27 +0,0 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView(
children: [
// Load a Lottie file from your assets
Lottie.asset('assets/LottieLogo1.json'),
// Load a Lottie file from a remote url
Lottie.network(
'https://raw.githubusercontent.com/xvrh/lottie-flutter/master/example/assets/Mobilo/A.json'),
// Load an animation and its images from a zip file
Lottie.asset('assets/lottiefiles/angel.zip'),
],
),
),
);
}
}

View File

@ -9,14 +9,14 @@ void main() async {
} }
class App extends StatefulWidget { class App extends StatefulWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
_AppState createState() => _AppState(); _AppState createState() => _AppState();
} }
class _AppState extends State<App> with TickerProviderStateMixin { class _AppState extends State<App> with TickerProviderStateMixin {
Future<LottieComposition> _composition; late final Future<LottieComposition> _composition;
@override @override
void initState() { void initState() {
@ -35,9 +35,9 @@ class _AppState extends State<App> with TickerProviderStateMixin {
body: FutureBuilder<LottieComposition>( body: FutureBuilder<LottieComposition>(
future: _composition, future: _composition,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) return ErrorWidget(snapshot.error); if (snapshot.hasError) return ErrorWidget(snapshot.error!);
if (!snapshot.hasData) return CircularProgressIndicator(); if (!snapshot.hasData) return CircularProgressIndicator();
return _LottieDetails(snapshot.data); return _LottieDetails(snapshot.data!);
}, },
), ),
), ),
@ -48,7 +48,7 @@ class _AppState extends State<App> with TickerProviderStateMixin {
class _LottieDetails extends StatefulWidget { class _LottieDetails extends StatefulWidget {
final LottieComposition composition; final LottieComposition composition;
const _LottieDetails(this.composition, {Key key}) : super(key: key); const _LottieDetails(this.composition, {Key? key}) : super(key: key);
@override @override
_LottieDetailsState createState() => _LottieDetailsState(); _LottieDetailsState createState() => _LottieDetailsState();
@ -56,7 +56,7 @@ class _LottieDetails extends StatefulWidget {
class _LottieDetailsState extends State<_LottieDetails> class _LottieDetailsState extends State<_LottieDetails>
with TickerProviderStateMixin { with TickerProviderStateMixin {
AnimationController _controller; late final AnimationController _controller;
@override @override
void initState() { void initState() {
@ -87,15 +87,15 @@ class _LottieDetailsState extends State<_LottieDetails>
title: Text('Composition duration'), title: Text('Composition duration'),
trailing: Text(widget.composition.durationFrames.toStringAsFixed(1)), trailing: Text(widget.composition.durationFrames.toStringAsFixed(1)),
), ),
RaisedButton( ElevatedButton(
child: Text('touchDownEnd - touchUpCancel'), child: Text('touchDownEnd - touchUpCancel'),
onPressed: () => _playBetween('touchDownEnd', 'touchUpCancel'), onPressed: () => _playBetween('touchDownEnd', 'touchUpCancel'),
), ),
RaisedButton( ElevatedButton(
child: Text('touchDownStart - touchDownEnd'), child: Text('touchDownStart - touchDownEnd'),
onPressed: () => _playBetween('touchDownStart', 'touchDownEnd'), onPressed: () => _playBetween('touchDownStart', 'touchDownEnd'),
), ),
RaisedButton( ElevatedButton(
child: Text('touchDownEnd - touchUpEnd'), child: Text('touchDownEnd - touchUpEnd'),
onPressed: () => _playBetween('touchDownEnd', 'touchUpEnd'), onPressed: () => _playBetween('touchDownEnd', 'touchUpEnd'),
), ),
@ -112,8 +112,8 @@ class _LottieDetailsState extends State<_LottieDetails>
} }
void _playBetween(String marker1, String marker2) { void _playBetween(String marker1, String marker2) {
var start = widget.composition.getMarker(marker1).start; var start = widget.composition.getMarker(marker1)!.start;
var end = widget.composition.getMarker(marker2).start; var end = widget.composition.getMarker(marker2)!.start;
_controller.value = start; _controller.value = start;
_controller.animateTo(end, _controller.animateTo(end,

View File

@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
late final AnimationController _controller;
int _repeatIndex = 0;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
setState(() {
_repeatIndex++;
});
if (_repeatIndex < 5) {
_controller.reset();
_controller.forward();
}
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView(
children: [
Lottie.asset(
'assets/AndroidWave.json',
controller: _controller,
width: 150,
height: 150,
onLoaded: (composition) {
// Configure the AnimationController with the duration of the
// Lottie file and start the animation.
_controller.duration = composition.duration;
_controller.forward();
},
),
Center(child: Text('Repeat: $_repeatIndex')),
],
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}

View File

@ -12,7 +12,7 @@ void main() async {
} }
class App extends StatefulWidget { class App extends StatefulWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
_AppState createState() => _AppState(); _AppState createState() => _AppState();
@ -20,7 +20,7 @@ class App extends StatefulWidget {
class _AppState extends State<App> with TickerProviderStateMixin { class _AppState extends State<App> with TickerProviderStateMixin {
int _index = 0; int _index = 0;
AnimationController _animationController; late final AnimationController _animationController;
@override @override
void initState() { void initState() {

View File

@ -1,3 +1,5 @@
//@dart=2.10
import 'dart:io'; import 'dart:io';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -26,7 +28,7 @@ class _MyAppState extends State<MyApp> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
RaisedButton( ElevatedButton(
child: Text('Export all frames'), child: Text('Export all frames'),
onPressed: _export, onPressed: _export,
), ),

View File

@ -1,157 +1,24 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart'; import 'package:lottie/lottie.dart';
import 'src/all_files.g.dart';
void main() { void main() => runApp(MyApp());
Logger.root
..level = Level.ALL
..onRecord.listen(print);
Lottie.traceEnabled = true;
runApp(App());
}
class App extends StatelessWidget { class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
//showPerformanceOverlay: true,
home: Scaffold( home: Scaffold(
appBar: AppBar( body: ListView(
title: Text('Lottie Flutter'),
),
body: GridView.builder(
itemCount: files.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) {
var assetName = files[index];
return GestureDetector(
child: _Item(
child: Lottie.asset(
assetName,
frameBuilder: (context, child, composition) {
return AnimatedOpacity(
child: child,
opacity: composition == null ? 0 : 1,
duration: const Duration(seconds: 1),
curve: Curves.easeOut,
);
},
),
),
onTap: () {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (context) => Detail(assetName)));
},
);
},
),
),
);
}
}
class _Item extends StatelessWidget {
final Widget child;
const _Item({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
offset: Offset(2, 2),
blurRadius: 5)
]),
child: child,
),
);
}
}
class Detail extends StatefulWidget {
final String assetName;
const Detail(this.assetName, {Key key}) : super(key: key);
@override
_DetailState createState() => _DetailState();
}
class _DetailState extends State<Detail> 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 Scaffold(
appBar: AppBar(
title: Text('${widget.assetName}'),
),
body: SingleChildScrollView(
child: Column(
children: [ children: [
Center( // Load a Lottie file from your assets
child: Lottie.asset( Lottie.asset('assets/LottieLogo1.json'),
widget.assetName,
controller: _controller, // Load a Lottie file from a remote url
onLoaded: (composition) { Lottie.network(
_controller.duration = composition.duration; 'https://raw.githubusercontent.com/xvrh/lottie-flutter/master/example/assets/Mobilo/A.json'),
_controller.repeat();
}, // Load an animation and its images from a zip file
), Lottie.asset('assets/lottiefiles/angel.zip'),
),
AnimatedBuilder(
animation: _controller,
builder: (context, _) => Row(
children: <Widget>[
Expanded(
child: Slider(
value: _controller.value,
onChanged: (newValue) {
_controller.value = newValue;
},
),
),
IconButton(
icon: Icon(_controller.isAnimating
? Icons.stop
: Icons.play_arrow),
onPressed: () {
setState(() {
if (_controller.isAnimating) {
_controller.stop();
} else {
_controller.repeat();
}
});
},
),
],
),
),
], ],
), ),
), ),

156
example/lib/main_app.dart Normal file
View File

@ -0,0 +1,156 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart';
import 'src/all_files.g.dart';
void main() {
Logger.root
..level = Level.ALL
..onRecord.listen(print);
Lottie.traceEnabled = true;
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
//showPerformanceOverlay: true,
home: Scaffold(
appBar: AppBar(
title: Text('Lottie Flutter'),
),
body: Scrollbar(
child: GridView.builder(
itemCount: files.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
itemBuilder: (context, index) {
var assetName = files[index];
return GestureDetector(
child: _Item(
child: Lottie.asset(
assetName,
frameBuilder: (context, child, composition) {
return AnimatedOpacity(
child: child,
opacity: composition == null ? 0 : 1,
duration: const Duration(seconds: 1),
curve: Curves.easeOut,
);
},
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (context) => Detail(assetName)));
},
);
},
),
),
),
);
}
}
class _Item extends StatelessWidget {
final Widget child;
const _Item({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
offset: Offset(2, 2),
blurRadius: 5)
]),
child: child,
),
);
}
}
class Detail extends StatefulWidget {
final String assetName;
const Detail(this.assetName, {Key? key}) : super(key: key);
@override
_DetailState createState() => _DetailState();
}
class _DetailState extends State<Detail> with TickerProviderStateMixin {
late final _controller = AnimationController(vsync: this);
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('${widget.assetName}'),
),
body: SingleChildScrollView(
child: Column(
children: [
Center(
child: Lottie.asset(
widget.assetName,
controller: _controller,
onLoaded: (composition) {
_controller.duration = composition.duration;
_controller.repeat();
},
),
),
AnimatedBuilder(
animation: _controller,
builder: (context, _) => Row(
children: <Widget>[
Expanded(
child: Slider(
value: _controller.value,
onChanged: (newValue) {
_controller.value = newValue;
},
),
),
IconButton(
icon: Icon(_controller.isAnimating
? Icons.stop
: Icons.play_arrow),
onPressed: () {
setState(() {
if (_controller.isAnimating) {
_controller.stop();
} else {
_controller.repeat();
}
});
},
),
],
),
),
],
),
),
);
}
}

View File

@ -13,7 +13,7 @@ void main() async {
class App extends StatelessWidget { class App extends StatelessWidget {
final LottieComposition composition; final LottieComposition composition;
const App({Key key, this.composition}) : super(key: key); const App({Key? key, required this.composition}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -97,13 +97,13 @@ class App extends StatelessWidget {
class _Lottie extends StatefulWidget { class _Lottie extends StatefulWidget {
final LottieComposition composition; final LottieComposition composition;
final double width; final double? width;
final double height; final double? height;
final BoxFit fit; final BoxFit? fit;
final AlignmentGeometry alignment; final AlignmentGeometry? alignment;
const _Lottie(this.composition, const _Lottie(this.composition,
{Key key, this.width, this.height, this.fit, this.alignment}) {Key? key, this.width, this.height, this.fit, this.alignment})
: super(key: key); : super(key: key);
@override @override
@ -111,7 +111,7 @@ class _Lottie extends StatefulWidget {
} }
class __LottieState extends State<_Lottie> with TickerProviderStateMixin { class __LottieState extends State<_Lottie> with TickerProviderStateMixin {
AnimationController _controller; late AnimationController _controller;
@override @override
void initState() { void initState() {

View File

@ -6,7 +6,7 @@ void main() async {
} }
class App extends StatelessWidget { class App extends StatelessWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -6,7 +6,7 @@ void main() async {
} }
class App extends StatelessWidget { class App extends StatelessWidget {
const App({Key key}) : super(key: key); const App({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -1,2 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -1,27 +1,28 @@
PODS: PODS:
- FlutterMacOS (1.0.0) - FlutterMacOS (1.22.4)
- path_provider (0.0.1) - path_provider (0.0.1)
- path_provider_macos (0.0.1): - path_provider_macos (0.0.1):
- FlutterMacOS - FlutterMacOS
DEPENDENCIES: DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral/.symlinks/flutter/darwin-x64`)
- path_provider (from `Flutter/ephemeral/.symlinks/plugins/path_provider/macos`) - path_provider (from `Flutter/ephemeral/.symlinks/plugins/path_provider/macos`)
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
SPEC REPOS:
trunk:
- FlutterMacOS
EXTERNAL SOURCES: EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral/.symlinks/flutter/darwin-x64
path_provider: path_provider:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider/macos :path: Flutter/ephemeral/.symlinks/plugins/path_provider/macos
path_provider_macos: path_provider_macos:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
SPEC CHECKSUMS: SPEC CHECKSUMS:
FlutterMacOS: 15bea8a44d2fa024068daa0140371c020b4b6ff9 FlutterMacOS: ac210ef71944b3f04789076d70d4c72c7ec0c619
path_provider: e0848572d1d38b9a7dd099e79cf83f5b7e2cde9f path_provider: e0848572d1d38b9a7dd099e79cf83f5b7e2cde9f
path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b
PODFILE CHECKSUM: d8ba9b3e9e93c62c74a660b46c6fcb09f03991a7 PODFILE CHECKSUM: d8ba9b3e9e93c62c74a660b46c6fcb09f03991a7
COCOAPODS: 1.9.1 COCOAPODS: 1.10.1

View File

@ -26,10 +26,6 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BC6FF5FCD90624533CC60DB /* Pods_Runner.framework */; }; F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BC6FF5FCD90624533CC60DB /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -50,8 +46,6 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */,
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */,
); );
name = "Bundle Framework"; name = "Bundle Framework";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -73,14 +67,12 @@
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; }; 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; };
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
5B4C0E87024EC2686CA05E23 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; 5B4C0E87024EC2686CA05E23 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -88,8 +80,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */, F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -145,8 +135,6 @@
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
D73912EF22F37F9E000D13A0 /* App.framework */,
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */,
); );
path = Flutter; path = Flutter;
sourceTree = "<group>"; sourceTree = "<group>";
@ -281,7 +269,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
}; };
33CC111E2044C6BF0003C045 /* ShellScript */ = { 33CC111E2044C6BF0003C045 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
@ -330,10 +318,10 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( inputPaths = (
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputFileListPaths = ( outputPaths = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;

View File

@ -7,77 +7,70 @@ packages:
name: archive name: archive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.13" version: "3.0.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.1" version: "2.5.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.3" version: "1.2.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.12" version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.5" version: "3.0.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file: file:
dependency: transitive dependency: transitive
description: description:
@ -96,7 +89,7 @@ packages:
name: flutter_colorpicker name: flutter_colorpicker
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.4" version: "0.4.0-nullsafety.0"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -108,14 +101,14 @@ packages:
name: golden_toolkit name: golden_toolkit
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.1" version: "0.9.0-nullsafety.0"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
name: http name: http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.1" version: "0.12.2"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
@ -136,42 +129,42 @@ packages:
name: logging name: logging
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.11.4" version: "1.0.0"
lottie: lottie:
dependency: "direct main" dependency: "direct main"
description: description:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.4.1" version: "0.8.0-nullsafety.4"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.6" version: "0.12.10"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.8" version: "1.3.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.11" version: "1.6.27"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -185,21 +178,28 @@ packages:
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+3" version: "0.0.4+8"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.4"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+3"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
name: pedantic name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.0" version: "1.9.2"
platform: platform:
dependency: transitive dependency: transitive
description: description:
@ -213,7 +213,7 @@ packages:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.3"
process: process:
dependency: transitive dependency: transitive
description: description:
@ -232,63 +232,70 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.3" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.16" version: "0.2.19"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.6" version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.1.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.4"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.0" version: "0.1.2"
sdks: sdks:
dart: ">=2.7.0 <3.0.0" dart: ">=2.12.0-29.10.beta <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0" flutter: ">=1.24.0-10.2.pre"

View File

@ -1,23 +1,23 @@
name: lottie_example name: lottie_example
description: A sample app for the Lottie player description: A sample app for the Lottie player
version: 0.0.1 publish_to: none
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0-0 <3.0.0"
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_colorpicker: ^0.4.0-nullsafety.0
http:
lottie: lottie:
path: ../ path: ../
flutter_colorpicker:
path_provider: path_provider:
http:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
golden_toolkit: golden_toolkit: ^0.9.0-nullsafety.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
@ -31,10 +31,11 @@ flutter:
- assets/lottiefiles/ - assets/lottiefiles/
- assets/Mobilo/ - assets/Mobilo/
- assets/Tests/ - assets/Tests/
- assets/Tests/images/
- assets/Logo/ - assets/Logo/
- assets/Images/ - assets/Images/
- assets/Images/WeAccept/ - assets/Images/WeAccept/
- assets/Weather/ - assets/weather/
- assets/example_with_images/ - assets/example_with_images/
- assets/example_with_images/images/ - assets/example_with_images/images/

View File

@ -0,0 +1,74 @@
import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'utils.dart';
void main() {
testWidgets('Can specify ImageProvider with zip file ', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var callCount = 0;
LottieImageProviderFactory imageProviderFactory = (image) {
++callCount;
return FileImage(File('assets/Images/WeAccept/img_0.png'));
};
var composition = (await tester.runAsync(() => FileLottie(
File('assets/spinning_carrousel.zip'),
imageProviderFactory: imageProviderFactory)
.load()))!;
await tester.pumpWidget(FilmStrip(composition, size: size));
expect(callCount, 2);
await expectLater(find.byType(FilmStrip),
matchesGoldenFile('goldens/dynamic_image/zip_with_provider.png'));
});
testWidgets('Can specify image delegate', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var image = await tester.runAsync(
() => loadImage(FileImage(File('assets/Images/WeAccept/img_0.png'))));
var composition = (await tester.runAsync(
() => FileLottie(File('assets/spinning_carrousel.zip')).load()))!;
var delegates = LottieDelegates(image: (composition, asset) {
return image;
});
await tester.pumpWidget(FilmStrip(
composition,
size: size,
delegates: delegates,
));
await expectLater(find.byType(FilmStrip),
matchesGoldenFile('goldens/dynamic_image/delegate.png'));
});
}
Future<ui.Image?> loadImage(ImageProvider provider) {
var completer = Completer<ui.Image?>();
var imageStream = provider.resolve(ImageConfiguration.empty);
late ImageStreamListener listener;
listener = ImageStreamListener((image, synchronousLoaded) {
imageStream.removeListener(listener);
completer.complete(image.image);
}, onError: (dynamic e, __) {
imageStream.removeListener(listener);
completer.complete();
});
imageStream.addListener(listener);
return completer.future;
}

View File

@ -7,7 +7,7 @@ import 'package:lottie/lottie.dart';
import 'utils.dart'; import 'utils.dart';
void main() { void main() {
LottieComposition composition; late LottieComposition composition;
setUpAll(() async { setUpAll(() async {
composition = await LottieComposition.fromBytes( composition = await LottieComposition.fromBytes(
@ -15,7 +15,7 @@ void main() {
}); });
void testGolden(String description, ValueDelegate delegate, void testGolden(String description, ValueDelegate delegate,
{double progress}) async { {double? progress}) async {
var screenshotName = description var screenshotName = description
.toLowerCase() .toLowerCase()
.replaceAll(RegExp('[^a-z0-9 ]'), '') .replaceAll(RegExp('[^a-z0-9 ]'), '')
@ -33,6 +33,7 @@ void main() {
composition: composition, composition: composition,
controller: animation, controller: animation,
delegates: LottieDelegates(values: [delegate]), delegates: LottieDelegates(values: [delegate]),
addRepaintBoundary: false,
), ),
); );
await tester.pump(); await tester.pump();
@ -45,6 +46,7 @@ void main() {
composition: composition, composition: composition,
controller: animation, controller: animation,
delegates: LottieDelegates(values: []), delegates: LottieDelegates(values: []),
addRepaintBoundary: false,
), ),
); );
await tester.pump(); await tester.pump();
@ -286,8 +288,8 @@ void main() {
testGolden( testGolden(
'Opacity interpolation ($progress)', 'Opacity interpolation ($progress)',
ValueDelegate.transformOpacity(['Shape Layer 1', 'Rectangle'], ValueDelegate.transformOpacity(['Shape Layer 1', 'Rectangle'],
callback: (frameInfo) => lerpDouble( callback: (frameInfo) => lerpDouble(10, 100,
10, 100, Curves.linear.transform(frameInfo.overallProgress)) Curves.linear.transform(frameInfo.overallProgress))!
.round()), .round()),
progress: progress); progress: progress);
} }

View File

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:golden_toolkit/golden_toolkit.dart'; import 'package:golden_toolkit/golden_toolkit.dart';
Future<void> main(FutureOr<void> Function() testMain) async { Future<void> testExecutable(FutureOr<void> Function() testMain) async {
await loadAppFonts(); await loadAppFonts();
return testMain(); return testMain();
} }

View File

@ -16,7 +16,8 @@ void main() {
var size = Size(500, 400); var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size; tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0; tester.binding.window.devicePixelRatioTestValue = 1.0;
var composition = await tester.runAsync(() => FileLottie(asset).load()); var composition =
(await tester.runAsync(() => FileLottie(asset).load()))!;
await tester.pumpWidget(FilmStrip(composition, size: size)); await tester.pumpWidget(FilmStrip(composition, size: size));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 7.1 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: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 19 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: 14 KiB

After

Width:  |  Height:  |  Size: 14 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: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 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: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 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: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 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: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 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: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Some files were not shown because too many files have changed in this diff Show More