Compare commits

...

36 Commits

Author SHA1 Message Date
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
b9aba4dce2 Prepare version v0.4.1 (#81) 2020-07-08 16:09:44 +02:00
2cb1aefb2a Sometimes sticker can has a color value stored as RGB, not RGBA (#79)
Co-authored-by: olegelifantiev <oleg-elifantiev@yandex.ru>
2020-07-08 09:47:46 +02:00
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
7e81ec3f69 Fix bug with matrix.mapRect (#61)
Fix a bug in the matrix transformation applied to a rect. We now use the MatrixUtils class from Flutter.
2020-05-18 12:55:53 +02:00
f9f093a8a2 Declare dependency on collection package 2020-05-15 16:25:15 +02:00
7c137ee55f Use offset value when drawing dashes (#58) 2020-05-15 16:14:58 +02:00
8f4952a23a Simplify AnimationController example (#50) 2020-04-18 22:54:31 +02:00
8bad4f96c0 Add an other example for animation controller (#49) 2020-04-17 21:47:07 +02:00
bb73626c46 Add golden test for all animations (#44)
And:

Improve "save_frames" example
Export AssetLottie, NetworkLottie etc..
2020-04-11 15:25:13 +02:00
47e47f5cb8 Add examples (#43)
- How to run the animation between 2 specifics frames
- How to export the animation to a file
2020-04-09 23:04:07 +02:00
954ec05598 Add alert dialog example (#39) 2020-04-03 23:20:22 +02:00
66e644d043 Prepare version 0.3.3 (#37) 2020-04-03 13:27:13 +02:00
3dab382b76 Fix a bug with rounded rectangles (#36) 2020-04-03 10:03:53 +02:00
078e661fd4 Add more test for dynamic properties (#35) 2020-04-03 09:14:43 +02:00
336890cafe Add a test for bugged loading animation (#34) 2020-04-01 23:57:27 +02:00
35ca2dc972 Add a test for dynamic properties (#33) 2020-04-01 23:35:27 +02:00
78aeed452f Fix bug with repeater (#29) 2020-03-16 09:10:35 +01:00
af9b69326a Dash path effect (#27) 2020-03-12 23:16:41 +01:00
511094262f Update example to latest version 2020-03-05 21:11:05 +01:00
62a60208b2 Bump version 2020-03-05 21:10:37 +01:00
c0c3ecbf5e Specify version range on the dependency on characters (#26) 2020-03-05 20:56:17 +01:00
d525de877e Fix gradients (#25) 2020-03-05 17:43:25 +01:00
2914caf220 Add example for hide after complete 2020-03-02 22:18:52 +01:00
e89c3c4914 Expose LottieDelegates to modify animation properties at runtime (#23) 2020-03-02 22:11:38 +01:00
4ae257eaab Set isApplyingOpacityToLayersEnabled to false (improve performance) (#22) 2020-02-27 07:53:32 +01:00
fc683482db Add an example to run an animation once (#21) 2020-02-26 23:00:28 +01:00
0d642c52f1 Port latest changes from lottie-android (#19) 2020-02-21 22:24:07 +01:00
fe748895d3 Update LICENSE 2020-02-21 20:43:06 +01:00
563 changed files with 134463 additions and 1328 deletions

View File

@ -10,8 +10,8 @@ jobs:
name: Flutter analyze
strategy:
matrix:
flutter: ['stable', 'dev']
runs-on: ubuntu-latest
flutter: ['stable']
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v1
@ -19,12 +19,16 @@ jobs:
channel: ${{ matrix.flutter }}
- run: flutter doctor
- run: flutter --version
- run: flutter pub get
working-directory: example
- run: flutter analyze
- run: flutter test test # https://github.com/flutter/flutter/issues/20907
- run: flutter test test
working-directory: example
- run: flutter pub run tool/prepare_submit.dart
- name: "check for uncommitted changes"
run: |
git diff --exit-code --stat -- . \
git diff --exit-code --stat -- . ':(exclude)*pubspec.lock' \
|| (echo "##[error] found changed files after build. please run 'dart tool/prepare_submit.dart'" \
"and check in all changes" \
&& exit 1)

2
.gitignore vendored
View File

@ -4,6 +4,8 @@ _*
!.gitignore
!.github
**/failures/*.png
*.iml
**/doc/api/
build/

View File

@ -1,32 +1,99 @@
## [0.2.2] - 2020-02-21
## [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]
- Support color value stored as RGB, not RGBA
## [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]
- Fix a bug with a wrongly clipped rectangle.
## [0.3.4]
- Fix a bug with dashed path
## [0.3.3]
- Fix a bug with rounded rectangle shape
## [0.3.2]
- Fix a bug with "repeater" content
## [0.3.1]
- Support dashed path
## [0.3.0+1]
- Specify a version range for the dependency on `characters`.
## [0.3.0]
- Add `LottieDelegates` a group of options to customize the lottie animation at runtime.
ie: Dynamically modify color, position, size, text... of every elements of the animation.
- Correctly display Linear and Radial Gradients
- Integrate latest changes from Lottie-android
## [0.2.2]
- Add a [repeat] parameter to specify if the automatic animation should loop.
- Add the [animate], [reverse], [repeat] properties on `LottieBuilder`
- Fix bug with `onLoaded` callback when the `LottieProvider` is changed
## [0.2.1] - 2020-02-11
## [0.2.1]
- Fix a big bug in the path transformation code. A lot more animations look correct now.
## [0.2.0+1] - 2020-02-04
## [0.2.0+1]
- Improve readme
- (internal) Add golden tests
## [0.2.0] - 2020-02-02
## [0.2.0]
- Support loading the animation and its images from a zip file
- Breaking: `LottieComposition.fromBytes` and `fromByteData` are now asynchronous.
## [0.1.4] - 2020-02-02
## [0.1.4]
- Support images in animation
- Basic support for text in animation (work in progress)
## [0.1.3] - 2020-02-01
## [0.1.3]
- Support Polystar shape
- Reorganize examples.
## [0.1.2] - 2020-01-31
## [0.1.2]
- Implement `Lottie.network`, `Lottie.file` and `Lottie.memory`
## [0.1.1] - 2020-01-31
## [0.1.1]
- Fix analysis lints
## [0.1.0] - 2020-01-31
## [0.1.0]
- Initial conversion of [lottie-android](https://github.com/airbnb/lottie-android) to Dart/Flutter

22
LICENSE
View File

@ -1 +1,21 @@
TODO: Add your license here.
MIT License
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

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)
[![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)
animations exported as json with [Bodymovin](https://github.com/bodymovin/bodymovin) and renders them natively on mobile!
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!
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 and macOS and web.
## Usage
@ -37,7 +37,7 @@ class MyApp extends StatelessWidget {
'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/lottiesfiles/angel.zip'),
Lottie.asset('assets/lottiefiles/angel.zip'),
],
),
),
@ -46,15 +46,11 @@ class MyApp extends StatelessWidget {
}
```
To load an animation from the assets folder, we need to add an `assets` section in the `pubspec.yaml`:
```yaml
flutter:
assets:
- assets/
```
### Specify a custom `AnimationController`
This example shows how to have full control over the animation by providing your own `AnimationController`.
This example shows how to take full control over the animation by providing your own `AnimationController`.
With a custom `AnimationController` you have a rich API to play the animation in various ways: start and stop the animation when you want,
play forward or backward, loop between specifics points...
```dart
import 'package:flutter/material.dart';
@ -89,8 +85,8 @@ class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
home: Scaffold(
body: ListView(
children: [
Lottie.network(
'https://raw.githubusercontent.com/xvrh/lottie-flutter/master/sample_app/assets/Mobilo/C.json',
Lottie.asset(
'assets/LottieLogo1.json',
controller: _controller,
onLoaded: (composition) {
// Configure the AnimationController with the duration of the
@ -108,6 +104,8 @@ class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
}
```
[See this file](https://github.com/xvrh/lottie-flutter/blob/master/example/lib/examples/animation_full_control.dart) for a more comprehensive example.
### Control the size of the Widget
The `Lottie` widget takes the same arguments and have the same behavior as the `Image` widget
in term of controlling its size.
@ -124,13 +122,14 @@ Lottie.asset(
animation.
### 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
cache automatically the json file.
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.
This example shows how to load and parse a Lottie composition from a json file.
```dart
class MyWidget extends StatefulWidget {
@override
@ -189,19 +188,20 @@ class CustomDrawer extends StatelessWidget {
}
class _Painter extends CustomPainter {
final LottieComposition composition;
final LottieDrawable drawable;
_Painter(this.composition);
_Painter(LottieComposition composition)
: drawable = LottieDrawable(composition);
@override
void paint(Canvas canvas, Size size) {
var drawable = LottieDrawable(composition);
var frameCount = 40;
var columns = 10;
for (var i = 0; i < frameCount; i++) {
var destRect = Offset(i % columns * 50.0, i ~/ 10 * 80.0) & (size / 5);
drawable.draw(canvas, destRect, progress: i / frameCount);
drawable
..setProgress(i / frameCount)
..draw(canvas, destRect);
}
}
@ -212,21 +212,47 @@ class _Painter extends CustomPainter {
}
````
## Limitations
This is a new library so usability, documentation and performance are still work in progress.
### Modify properties at runtime
This example shows how to modify some properties of the animation at runtime. Here we change the text,
the color, the opacity and the position of some layers.
For each `ValueDelegate` we can either provide a static `value` or a `callback` to compute a value for a each frame.
The following features are not yet implemented:
- Dash path effects
- Transforms on gradients (stroke and fills)
- Expose `Value callback` to modify dynamically some properties of the animation
- Text in animations has very basic support (unoptimized and buggy)
````dart
class _Animation extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Lottie.asset(
'assets/Tests/Shapes.json',
delegates: LottieDelegates(
text: (initialText) => '**$initialText**',
values: [
ValueDelegate.color(
const ['Shape Layer 1', 'Rectangle', 'Fill 1'],
value: Colors.red,
),
ValueDelegate.opacity(
const ['Shape Layer 1', 'Rectangle'],
callback: (frameInfo) => (frameInfo.overallProgress * 100).round(),
),
ValueDelegate.position(
const ['Shape Layer 1', 'Rectangle', '**'],
relative: Offset(100, 200),
),
],
),
);
}
}
````
## Limitations
Only the [supported features of Lottie Android](https://airbnb.io/lottie/#/supported-features)
are supported in this port.
## Flutter Web
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
## Complete example
See the Sample app (in the `example` folder) for a complete example of the various possibilities.
## More examples
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)
[![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)
animations exported as json with [Bodymovin](https://github.com/bodymovin/bodymovin) and renders them natively on mobile!
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!
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 and macOS and web.
## Usage
@ -17,23 +17,21 @@ 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.
```dart
import 'example/lib/examples/main.dart';
```
To load an animation from the assets folder, we need to add an `assets` section in the `pubspec.yaml`:
```yaml
flutter:
assets:
- assets/
import 'example/lib/main.dart';
```
### Specify a custom `AnimationController`
This example shows how to have full control over the animation by providing your own `AnimationController`.
This example shows how to take full control over the animation by providing your own `AnimationController`.
With a custom `AnimationController` you have a rich API to play the animation in various ways: start and stop the animation when you want,
play forward or backward, loop between specifics points...
```dart
import 'example/lib/examples/animation_controller.dart';
```
[See this file](https://github.com/xvrh/lottie-flutter/blob/master/example/lib/examples/animation_full_control.dart) for a more comprehensive example.
### Control the size of the Widget
The `Lottie` widget takes the same arguments and have the same behavior as the `Image` widget
in term of controlling its size.
@ -50,13 +48,14 @@ Lottie.asset(
animation.
### 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
cache automatically the json file.
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.
This example shows how to load and parse a Lottie composition from a json file.
```dart
import 'example/lib/examples/custom_load.dart#example';
```
@ -69,21 +68,23 @@ a specific position and size.
import 'example/lib/examples/custom_draw.dart#example';
````
## Limitations
This is a new library so usability, documentation and performance are still work in progress.
### Modify properties at runtime
This example shows how to modify some properties of the animation at runtime. Here we change the text,
the color, the opacity and the position of some layers.
For each `ValueDelegate` we can either provide a static `value` or a `callback` to compute a value for a each frame.
The following features are not yet implemented:
- Dash path effects
- Transforms on gradients (stroke and fills)
- Expose `Value callback` to modify dynamically some properties of the animation
- Text in animations has very basic support (unoptimized and buggy)
````dart
import 'example/lib/examples/simple_dynamic_properties.dart#example';
````
## Limitations
Only the [supported features of Lottie Android](https://airbnb.io/lottie/#/supported-features)
are supported in this port.
## Flutter Web
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
## Complete example
See the Sample app (in the `example` folder) for a complete example of the various possibilities.
## More examples
See the `example` folder for more code samples of the various possibilities.

View File

@ -3,6 +3,7 @@ analyzer:
errors:
strong-mode:
implicit-casts: false
implicit-dynamic: false
linter:
rules:
avoid_renaming_method_parameters: true

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,185 @@
{
"v": "5.5.7",
"meta": {
"g": "LottieFiles AE 0.1.14",
"a": "",
"k": "",
"d": "",
"tc": ""
},
"fr": 60,
"ip": 0,
"op": 180,
"w": 300,
"h": 300,
"nm": " Square",
"ddd": 0,
"assets": [],
"layers": [
{
"ddd": 0,
"ind": 1,
"ty": 4,
"nm": "Shape Layer 1",
"sr": 1,
"ks": {
"o": {
"a": 0,
"k": 100,
"ix": 11
},
"r": {
"a": 0,
"k": 0,
"ix": 10
},
"p": {
"a": 0,
"k": [
150,
150,
0
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100,
100
],
"ix": 6
}
},
"ao": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ty": "rc",
"d": 1,
"s": {
"a": 0,
"k": [
182.992,
182.992
],
"ix": 2
},
"p": {
"a": 0,
"k": [
0,
0
],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 4
},
"nm": "Rectangle Path 1",
"mn": "ADBE Vector Shape - Rect",
"hd": false
},
{
"ty": "fl",
"c": {
"a": 0,
"k": [
1,
0,
0,
255
],
"ix": 4
},
"o": {
"a": 0,
"k": 100,
"ix": 5
},
"r": 1,
"bm": 0,
"nm": "Fill 1",
"mn": "ADBE Vector Graphic - Fill",
"hd": false
},
{
"ty": "tr",
"p": {
"a": 0,
"k": [
-8.504,
1.496
],
"ix": 2
},
"a": {
"a": 0,
"k": [
0,
0
],
"ix": 1
},
"s": {
"a": 0,
"k": [
100,
100
],
"ix": 3
},
"r": {
"a": 0,
"k": 0,
"ix": 6
},
"o": {
"a": 0,
"k": 100,
"ix": 7
},
"sk": {
"a": 0,
"k": 0,
"ix": 4
},
"sa": {
"a": 0,
"k": 0,
"ix": 5
},
"nm": "Transform"
}
],
"nm": "Rectangle 1",
"np": 2,
"cix": 2,
"bm": 0,
"ix": 1,
"mn": "ADBE Vector Group",
"hd": false
}
],
"ip": 0,
"op": 180,
"st": 0,
"bm": 0
}
],
"markers": []
}

File diff suppressed because one or more lines are too long

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

Binary file not shown.

118232
example/assets/playing.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

3133
example/assets/tent.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

87
example/ios/Podfile Normal file
View File

@ -0,0 +1,87 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) do |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
end
end
generated_key_values
end
target 'Runner' do
use_frameworks!
use_modular_headers!
# Flutter Pod
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
# Plugin Pods
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end

28
example/ios/Podfile.lock Normal file
View File

@ -0,0 +1,28 @@
PODS:
- Flutter (1.0.0)
- path_provider (0.0.1):
- Flutter
- path_provider_macos (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
path_provider_macos:
:path: ".symlinks/plugins/path_provider_macos/ios"
SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
COCOAPODS: 1.9.1

View File

@ -9,11 +9,8 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
4E7FB8175FD7E724C16AD66F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3978ECE970E899926A99EA4E /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@ -26,8 +23,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@ -37,14 +32,16 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1B497423C23FD55DD0B8C378 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
31ACBCF01D379565237D9814 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
3978ECE970E899926A99EA4E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
5A699D4B67473B61D811D350 /* 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>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@ -57,20 +54,36 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
4E7FB8175FD7E724C16AD66F /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
14B9AAB3E57437F7B9E442AA /* Pods */ = {
isa = PBXGroup;
children = (
1B497423C23FD55DD0B8C378 /* Pods-Runner.debug.xcconfig */,
31ACBCF01D379565237D9814 /* Pods-Runner.release.xcconfig */,
5A699D4B67473B61D811D350 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
3E6BFE152BA6E928D3C57CB7 /* Frameworks */ = {
isa = PBXGroup;
children = (
3978ECE970E899926A99EA4E /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
@ -84,6 +97,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
14B9AAB3E57437F7B9E442AA /* Pods */,
3E6BFE152BA6E928D3C57CB7 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -125,12 +140,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
43690862AB1C8D2C663E62A1 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
DA3E0E6397CD983DB6281FAB /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -202,7 +219,29 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
43690862AB1C8D2C663E62A1 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
@ -218,6 +257,26 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
DA3E0E6397CD983DB6281FAB /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../Flutter/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */

View File

@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(body: _Page()),
);
}
}
class _Page extends StatefulWidget {
@override
__PageState createState() => __PageState();
}
class __PageState extends State<_Page> {
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) => _showLoader());
}
void _showLoader() {
showDialog<void>(
context: context,
builder: (context) => Center(
child: Lottie.network(
'https://assets10.lottiefiles.com/datafiles/QeC7XD39x4C1CIj/data.json',
fit: BoxFit.contain,
width: 200,
height: 200,
),
),
);
}
@override
Widget build(BuildContext context) {
return Center();
}
}

View File

@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() async {
runApp(App());
}
class App extends StatelessWidget {
const App({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.lightBlue,
home: Scaffold(
backgroundColor: Colors.lightBlue,
body: Center(
child: SizedBox(
width: 300,
height: 300,
child: Lottie.asset(
'assets/LottieLogo1.json',
animate: true,
repeat: false,
),
),
),
),
);
}
}

View File

@ -30,8 +30,8 @@ class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
home: Scaffold(
body: ListView(
children: [
Lottie.network(
'https://raw.githubusercontent.com/xvrh/lottie-flutter/master/sample_app/assets/Mobilo/C.json',
Lottie.asset(
'assets/LottieLogo1.json',
controller: _controller,
onLoaded: (composition) {
// Configure the AnimationController with the duration of the

View File

@ -0,0 +1,109 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
/// This example show how to play the Lottie animation in various way:
/// - Start and stop the animation on event callback
/// - Play the animation forward and backward
/// - Loop between two specific frames
///
/// This works by creating an AnimationController instance and passing it
/// to the Lottie widget.
/// The AnimationController class has a rich API to run the animation in various ways.
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this)
..value = 0.5
..addListener(() {
setState(() {
// Rebuild the widget at each frame to update the "progress" label.
});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Animation control'),
),
body: Column(
children: <Widget>[
const SizedBox(height: 20),
Lottie.asset(
'assets/LottieLogo1.json',
controller: _controller,
height: 300,
onLoaded: (composition) {
setState(() {
_controller.duration = composition.duration;
});
},
),
Text('${_controller.value.toStringAsFixed(2)}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Play backward
IconButton(
icon: Icon(Icons.arrow_left),
onPressed: () {
_controller.reverse();
},
),
// Pause
IconButton(
icon: Icon(Icons.pause),
onPressed: () {
_controller.stop();
},
),
// Play forward
IconButton(
icon: Icon(Icons.arrow_right),
onPressed: () {
_controller.forward();
},
),
],
),
const SizedBox(height: 30),
RaisedButton(
child: Text('Loop between frames'),
onPressed: () {
// Loop between 2 specifics frames
var start = 0.1;
var stop = 0.5;
_controller.repeat(
min: start,
max: stop,
reverse: true,
period: _controller.duration * (stop - start),
);
},
),
],
),
),
);
}
}

View File

@ -69,19 +69,20 @@ class CustomDrawer extends StatelessWidget {
}
class _Painter extends CustomPainter {
final LottieComposition composition;
final LottieDrawable drawable;
_Painter(this.composition);
_Painter(LottieComposition composition)
: drawable = LottieDrawable(composition);
@override
void paint(Canvas canvas, Size size) {
var drawable = LottieDrawable(composition);
var frameCount = 40;
var columns = 10;
for (var i = 0; i < frameCount; i++) {
var destRect = Offset(i % columns * 50.0, i ~/ 10 * 80.0) & (size / 5);
drawable.draw(canvas, destRect, progress: i / frameCount);
drawable
..setProgress(i / frameCount)
..draw(canvas, destRect);
}
}

View File

@ -0,0 +1,86 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:lottie/lottie.dart';
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 {
Color _color = Colors.green;
double _opacity = 0.5;
bool _useDelegates = true;
@override
Widget build(BuildContext context) {
var valueDelegates = [
ValueDelegate.color(['Shape Layer 1', 'Rectangle', 'Fill 1'],
value: _color),
ValueDelegate.opacity(['Shape Layer 1', 'Rectangle', 'Fill 1'],
callback: (_) => (_opacity * 100).round()),
];
return MaterialApp(
color: Colors.blue,
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Dynamic properties'),
),
body: ListView(
children: <Widget>[
SizedBox(
width: 300,
height: 300,
child: Lottie.asset(
'assets/Tests/Shapes.json',
delegates: LottieDelegates(
values: _useDelegates ? valueDelegates : null),
),
),
Checkbox(
value: _useDelegates,
onChanged: (newValue) {
setState(() {
_useDelegates = newValue;
});
},
),
Slider(
value: _opacity,
onChanged: (newOpacity) {
setState(() {
_opacity = newOpacity;
});
},
),
Center(
child: Container(
width: 500,
child: ColorPicker(
pickerColor: _color,
onColorChanged: (newColor) {
setState(() {
_color = newColor;
});
},
showLabel: false,
enableAlpha: false,
pickerAreaHeightPercent: 0.8,
),
),
),
],
),
),
);
}
}

View File

@ -0,0 +1,72 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
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 {
TextEditingController _textController;
@override
void initState() {
super.initState();
_textController = TextEditingController(text: /*'🔥Fire🔥'*/ 'Fire');
}
@override
void dispose() {
_textController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.blue,
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Dynamic text'),
),
body: Center(
child: Column(
children: <Widget>[
SizedBox(
width: 300,
height: 300,
child: Lottie.asset(
'assets/Tests/DynamicText.json',
delegates: LottieDelegates(
text: (animationText) => _textController.text,
textStyle: (font) => TextStyle(
fontFamily: font.fontFamily,
fontStyle: FontStyle.italic),
),
),
),
Container(
width: 300,
child: CupertinoTextField(
controller: _textController,
onChanged: (newText) {
setState(() {});
},
),
)
],
),
),
),
);
}
}

View File

@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
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 {
AnimationController _animationController;
bool _showAnimation = true;
@override
void initState() {
super.initState();
_animationController = AnimationController(vsync: this)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
setState(() {
_showAnimation = false;
});
}
});
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.lightBlue,
home: Scaffold(
backgroundColor: Colors.lightBlue,
appBar: AppBar(
title: Text('Show lottie animation: $_showAnimation'),
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
if (_showAnimation)
Lottie.asset(
'assets/LottieLogo1.json',
controller: _animationController,
width: 200,
onLoaded: (composition) {
_animationController
..duration = composition.duration
..reset()
..forward();
},
),
],
),
),
),
),
);
}
}

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/lottiesfiles/angel.zip'),
],
),
),
);
}
}

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

@ -0,0 +1,71 @@
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart';
import '../src/all_files.g.dart';
void main() async {
Logger.root
..level = Level.ALL
..onRecord.listen(print);
runApp(App());
}
class App extends StatefulWidget {
const App({Key key}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> with TickerProviderStateMixin {
int _index = 0;
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController = AnimationController(vsync: this)
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
setState(() {
++_index;
});
}
});
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.lightBlue,
home: Scaffold(
backgroundColor: Colors.lightBlue,
appBar: AppBar(
title: Text('$_index'),
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
Lottie.asset(files[_index % files.length],
controller: _animationController, onLoaded: (composition) {
_animationController
..duration = composition.duration
..reset()
..forward();
}),
],
),
),
),
),
);
}
}

View File

@ -0,0 +1,100 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lottie/lottie.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
/// This example shows how to save the frame of an animation to files on disk.
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<File> _frames;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey,
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
RaisedButton(
child: Text('Export all frames'),
onPressed: _export,
),
if (_frames != null)
Expanded(
child: GridView.count(
crossAxisCount: 10,
children: [..._frames.map((f) => Image.file(f))],
),
)
],
),
),
),
);
}
Future<void> _export() async {
var composition =
await AssetLottie('assets/lottiefiles/airbnb.json').load();
var frames = await exportFrames(
composition, await _createTempDirectory('export-lottie'),
progresses: [for (var i = 0.0; i <= 1; i += 0.1) i],
size: Size(50, 50));
setState(() {
_frames = frames;
});
}
}
Future<List<File>> exportFrames(LottieComposition composition, String directory,
{@required Size size, @required List<double> progresses}) async {
var drawable = LottieDrawable(composition);
var frames = <File>[];
for (var progress in progresses) {
drawable.setProgress(progress);
var bytes = await _toByteData(drawable, size);
var fileName = (progress * 100).round().toString().padLeft(3, '0');
var file = File(p.join(directory, '$fileName.png'));
await file.writeAsBytes(bytes.buffer.asUint8List());
frames.add(file);
}
return frames;
}
Future<ByteData> _toByteData(LottieDrawable drawable, Size size) async {
var pictureRecorder = PictureRecorder();
var canvas = Canvas(pictureRecorder);
drawable.draw(canvas, Offset.zero & size);
var picture = pictureRecorder.endRecording();
var image = await picture.toImage(size.width.toInt(), size.height.toInt());
return await image.toByteData(format: ImageByteFormat.png);
}
Future<String> _createTempDirectory(String folderName) async {
final tempDirectory = await getTemporaryDirectory();
var dir = Directory(p.join(tempDirectory.path, folderName));
if (!dir.existsSync()) {
await dir.create(recursive: true);
}
return dir.path;
}

View File

@ -0,0 +1,45 @@
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: [_Animation()],
),
),
);
}
}
//--- example
class _Animation extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Lottie.asset(
'assets/Tests/Shapes.json',
delegates: LottieDelegates(
text: (initialText) => '**$initialText**',
values: [
ValueDelegate.color(
const ['Shape Layer 1', 'Rectangle', 'Fill 1'],
value: Colors.red,
),
ValueDelegate.opacity(
const ['Shape Layer 1', 'Rectangle'],
callback: (frameInfo) => (frameInfo.overallProgress * 100).round(),
),
ValueDelegate.position(
const ['Shape Layer 1', 'Rectangle', '**'],
relative: Offset(100, 200),
),
],
),
);
}
}
//---

View File

@ -1,159 +1,24 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart';
import 'package:lottie/src/l.dart';
import 'src/all_files.g.dart';
void main() {
Logger.root
..level = Level.ALL
..onRecord.listen(print);
L.setTraceEnabled(true);
runApp(App());
}
void main() => runApp(MyApp());
class App extends StatelessWidget {
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
//showPerformanceOverlay: true,
home: Scaffold(
appBar: AppBar(
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(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,
//border: Border.all(color: Colors.black12),
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(
body: ListView(
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();
}
});
},
),
],
),
),
// 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'),
],
),
),

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

@ -0,0 +1,160 @@
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: 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: [
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

@ -1,341 +1,355 @@
// Generated from tool/generate_file_list.dart
final files = [
'assets/14595-thumbs-up.json',
'assets/Mobilo/T.json',
'assets/17297-fireworks.json',
'assets/AndroidWave.json',
'assets/DynamicGradient.json',
'assets/HamburgerArrow.json',
'assets/Logo/LogoSmall.json',
'assets/LottieLogo1.json',
'assets/LottieLogo2.json',
'assets/Mobilo/A.json',
'assets/Mobilo/X.json',
'assets/Mobilo/BlinkingCursor.json',
'assets/Mobilo/M.json',
'assets/Mobilo/L.json',
'assets/Mobilo/Y.json',
'assets/Mobilo/U.json',
'assets/Mobilo/K.json',
'assets/Mobilo/R.json',
'assets/Mobilo/G.json',
'assets/Mobilo/F.json',
'assets/Mobilo/S.json',
'assets/Mobilo/J.json',
'assets/Mobilo/I.json',
'assets/Mobilo/E.json',
'assets/Mobilo/Apostrophe.json',
'assets/Mobilo/B.json',
'assets/Mobilo/BlinkingCursor.json',
'assets/Mobilo/C.json',
'assets/Mobilo/Colon.json',
'assets/Mobilo/Comma.json',
'assets/Mobilo/D.json',
'assets/Mobilo/E.json',
'assets/Mobilo/F.json',
'assets/Mobilo/G.json',
'assets/Mobilo/H.json',
'assets/Mobilo/I.json',
'assets/Mobilo/J.json',
'assets/Mobilo/K.json',
'assets/Mobilo/L.json',
'assets/Mobilo/M.json',
'assets/Mobilo/N.json',
'assets/Mobilo/O.json',
'assets/Mobilo/P.json',
'assets/Mobilo/Q.json',
'assets/Mobilo/D.json',
'assets/Mobilo/Colon.json',
'assets/Mobilo/H.json',
'assets/Mobilo/C.json',
'assets/Mobilo/R.json',
'assets/Mobilo/S.json',
'assets/Mobilo/T.json',
'assets/Mobilo/U.json',
'assets/Mobilo/V.json',
'assets/Mobilo/Comma.json',
'assets/Mobilo/O.json',
'assets/Mobilo/Z.json',
'assets/Mobilo/N.json',
'assets/Mobilo/W.json',
'assets/Mobilo/B.json',
'assets/HamburgerArrow.json',
'assets/Tests/Remap.json',
'assets/Tests/Airbnb400.zip',
'assets/Tests/catrim_converted.json',
'assets/Tests/StartEndFrame.json',
'assets/Tests/TrackMattes.json',
'assets/Tests/DynamicText.json',
'assets/Tests/Precomps.json',
'assets/Tests/2ParentsMatte.json',
'assets/Mobilo/X.json',
'assets/Mobilo/Y.json',
'assets/Mobilo/Z.json',
'assets/Tests/2FrameAnimation.json',
'assets/Tests/LoopPlayOnce.json',
'assets/Tests/bm_converted.json',
'assets/Tests/RGBMarker.json',
'assets/Tests/WeAccept.json',
'assets/Tests/MiterLimit.json',
'assets/Tests/dalek.json',
'assets/Tests/MaskInv.json',
'assets/Tests/MatteTimeStretchScan.json',
'assets/Tests/Marker.json',
'assets/Tests/TrimPathsInsideAndOutsideGroup.json',
'assets/Tests/MaskNone.json',
'assets/Tests/Text_Justification_Translate_Scale_Rotation_Text.json',
'assets/Tests/InterpolatorLoopBack.json',
'assets/Tests/SplitDimensions.json',
'assets/Tests/EndFrame.json',
'assets/Tests/RGB.json',
'assets/Tests/DynamicGradient.json',
'assets/Tests/Font_Text_Justification_Translate_Scale_Rotation_Test.json',
'assets/Tests/adrock_converted.json',
'assets/Tests/ShapeTypes.json',
'assets/Tests/Squares.json',
'assets/Tests/Parenting.json',
'assets/Tests/catrim.json',
'assets/Tests/Stroke.json',
'assets/Tests/TimeStretch.json',
'assets/Tests/CheckSwitch.json',
'assets/Tests/hd.json',
'assets/Tests/OverlapShapeWithOpacity.json',
'assets/Tests/Shapes.json',
'assets/Tests/Masks.json',
'assets/Tests/SolidLayerTransform.json',
'assets/Tests/WeAcceptInlineImage.json',
'assets/Tests/TrimPaths.json',
'assets/Tests/2ParentsMatte.json',
'assets/Tests/Airbnb.zip',
'assets/Tests/DifferentPointsCount.json',
'assets/Tests/Skew.json',
'assets/Tests/GradientFill.json',
'assets/Tests/TransformWithoutEndValues.json',
'assets/Tests/EllipseDirection.json',
'assets/Tests/TimeStretchMask.json',
'assets/Tests/Frame.json',
'assets/Tests/map.zip',
'assets/Tests/august_view_pulse.zip',
'assets/Tests/KeyframeTypes.json',
'assets/Tests/dalek_converted.json',
'assets/Tests/Laugh4.json',
'assets/Tests/Scale0.json',
'assets/Tests/StarSkew.json',
'assets/Tests/TextBaseline.json',
'assets/Tests/Text.json',
'assets/Tests/bm.json',
'assets/Tests/Fill.json',
'assets/Tests/MaskA.json',
'assets/Tests/Repeater.json',
'assets/Tests/TimeStretchPrecomp.json',
'assets/Tests/adrock.json',
'assets/Tests/MatteTimeStretchLine.json',
'assets/Tests/Airbnb400.zip',
'assets/Tests/Airbnb800.zip',
'assets/DynamicGradient.json',
'assets/LottieLogo2.json',
'assets/AndroidWave.json',
'assets/LottieLogo1.json',
'assets/Logo/LogoSmall.json',
'assets/lottiefiles/the_final_frontier.json',
'assets/Tests/CheckSwitch.json',
'assets/Tests/DifferentPointsCount.json',
'assets/Tests/DynamicGradient.json',
'assets/Tests/DynamicText.json',
'assets/Tests/EllipseDirection.json',
'assets/Tests/EndFrame.json',
'assets/Tests/Fill.json',
'assets/Tests/Font_Text_Justification_Translate_Scale_Rotation_Test.json',
'assets/Tests/Frame.json',
'assets/Tests/GradientFill.json',
'assets/Tests/InterpolatorLoopBack.json',
'assets/Tests/KeyframeTypes.json',
'assets/Tests/Laugh4.json',
'assets/Tests/LoopPlayOnce.json',
'assets/Tests/Marker.json',
'assets/Tests/MaskA.json',
'assets/Tests/MaskInv.json',
'assets/Tests/MaskNone.json',
'assets/Tests/Masks.json',
'assets/Tests/MatteTimeStretchLine.json',
'assets/Tests/MatteTimeStretchScan.json',
'assets/Tests/MiterLimit.json',
'assets/Tests/OverlapShapeWithOpacity.json',
'assets/Tests/Parenting.json',
'assets/Tests/Precomps.json',
'assets/Tests/RGB.json',
'assets/Tests/RGBMarker.json',
'assets/Tests/Remap.json',
'assets/Tests/Repeater.json',
'assets/Tests/Scale0.json',
'assets/Tests/ShapeTypes.json',
'assets/Tests/Shapes.json',
'assets/Tests/Skew.json',
'assets/Tests/SolidLayerTransform.json',
'assets/Tests/SplitDimensions.json',
'assets/Tests/Squares.json',
'assets/Tests/StarSkew.json',
'assets/Tests/StartEndFrame.json',
'assets/Tests/Stroke.json',
'assets/Tests/TelegramAlphaCompat.json',
'assets/Tests/Text.json',
'assets/Tests/TextBaseline.json',
'assets/Tests/Text_Justification_Translate_Scale_Rotation_Text.json',
'assets/Tests/TimeRemapAndStartOffset.json',
'assets/Tests/TimeStretch.json',
'assets/Tests/TimeStretchMask.json',
'assets/Tests/TimeStretchPrecomp.json',
'assets/Tests/TrackMattes.json',
'assets/Tests/TransformWithoutEndValues.json',
'assets/Tests/TrimPaths.json',
'assets/Tests/TrimPathsInsideAndOutsideGroup.json',
'assets/Tests/WeAccept.json',
'assets/Tests/WeAcceptInlineImage.json',
'assets/Tests/adrock.json',
'assets/Tests/adrock_converted.json',
'assets/Tests/august_view_pulse.zip',
'assets/Tests/bm.json',
'assets/Tests/bm_converted.json',
'assets/Tests/catrim.json',
'assets/Tests/catrim_converted.json',
'assets/Tests/dalek.json',
'assets/Tests/dalek_converted.json',
'assets/Tests/hd.json',
'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/lottiefiles/100_percent.json',
'assets/lottiefiles/Plane.json',
'assets/lottiefiles/StreetByMorning.json',
'assets/lottiefiles/___.json',
'assets/lottiefiles/a_mountain.json',
'assets/lottiefiles/accept_arrows.json',
'assets/lottiefiles/airbnb.json',
'assets/lottiefiles/android_fingerprint.json',
'assets/lottiefiles/angel.zip',
'assets/lottiefiles/anima.json',
'assets/lottiefiles/animated_graph.json',
'assets/lottiefiles/animated_laptop_.json',
'assets/lottiefiles/animated_logo.json',
'assets/lottiefiles/atm_link.json',
'assets/lottiefiles/autoconnect_loading.json',
'assets/lottiefiles/ball_&_map.zip',
'assets/lottiefiles/banner_animation.json',
'assets/lottiefiles/bb8.json',
'assets/lottiefiles/bell.json',
'assets/lottiefiles/birds.json',
'assets/lottiefiles/bitcoin_to_the_moon.json',
'assets/lottiefiles/blood_transfusion_kawaii.json',
'assets/lottiefiles/bomb.json',
'assets/lottiefiles/books.json',
'assets/lottiefiles/bootymovin.json',
'assets/lottiefiles/bounching_ball.json',
'assets/lottiefiles/brain__.json',
'assets/lottiefiles/browser.json',
'assets/lottiefiles/building_evolution_animation.json',
'assets/lottiefiles/camera.json',
'assets/lottiefiles/camptravel.zip',
'assets/lottiefiles/cancel_button.json',
'assets/lottiefiles/cash.json',
'assets/lottiefiles/change_to_search_bar.json',
'assets/lottiefiles/check_pop.json',
'assets/lottiefiles/chinese.json',
'assets/lottiefiles/clock.json',
'assets/lottiefiles/cloud_disconnection.json',
'assets/lottiefiles/code_invite_success.json',
'assets/lottiefiles/coding_ape.json',
'assets/lottiefiles/coinfall.json',
'assets/lottiefiles/colorline.json',
'assets/lottiefiles/confusion.json',
'assets/lottiefiles/construction_site.json',
'assets/lottiefiles/cooking_app.json',
'assets/lottiefiles/countdown.json',
'assets/lottiefiles/credit_card.json',
'assets/lottiefiles/credit_level.json',
'assets/lottiefiles/cube_loader.json',
'assets/lottiefiles/cubo_livre.json',
'assets/lottiefiles/curly_hair_character_loop.json',
'assets/lottiefiles/cycle_animation.json',
'assets/lottiefiles/day_night_cycle.json',
'assets/lottiefiles/day_of_the_dead.json',
'assets/lottiefiles/deadpool.json',
'assets/lottiefiles/delivery_van.json',
'assets/lottiefiles/developer-animation.zip',
'assets/lottiefiles/dna_loader.json',
'assets/lottiefiles/dog.json',
'assets/lottiefiles/done.json',
'assets/lottiefiles/download copy.json',
'assets/lottiefiles/download.json',
'assets/lottiefiles/downloader.json',
'assets/lottiefiles/drop.json',
'assets/lottiefiles/drop_to_refresh.json',
'assets/lottiefiles/edited-landscape.json',
'assets/lottiefiles/elephant_trunk_swing.json',
'assets/lottiefiles/emoji_shock.json',
'assets/lottiefiles/emoji_tongue.json',
'assets/lottiefiles/emoji_wink.json',
'assets/lottiefiles/empty_status.json',
'assets/lottiefiles/estimate.json',
'assets/lottiefiles/fab_animate.json',
'assets/lottiefiles/fabulous_onboarding_animation.json',
'assets/lottiefiles/favourite_app_icon.json',
'assets/lottiefiles/file_error.json',
'assets/lottiefiles/finance_animation.json',
'assets/lottiefiles/fingerprint_scanner.json',
'assets/lottiefiles/finish,done.json',
'assets/lottiefiles/fish.json',
'assets/lottiefiles/flag_of_mexico.json',
'assets/lottiefiles/flow.json',
'assets/lottiefiles/frog.json',
'assets/lottiefiles/funky_chicken.json',
'assets/lottiefiles/gaming_pad.json',
'assets/lottiefiles/gears.json',
'assets/lottiefiles/geometry.zip',
'assets/lottiefiles/glow_loading.json',
'assets/lottiefiles/gradient_animated_background.json',
'assets/lottiefiles/happy birthday.json',
'assets/lottiefiles/hardware.json',
'assets/lottiefiles/hint_01.json',
'assets/lottiefiles/im_thirsty.json',
'assets/lottiefiles/immiguide_.json',
'assets/lottiefiles/in-app_purchasing.json',
'assets/lottiefiles/india.json',
'assets/lottiefiles/infinite_rainbow.json',
'assets/lottiefiles/intelia_logo_animation.json',
'assets/lottiefiles/iphone_x_loading.json',
'assets/lottiefiles/jojo_the_bird.json',
'assets/lottiefiles/jolly_walker.json',
'assets/lottiefiles/judgement.json',
'assets/lottiefiles/kod.io_logo_reveal.json',
'assets/lottiefiles/la_calavera.json',
'assets/lottiefiles/landing_page.json',
'assets/lottiefiles/lego_loader.json',
'assets/lottiefiles/light.json',
'assets/lottiefiles/lightsaber.json',
'assets/lottiefiles/little_girl_jumping_-_loader.json',
'assets/lottiefiles/loading.json',
'assets/lottiefiles/loading_copy.json',
'assets/lottiefiles/loading_disc.json',
'assets/lottiefiles/loading_semicircle.json',
'assets/lottiefiles/location.json',
'assets/lottiefiles/location_marker.json',
'assets/lottiefiles/location_pin.json',
'assets/lottiefiles/lottie_logo_1.json',
'assets/lottiefiles/lottiepreview_qr.json',
'assets/lottiefiles/mailsent.json',
'assets/lottiefiles/man_and_pay_with_credit_card.json',
'assets/lottiefiles/map_animation.json',
'assets/lottiefiles/material loading.json',
'assets/lottiefiles/material_loader.json',
'assets/lottiefiles/material_loading_2.json',
'assets/lottiefiles/material_wave_loading.json',
'assets/lottiefiles/finish,done.json',
'assets/lottiefiles/rocket.json',
'assets/lottiefiles/chinese.json',
'assets/lottiefiles/cubo_livre.json',
'assets/lottiefiles/slack_app_loader.json',
'assets/lottiefiles/no_internet_connection.json',
'assets/lottiefiles/moving_eye.json',
'assets/lottiefiles/downloader.json',
'assets/lottiefiles/poo_loader.json',
'assets/lottiefiles/airbnb.json',
'assets/lottiefiles/phonological.json',
'assets/lottiefiles/camptravel.zip',
'assets/lottiefiles/bounching_ball.json',
'assets/lottiefiles/walking.json',
'assets/lottiefiles/coding_ape.json',
'assets/lottiefiles/clock.json',
'assets/lottiefiles/timer_(3_second_loop).json',
'assets/lottiefiles/file_error.json',
'assets/lottiefiles/android_fingerprint.json',
'assets/lottiefiles/patient_successfully_added.json',
'assets/lottiefiles/toggle_switch.json',
'assets/lottiefiles/notification_request.json',
'assets/lottiefiles/loading disc.json',
'assets/lottiefiles/tractor_animation.json',
'assets/lottiefiles/Plane.json',
'assets/lottiefiles/retweet.json',
'assets/lottiefiles/blood_transfusion_kawaii.json',
'assets/lottiefiles/truecosmos.json',
'assets/lottiefiles/banner_animation.json',
'assets/lottiefiles/gears.json',
'assets/lottiefiles/progress_bar 2.json',
'assets/lottiefiles/flag_of_mexico.json',
'assets/lottiefiles/location_pin.json',
'assets/lottiefiles/play,_pause.json',
'assets/lottiefiles/panel2d.json',
'assets/lottiefiles/emoji_tongue.json',
'assets/lottiefiles/jolly_walker.json',
'assets/lottiefiles/switch_loop.json',
'assets/lottiefiles/intelia_logo_animation.json',
'assets/lottiefiles/credit_card.json',
'assets/lottiefiles/empty_status.json',
'assets/lottiefiles/autoconnect_loading.json',
'assets/lottiefiles/camera.json',
'assets/lottiefiles/volume_indicator.json',
'assets/lottiefiles/bell.json',
'assets/lottiefiles/colorline.json',
'assets/lottiefiles/mailsent.json',
'assets/lottiefiles/square_drop_loader.json',
'assets/lottiefiles/gradient_animated_background.json',
'assets/lottiefiles/vr_animation.json',
'assets/lottiefiles/rocksauce_title_card.json',
'assets/lottiefiles/streetby_test_loading.json',
'assets/lottiefiles/hardware.json',
'assets/lottiefiles/man_and_pay_with_credit_card.json',
'assets/lottiefiles/tractor.json',
'assets/lottiefiles/brain__.json',
'assets/lottiefiles/summer.json',
'assets/lottiefiles/passport.json',
'assets/lottiefiles/drop_to_refresh.json',
'assets/lottiefiles/penguin.json',
'assets/lottiefiles/location_marker.json',
'assets/lottiefiles/dna_loader.json',
'assets/lottiefiles/geometry.zip',
'assets/lottiefiles/pink_drink_machine.json',
'assets/lottiefiles/sensor_scan.zip',
'assets/lottiefiles/fingerprint_scanner.json',
'assets/lottiefiles/play_button.json',
'assets/lottiefiles/jojo_the_bird.json',
'assets/lottiefiles/cloud_disconnection.json',
'assets/lottiefiles/dog.json',
'assets/lottiefiles/loading.json',
'assets/lottiefiles/curly_hair_character_loop.json',
'assets/lottiefiles/india.json',
'assets/lottiefiles/anima.json',
'assets/lottiefiles/volume_shake_indicator.json',
'assets/lottiefiles/rating.json',
'assets/lottiefiles/birds.json',
'assets/lottiefiles/in-app_purchasing.json',
'assets/lottiefiles/rejection.json',
'assets/lottiefiles/judgement.json',
'assets/lottiefiles/splashy_loader.json',
'assets/lottiefiles/construction_site.json',
'assets/lottiefiles/download.json',
'assets/lottiefiles/uk.json',
'assets/lottiefiles/location.json',
'assets/lottiefiles/change_to_search_bar.json',
'assets/lottiefiles/x_pop.json',
'assets/lottiefiles/socar_logo.json',
'assets/lottiefiles/fish.json',
'assets/lottiefiles/landing_page.json',
'assets/lottiefiles/turbine.json',
'assets/lottiefiles/ofrenda.json',
'assets/lottiefiles/emoji_shock.json',
'assets/lottiefiles/sky.zip',
'assets/lottiefiles/bb8.json',
'assets/lottiefiles/powerupp_app_onboard (1).json',
'assets/lottiefiles/im_thirsty.json',
'assets/lottiefiles/permission.json',
'assets/lottiefiles/animated_logo.json',
'assets/lottiefiles/youtube_icon_reveal.json',
'assets/lottiefiles/fab_animate.json',
'assets/lottiefiles/money.json',
'assets/lottiefiles/pagado.json',
'assets/lottiefiles/servishero_loading.json',
'assets/lottiefiles/me_at_office.json',
'assets/lottiefiles/swiftkey-logo.json',
'assets/lottiefiles/favourite_app_icon.json',
'assets/lottiefiles/atm_link.json',
'assets/lottiefiles/emoji_wink.json',
'assets/lottiefiles/preloader.json',
'assets/lottiefiles/us.json',
'assets/lottiefiles/soda_loader.json',
'assets/lottiefiles/medal.json',
'assets/lottiefiles/menuButton2.json',
'assets/lottiefiles/menu_button_alt.json',
'assets/lottiefiles/mindful.json',
'assets/lottiefiles/mnemonics.json',
'assets/lottiefiles/money.json',
'assets/lottiefiles/motorcycle.json',
'assets/lottiefiles/moving bus.json',
'assets/lottiefiles/moving_eye.json',
'assets/lottiefiles/no_internet_connection.json',
'assets/lottiefiles/notification_request.json',
'assets/lottiefiles/octopus.json',
'assets/lottiefiles/ofrenda.json',
'assets/lottiefiles/on_off_settings_switch.json',
'assets/lottiefiles/pagado.json',
'assets/lottiefiles/pagination.json',
'assets/lottiefiles/panel2d.json',
'assets/lottiefiles/passport.json',
'assets/lottiefiles/patient_successfully_added.json',
'assets/lottiefiles/payme.json',
'assets/lottiefiles/peli-canon.json',
'assets/lottiefiles/pen_tool_loop.json',
'assets/lottiefiles/pencil_write.json',
'assets/lottiefiles/penguin.json',
'assets/lottiefiles/permission.json',
'assets/lottiefiles/personal_character.json',
'assets/lottiefiles/ph_onboarding_.json',
'assets/lottiefiles/phonological.json',
'assets/lottiefiles/pink_drink_machine.json',
'assets/lottiefiles/plane_to_dollar.json',
'assets/lottiefiles/play,_pause.json',
'assets/lottiefiles/play_and_like_it.json',
'assets/lottiefiles/play_button.json',
'assets/lottiefiles/playing.json',
'assets/lottiefiles/point.json',
'assets/lottiefiles/poo_loader.json',
'assets/lottiefiles/powerupp_app_onboard (1).json',
'assets/lottiefiles/powerupp_app_onboard.json',
'assets/lottiefiles/preloader.json',
'assets/lottiefiles/print.json',
'assets/lottiefiles/progress_bar 2.json',
'assets/lottiefiles/progress_bar.json',
'assets/lottiefiles/rating.json',
'assets/lottiefiles/red_pocket_pop_up.json',
'assets/lottiefiles/rejection.json',
'assets/lottiefiles/retweet.json',
'assets/lottiefiles/rocket.json',
'assets/lottiefiles/rocksauce_title_card.json',
'assets/lottiefiles/scan.json',
'assets/lottiefiles/scan_qr_code_success.json',
'assets/lottiefiles/search_button.json',
'assets/lottiefiles/security_token_roundtable.zip',
'assets/lottiefiles/sensor_scan.zip',
'assets/lottiefiles/servishero_loading.json',
'assets/lottiefiles/simple_loader.json',
'assets/lottiefiles/sky.zip',
'assets/lottiefiles/slack_app_loader.json',
'assets/lottiefiles/snowcation.json',
'assets/lottiefiles/socar_logo.json',
'assets/lottiefiles/soda_loader.json',
'assets/lottiefiles/spacehub.json',
'assets/lottiefiles/spinner loading.json',
'assets/lottiefiles/splashy_loader.json',
'assets/lottiefiles/square_drop_loader.json',
'assets/lottiefiles/star 2.json',
'assets/lottiefiles/streetby_test_loading.json',
'assets/lottiefiles/submit button.json',
'assets/lottiefiles/summer.json',
'assets/lottiefiles/sushi_and_wine.zip',
'assets/lottiefiles/swiftkey-logo.json',
'assets/lottiefiles/swipe_menu.json',
'assets/lottiefiles/swipe_right_indicator.json',
'assets/lottiefiles/switch_loop.json',
'assets/lottiefiles/the_final_frontier.json',
'assets/lottiefiles/tigerobo_demo.json',
'assets/lottiefiles/timer_(3_second_loop).json',
'assets/lottiefiles/toggle.json',
'assets/lottiefiles/toggle_switch.json',
'assets/lottiefiles/touch_id.json',
'assets/lottiefiles/tractor.json',
'assets/lottiefiles/tractor_animation.json',
'assets/lottiefiles/trail_loading.json',
'assets/lottiefiles/trophy.json',
'assets/lottiefiles/trophy_animation.zip',
'assets/lottiefiles/countdown.json',
'assets/lottiefiles/glow_loading.json',
'assets/lottiefiles/developer-animation.zip',
'assets/lottiefiles/bitcoin_to_the_moon.json',
'assets/lottiefiles/credit_level.json',
'assets/lottiefiles/medal.json',
'assets/lottiefiles/xamarin_logo_2.json',
'assets/lottiefiles/loading copy.json',
'assets/lottiefiles/done.json',
'assets/lottiefiles/plane_to_dollar.json',
'assets/lottiefiles/octopus.json',
'assets/lottiefiles/finance_animation.json',
'assets/lottiefiles/download copy.json',
'assets/lottiefiles/frog.json',
'assets/lottiefiles/yoga_carpet.json',
'assets/lottiefiles/sushi_and_wine.zip',
'assets/lottiefiles/payme.json',
'assets/lottiefiles/lego_loader.json',
'assets/lottiefiles/deadpool.json',
'assets/lottiefiles/updating_map.json',
'assets/lottiefiles/elephant_trunk_swing.json',
'assets/lottiefiles/lottie_logo_1.json',
'assets/lottiefiles/tigerobo_demo.json',
'assets/lottiefiles/100_percent.json',
'assets/lottiefiles/flow.json',
'assets/lottiefiles/hint_01.json',
'assets/lottiefiles/moving bus.json',
'assets/lottiefiles/light.json',
'assets/lottiefiles/little_girl_jumping_-_loader.json',
'assets/lottiefiles/red_pocket_pop_up.json',
'assets/lottiefiles/star 2.json',
'assets/lottiefiles/playing.json',
'assets/lottiefiles/motorcycle.json',
'assets/lottiefiles/submit button.json',
'assets/lottiefiles/infinite_rainbow.json',
'assets/lottiefiles/print.json',
'assets/lottiefiles/powerupp_app_onboard.json',
'assets/lottiefiles/cycle_animation.json',
'assets/lottiefiles/vigilance_camera.json',
'assets/lottiefiles/code_invite_success.json',
'assets/lottiefiles/walking_arrow.json',
'assets/lottiefiles/pen_tool_loop.json',
'assets/lottiefiles/mnemonics.json',
'assets/lottiefiles/bootymovin.json',
'assets/lottiefiles/happy birthday.json',
'assets/lottiefiles/books.json',
'assets/lottiefiles/angel.zip',
'assets/lottiefiles/building_evolution_animation.json',
'assets/lottiefiles/edited-landscape.json',
'assets/lottiefiles/spinner loading.json',
'assets/lottiefiles/accept_arrows.json',
'assets/lottiefiles/mindful.json',
'assets/lottiefiles/gaming_pad.json',
'assets/lottiefiles/menuButton2.json',
'assets/lottiefiles/wolf_peek.json',
'assets/lottiefiles/security_token_roundtable.zip',
'assets/lottiefiles/day_night_cycle.json',
'assets/lottiefiles/cancel_button.json',
'assets/lottiefiles/menu_button_alt.json',
'assets/lottiefiles/animated_graph.json',
'assets/lottiefiles/point.json',
'assets/lottiefiles/search_button.json',
'assets/lottiefiles/a_mountain.json',
'assets/lottiefiles/on_off_settings_switch.json',
'assets/lottiefiles/truecosmos.json',
'assets/lottiefiles/turbine.json',
'assets/lottiefiles/typing dot.json',
'assets/lottiefiles/kod.io_logo_reveal.json',
'assets/lottiefiles/___.json',
'assets/lottiefiles/animated_laptop_.json',
'assets/lottiefiles/simple_loader.json',
'assets/lottiefiles/personal_character.json',
'assets/lottiefiles/check_pop.json',
'assets/lottiefiles/xuanwheel_logo.json',
'assets/lottiefiles/lightsaber.json',
'assets/lottiefiles/peli-canon.json',
'assets/lottiefiles/map_animation.json',
'assets/lottiefiles/funky_chicken.json',
'assets/lottiefiles/ball_&_map.zip',
'assets/lottiefiles/snowcation.json',
'assets/lottiefiles/estimate.json',
'assets/lottiefiles/delivery_van.json',
'assets/lottiefiles/spacehub.json',
'assets/lottiefiles/material loading.json',
'assets/lottiefiles/swipe_right_indicator.json',
'assets/lottiefiles/pagination.json',
'assets/lottiefiles/confusion.json',
'assets/lottiefiles/coinfall.json',
'assets/lottiefiles/fabulous_onboarding_animation.json',
'assets/lottiefiles/win_result_2.json',
'assets/lottiefiles/scan.json',
'assets/lottiefiles/la_calavera.json',
'assets/lottiefiles/drop.json',
'assets/lottiefiles/scan_qr_code_success.json',
'assets/lottiefiles/loading_semicircle.json',
'assets/lottiefiles/immiguide_.json',
'assets/lottiefiles/vr_sickness.json',
'assets/lottiefiles/cash.json',
'assets/lottiefiles/ph_onboarding_.json',
'assets/lottiefiles/uk.json',
'assets/lottiefiles/updating_map.json',
'assets/lottiefiles/us.json',
'assets/lottiefiles/video_cam.json',
'assets/lottiefiles/material_loader.json',
'assets/lottiefiles/toggle.json',
'assets/lottiefiles/browser.json',
'assets/lottiefiles/day_of_the_dead.json',
'assets/lottiefiles/cube_loader.json',
'assets/lottiefiles/washing_machine.json',
'assets/lottiefiles/vigilance_camera.json',
'assets/lottiefiles/volume_indicator.json',
'assets/lottiefiles/volume_shake_indicator.json',
'assets/lottiefiles/vr_animation.json',
'assets/lottiefiles/vr_sickness.json',
'assets/lottiefiles/walking.json',
'assets/lottiefiles/walking_arrow.json',
'assets/lottiefiles/wallet recharge.json',
'assets/lottiefiles/pencil_write.json',
'assets/lottiefiles/progress_bar.json',
'assets/lottiefiles/iphone_x_loading.json',
'assets/lottiefiles/bomb.json',
'assets/lottiefiles/swipe_menu.json',
'assets/lottiefiles/trail_loading.json',
'assets/lottiefiles/StreetByMorning.json',
'assets/lottiefiles/cooking_app.json',
'assets/lottiefiles/lottiepreview_qr.json',
'assets/lottiefiles/touch_id.json',
'assets/lf20_w2Afea.json',
'assets/lottiefiles/washing_machine.json',
'assets/lottiefiles/win_result_2.json',
'assets/lottiefiles/wolf_peek.json',
'assets/lottiefiles/x_pop.json',
'assets/lottiefiles/xamarin_logo_2.json',
'assets/lottiefiles/xuanwheel_logo.json',
'assets/lottiefiles/yoga_carpet.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

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

View File

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

View File

@ -5,6 +5,8 @@
import FlutterMacOS
import Foundation
import path_provider_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
}

82
example/macos/Podfile Normal file
View File

@ -0,0 +1,82 @@
platform :osx, '10.11'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
pods_ary = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
end
def pubspec_supports_macos(file)
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return false;
end
File.foreach(file_abs_path) { |line|
return true if line =~ /^\s*macos:/
}
return false
end
target 'Runner' do
use_frameworks!
use_modular_headers!
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
ephemeral_dir = File.join('Flutter', 'ephemeral')
symlink_dir = File.join(ephemeral_dir, '.symlinks')
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
system("rm -rf #{symlink_dir}")
system("mkdir -p #{symlink_plugins_dir}")
# Flutter Pods
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
if generated_xcconfig.empty?
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
end
generated_xcconfig.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join(symlink_dir, 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
end
}
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join(symlink_plugins_dir, p[:name])
File.symlink(p[:path], symlink)
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
pod p[:name], :path => File.join(symlink, 'macos')
end
}
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true

View File

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

View File

@ -30,6 +30,7 @@
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 */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -58,9 +59,12 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
07433C750748E9780BC34A17 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
0BC6FF5FCD90624533CC60DB /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
10F2CF3D6900CD627E92FAFB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
@ -73,6 +77,7 @@
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>"; };
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>"; };
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>"; };
D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
@ -85,6 +90,7 @@
files = (
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
F03CC91740A974D36C2A6384 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -109,6 +115,7 @@
33CEB47122A05771004F2AC0 /* Flutter */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
E1769B635E3D601E790C66A4 /* Pods */,
);
sourceTree = "<group>";
};
@ -160,10 +167,22 @@
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
0BC6FF5FCD90624533CC60DB /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
E1769B635E3D601E790C66A4 /* Pods */ = {
isa = PBXGroup;
children = (
10F2CF3D6900CD627E92FAFB /* Pods-Runner.debug.xcconfig */,
07433C750748E9780BC34A17 /* Pods-Runner.release.xcconfig */,
5B4C0E87024EC2686CA05E23 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -171,11 +190,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
66E2D04933C70A4FC0890B06 /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
F22406C58ADF93CA802196B1 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -282,6 +303,43 @@
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n";
};
66E2D04933C70A4FC0890B06 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
F22406C58ADF93CA802196B1 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */

View File

@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -4,8 +4,14 @@
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.assets.pictures.read-write</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>

View File

@ -4,6 +4,12 @@
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.assets.pictures.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>

View File

@ -7,42 +7,56 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
version: "2.0.13"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.2"
version: "1.6.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
version: "2.5.0-nullsafety.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
version: "2.1.0-nullsafety.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.3"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
version: "1.2.0-nullsafety.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
version: "1.15.0-nullsafety.3"
convert:
dependency: transitive
description:
@ -56,24 +70,73 @@ packages:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.5"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_colorpicker:
dependency: "direct main"
description:
name: flutter_colorpicker
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
image:
dependency: transitive
golden_toolkit:
dependency: "direct dev"
description:
name: image
name: golden_toolkit
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "0.6.0"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.2"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
logging:
dependency: transitive
description:
@ -87,49 +150,91 @@ packages:
path: ".."
relative: true
source: path
version: "0.2.1"
version: "0.7.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.6"
version: "0.12.10-nullsafety.1"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.8"
version: "1.3.0-nullsafety.3"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
version: "1.8.0-nullsafety.1"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.21"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+2"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+4"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+1"
pedantic:
dependency: "direct overridden"
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
petitparser:
version: "1.9.2"
platform:
dependency: transitive
description:
name: petitparser
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
quiver:
version: "2.2.1"
plugin_platform_interface:
dependency: transitive
description:
name: quiver
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "1.0.3"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.13"
sky_engine:
dependency: transitive
description: flutter
@ -141,62 +246,70 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.5"
version: "1.8.0-nullsafety.2"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
version: "1.10.0-nullsafety.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0-nullsafety.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
version: "1.1.0-nullsafety.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0-nullsafety.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.11"
version: "0.2.19-nullsafety.2"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
version: "1.3.0-nullsafety.3"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
xml:
version: "2.1.0-nullsafety.3"
win32:
dependency: transitive
description:
name: xml
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "3.5.0"
version: "1.7.3"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
sdks:
dart: ">=2.7.0 <3.0.0"
dart: ">=2.10.0-110 <2.11.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0"

View File

@ -8,15 +8,16 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_colorpicker:
http:
lottie:
path: ../
path_provider:
dev_dependencies:
flutter_test:
sdk: flutter
dependency_overrides:
pedantic: ^1.9.0
golden_toolkit:
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
@ -33,34 +34,29 @@ flutter:
- assets/Logo/
- assets/Images/
- assets/Images/WeAccept/
- assets/weather/
- assets/example_with_images/
- assets/example_with_images/images/
# To add assets to your package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# To add custom fonts to your package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages
fonts:
- family: Comic Neue
fonts:
- asset: assets/fonts/Comic-Neue.ttf
- family: Helvetica
fonts:
- asset: assets/fonts/Helvetica.ttf
- family: Helvetica Neue
fonts:
- asset: assets/fonts/Helvetica-Neue.ttf
- family: Open Sans
fonts:
- asset: assets/fonts/Open-Sans.ttf
- family: PT Serif
fonts:
- asset: assets/fonts/PT-Serif.ttf
- family: Roboto
fonts:
- asset: assets/fonts/Roboto.ttf
- family: Noto Emoji
fonts:
- asset: assets/fonts/NotoEmoji-Regular.ttf

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,346 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'utils.dart';
void main() {
LottieComposition composition;
setUpAll(() async {
composition = await LottieComposition.fromBytes(
File('assets/Tests/Shapes.json').readAsBytesSync());
});
void testGolden(String description, ValueDelegate delegate,
{double progress}) async {
var screenshotName = description
.toLowerCase()
.replaceAll(RegExp('[^a-z0-9 ]'), '')
.replaceAll(' ', '_');
testWidgets(description, (tester) async {
var animation =
AnimationController(vsync: tester, duration: composition.duration);
if (progress != null) {
animation.value = progress;
}
await tester.pumpWidget(
Lottie(
composition: composition,
controller: animation,
delegates: LottieDelegates(values: [delegate]),
addRepaintBoundary: false,
),
);
await tester.pump();
await expectLater(find.byType(Lottie),
matchesGoldenFile('goldens/dynamic/$screenshotName.png'));
if (progress == null || progress == 0) {
await tester.pumpWidget(
Lottie(
composition: composition,
controller: animation,
delegates: LottieDelegates(values: []),
addRepaintBoundary: false,
),
);
await tester.pump();
await expectLater(find.byType(Lottie),
matchesGoldenFile('goldens/dynamic_without_delegate.png'));
}
});
}
testGolden(
'Fill color (Green)',
ValueDelegate.color(['Shape Layer 1', 'Rectangle', 'Fill 1'],
value: Colors.green),
);
testGolden(
'Fill color (Yellow)',
ValueDelegate.color(['Shape Layer 1', 'Rectangle', 'Fill 1'],
value: Colors.yellow),
);
testGolden(
'Fill opacity',
ValueDelegate.opacity(['Shape Layer 1', 'Rectangle', 'Fill 1'], value: 50),
);
testGolden(
'Stroke color',
ValueDelegate.strokeColor(['Shape Layer 1', 'Rectangle', 'Stroke 1'],
value: Colors.green),
);
testGolden(
'Stroke width',
ValueDelegate.strokeWidth(['Shape Layer 1', 'Rectangle', 'Stroke 1'],
value: 50),
);
testGolden(
'Stroke opacity',
ValueDelegate.opacity(['Shape Layer 1', 'Rectangle', 'Stroke 1'],
value: 50),
);
testGolden(
'Transform anchor point',
ValueDelegate.transformAnchorPoint(['Shape Layer 1', 'Rectangle'],
value: Offset(20, 20)),
);
testGolden(
'Transform position',
ValueDelegate.transformPosition(['Shape Layer 1', 'Rectangle'],
value: Offset(20, 20)),
);
testGolden(
'Transform position (relative)',
ValueDelegate.transformPosition(['Shape Layer 1', 'Rectangle'],
relative: Offset(20, 20)),
);
testGolden(
'Transform opacity',
ValueDelegate.transformOpacity(['Shape Layer 1', 'Rectangle'], value: 50),
);
testGolden(
'Transform rotation',
ValueDelegate.transformRotation(['Shape Layer 1', 'Rectangle'], value: 45),
);
testGolden(
'Transform scale',
ValueDelegate.transformScale(['Shape Layer 1', 'Rectangle'],
value: Offset(0.5, 0.5)),
);
testGolden(
'Rectangle corner roundedness',
ValueDelegate.cornerRadius(
['Shape Layer 1', 'Rectangle', 'Rectangle Path 1'],
value: 7),
);
testGolden(
'Rectangle position',
ValueDelegate.position(['Shape Layer 1', 'Rectangle', 'Rectangle Path 1'],
relative: Offset(20, 20)),
);
testGolden(
'Rectangle size',
ValueDelegate.rectangleSize(
['Shape Layer 1', 'Rectangle', 'Rectangle Path 1'],
relative: Offset(30, 40)),
);
testGolden(
'Ellipse position',
ValueDelegate.position(['Shape Layer 1', 'Ellipse', 'Ellipse Path 1'],
relative: Offset(20, 20)),
);
testGolden(
'Ellipse size',
ValueDelegate.ellipseSize(['Shape Layer 1', 'Ellipse', 'Ellipse Path 1'],
relative: Offset(40, 60)),
);
testGolden(
'Star points',
ValueDelegate.polystarPoints(['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 8),
);
testGolden(
'Star rotation',
ValueDelegate.polystarRotation(['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 10),
);
testGolden(
'Star position',
ValueDelegate.position(['Shape Layer 1', 'Star', 'Polystar Path 1'],
relative: Offset(20, 20)),
);
testGolden(
'Star inner radius',
ValueDelegate.polystarInnerRadius(
['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 10),
);
testGolden(
'Star inner roundedness',
ValueDelegate.polystarInnerRoundedness(
['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 100),
);
testGolden(
'Star outer radius',
ValueDelegate.polystarOuterRadius(
['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 60),
);
testGolden(
'Star outer roundedness',
ValueDelegate.polystarOuterRoundedness(
['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 100),
);
testGolden(
'Polygon points',
ValueDelegate.polystarPoints(['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 8),
);
testGolden(
'Polygon rotation',
ValueDelegate.polystarRotation(['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 10),
);
testGolden(
'Polygon position',
ValueDelegate.position(['Shape Layer 1', 'Star', 'Polystar Path 1'],
relative: Offset(20, 20)),
);
testGolden(
'Polygon radius',
ValueDelegate.polystarOuterRadius(
['Shape Layer 1', 'Star', 'Polystar Path 1'],
relative: 60),
);
testGolden(
'Polygon roundedness',
ValueDelegate.polystarOuterRoundedness(
['Shape Layer 1', 'Star', 'Polystar Path 1'],
value: 100),
);
testGolden(
'Repeater transform position',
ValueDelegate.transformPosition(
['Shape Layer 1', 'Repeater Shape', 'Repeater 1'],
relative: Offset(100, 100)),
);
testGolden(
'Repeater transform start opacity',
ValueDelegate.transformStartOpacity(
['Shape Layer 1', 'Repeater Shape', 'Repeater 1'],
value: 25),
);
testGolden(
'Repeater transform end opacity',
ValueDelegate.transformEndOpacity(
['Shape Layer 1', 'Repeater Shape', 'Repeater 1'],
value: 25),
);
testGolden(
'Repeater transform rotation',
ValueDelegate.transformRotation(
['Shape Layer 1', 'Repeater Shape', 'Repeater 1'],
value: 45),
);
testGolden(
'Repeater transform scale',
ValueDelegate.transformScale(
['Shape Layer 1', 'Repeater Shape', 'Repeater 1'],
value: Offset(2, 2)),
);
testGolden('Time remapping', ValueDelegate.timeRemap(['Circle 1'], value: 1),
progress: 0.1);
testGolden(
'Color Filter',
ValueDelegate.colorFilter(['**'],
value: ColorFilter.mode(Colors.green, BlendMode.srcATop)),
);
testGolden(
'Null Color Filter',
ValueDelegate.colorFilter(['**'], value: null),
);
for (var progress in [0.0, 0.5, 1.0]) {
testGolden(
'Opacity interpolation ($progress)',
ValueDelegate.transformOpacity(['Shape Layer 1', 'Rectangle'],
callback: (frameInfo) => lerpDouble(
10, 100, Curves.linear.transform(frameInfo.overallProgress))
.round()),
progress: progress);
}
testWidgets('warningShimmer', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var composition = await LottieComposition.fromBytes(
File('test/data/warningShimmer.json').readAsBytesSync());
var delegates = <String, List<ValueDelegate>>{
'1': [
for (var i in ['1', '2', '5'])
ValueDelegate.color(['Layer $i Outlines', '**'], value: Colors.red),
for (var i in ['3', '4'])
ValueDelegate.color(['Layer $i Outlines', '**'],
value: Colors.greenAccent),
],
'2': [
for (var i in ['1', '2', '5'])
ValueDelegate.color(['Layer $i Outlines', 'Group 1', '*'],
value: Colors.red),
for (var i in ['3', '4'])
ValueDelegate.color(['Layer $i Outlines', 'Group 1', '*'],
value: Colors.greenAccent),
],
'3': [
for (var i in ['1', '2', '5'])
ValueDelegate.color(['Layer $i Outlines', 'Group 1', 'Fill 1'],
value: Colors.red),
for (var i in ['3', '4'])
ValueDelegate.color(['Layer $i Outlines', 'Group 1', 'Fill 1'],
value: Colors.greenAccent),
],
};
for (var variant in delegates.entries) {
await tester.pumpWidget(
FilmStrip(
composition,
size: size,
delegates: LottieDelegates(
values: variant.value,
),
),
);
await expectLater(find.byType(FilmStrip),
matchesGoldenFile('goldens/warningShimmer_${variant.key}.png'));
}
});
}

View File

@ -0,0 +1,29 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
void main() {
testWidgets('Dynamic test', (tester) async {
var composition = await LottieComposition.fromBytes(
File('assets/Tests/DynamicText.json').readAsBytesSync());
await tester.pumpWidget(
MaterialApp(
home: Lottie(
composition: composition,
animate: false,
delegates: LottieDelegates(
text: (input) => '🔥c🔥👮🏿🔥',
textStyle: (font) => TextStyle(
fontFamily: 'Roboto', fontFamilyFallback: ['Noto Emoji']),
values: []),
),
),
);
await expectLater(
find.byType(Lottie), matchesGoldenFile('goldens/dynamic_text.png'));
});
}

View File

@ -0,0 +1,23 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'package:path/path.dart' as p;
import 'utils.dart';
void main() {
testWidgets('Animations with stroke', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var composition = await LottieComposition.fromBytes(
File('assets/17297-fireworks.json').readAsBytesSync());
await tester.pumpWidget(FilmStrip(composition, size: size));
await expectLater(find.byType(FilmStrip),
matchesGoldenFile(p.join('goldens/fireworks.png')));
});
}

View File

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

View File

@ -0,0 +1,32 @@
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'package:path/path.dart' as p;
import 'utils.dart';
void main() {
var root = 'assets';
for (var asset in Directory(root)
.listSync(recursive: true)
.whereType<File>()
.where((f) => const ['.json', '.zip'].contains(p.extension(f.path)))) {
testWidgets('Goldens ${asset.path}', (tester) async {
var size = Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
var composition = await tester.runAsync(() => FileLottie(asset).load());
await tester.pumpWidget(FilmStrip(composition, size: size));
var folder = p.relative(asset.path, from: root);
var fileName =
'${p.basenameWithoutExtension(asset.path)}.png'.toLowerCase();
await expectLater(
find.byType(FilmStrip),
matchesGoldenFile(
p.join('goldens/all', p.dirname(folder), fileName)));
});
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

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