Compare commits

..

14 Commits

639 changed files with 18358 additions and 61268 deletions

BIN
.DS_Store vendored

Binary file not shown.

31
.github/workflows/analyze-and-test.yaml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Lottie Flutter
on:
pull_request:
push:
branches:
- master
jobs:
analyze_and_test:
name: Flutter analyze
strategy:
matrix:
flutter: ['stable', 'dev']
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v1
with:
channel: ${{ matrix.flutter }}
- run: flutter doctor
- run: flutter --version
- run: flutter analyze
- run: flutter test test # https://github.com/flutter/flutter/issues/20907
- run: flutter pub run tool/prepare_submit.dart
- name: "check for uncommitted changes"
run: |
git diff --exit-code --stat -- . \
|| (echo "##[error] found changed files after build. please run 'dart tool/prepare_submit.dart'" \
"and check in all changes" \
&& exit 1)
shell: bash

32
.github/workflows/publish-on-pub.yaml vendored Normal file
View File

@ -0,0 +1,32 @@
name: Publish package to pub.dev
on:
push:
tags:
- v*
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v1
with:
channel: 'stable'
- run: flutter pub get
- run: flutter pub run tool/publish/comment_dependency_overrides.dart
- run: flutter pub get
- run: echo ::set-env name=RELEASE_VERSION::${GITHUB_REF}
- run: flutter pub run tool/publish/check_version.dart ${{ env.RELEASE_VERSION }}
- name: Setup credentials
run: |
mkdir -p $FLUTTER_HOME/.pub-cache
cat <<EOF > $FLUTTER_HOME/.pub-cache/credentials.json
{
"accessToken":"${{ secrets.OAUTH_ACCESS_TOKEN }}",
"refreshToken":"${{ secrets.OAUTH_REFRESH_TOKEN }}",
"tokenEndpoint":"https://accounts.google.com/o/oauth2/token",
"scopes": [ "openid", "https://www.googleapis.com/auth/userinfo.email" ],
"expiration": 1580681402856
}
EOF
- name: Publish package
run: flutter pub publish --force

9
.gitignore vendored
View File

@ -0,0 +1,9 @@
.*
_*
!.gitignore
!.github
*.iml
**/doc/api/
build/

10
.metadata Normal file
View File

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 27321ebbad34b0a3fafe99fac037102196d655ff
channel: stable
project_type: package

27
CHANGELOG.md Normal file
View File

@ -0,0 +1,27 @@
## [0.2.1] - 2020-02-11
- Fix a big bug in the path transformation code. A lot more animations look correct now.
## [0.2.0+1] - 2020-02-04
- Improve readme
- (internal) Add golden tests
## [0.2.0] - 2020-02-02
- 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
- Support images in animation
- Basic support for text in animation (work in progress)
## [0.1.3] - 2020-02-01
- Support Polystar shape
- Reorganize examples.
## [0.1.2] - 2020-01-31
- Implement `Lottie.network`, `Lottie.file` and `Lottie.memory`
## [0.1.1] - 2020-01-31
- Fix analysis lints
## [0.1.0] - 2020-01-31
- Initial conversion of [lottie-android](https://github.com/airbnb/lottie-android) to Dart/Flutter

1
LICENSE Normal file
View File

@ -0,0 +1 @@
TODO: Add your license here.

232
README.md Normal file
View File

@ -0,0 +1,232 @@
# Lottie for Flutter
[![](https://github.com/xvrh/lottie-flutter/workflows/Lottie%20Flutter/badge.svg?branch=master)](https://github.com/xvrh/lottie-flutter)
[![pub package](https://img.shields.io/pub/v/lottie.svg)](https://pub.dev/packages/lottie)
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!
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))
## Usage
### Simple animation
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 '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'),
],
),
),
);
}
}
```
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`.
```dart
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView(
children: [
Lottie.network(
'https://raw.githubusercontent.com/xvrh/lottie-flutter/master/sample_app/assets/Mobilo/C.json',
controller: _controller,
onLoaded: (composition) {
// Configure the AnimationController with the duration of the
// Lottie file and start the animation.
_controller
..duration = composition.duration
..forward();
},
),
],
),
),
);
}
}
```
### 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.
```dart
Lottie.asset(
'assets/LottieLogo1.json',
width: 200,
height: 200,
fit: BoxFit.fill,
)
```
`width` and `height` are optionals and fallback on the size imposed by the parent or on the intrinsic size of the lottie
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.
```dart
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Future<LottieComposition> _composition;
@override
void initState() {
super.initState();
_composition = _loadComposition();
}
Future<LottieComposition> _loadComposition() async {
var assetData = await rootBundle.load('assets/LottieLogo1.json');
return await LottieComposition.fromByteData(assetData);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<LottieComposition>(
future: _composition,
builder: (context, snapshot) {
var composition = snapshot.data;
if (composition != null) {
return Lottie(composition: composition);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
}
```
### Custom drawing
This example goes low level and shows you how to draw a `LottieComposition` on a custom Canvas at a specific frame in
a specific position and size.
````dart
class CustomDrawer extends StatelessWidget {
final LottieComposition composition;
const CustomDrawer(this.composition, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _Painter(composition),
size: Size(400, 400),
);
}
}
class _Painter extends CustomPainter {
final LottieComposition composition;
_Painter(this.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);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
````
## Limitations
This is a new library so usability, documentation and performance are still work in progress.
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)
## 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.

89
README.template.md Normal file
View File

@ -0,0 +1,89 @@
# Lottie for Flutter
[![](https://github.com/xvrh/lottie-flutter/workflows/Lottie%20Flutter/badge.svg?branch=master)](https://github.com/xvrh/lottie-flutter)
[![pub package](https://img.shields.io/pub/v/lottie.svg)](https://pub.dev/packages/lottie)
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!
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))
## Usage
### Simple animation
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/
```
### Specify a custom `AnimationController`
This example shows how to have full control over the animation by providing your own `AnimationController`.
```dart
import 'example/lib/examples/animation_controller.dart';
```
### 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.
```dart
Lottie.asset(
'assets/LottieLogo1.json',
width: 200,
height: 200,
fit: BoxFit.fill,
)
```
`width` and `height` are optionals and fallback on the size imposed by the parent or on the intrinsic size of the lottie
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.
```dart
import 'example/lib/examples/custom_load.dart#example';
```
### Custom drawing
This example goes low level and shows you how to draw a `LottieComposition` on a custom Canvas at a specific frame in
a specific position and size.
````dart
import 'example/lib/examples/custom_draw.dart#example';
````
## Limitations
This is a new library so usability, documentation and performance are still work in progress.
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)
## 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.

38
analysis_options.yaml Normal file
View File

@ -0,0 +1,38 @@
include: package:pedantic/analysis_options.yaml
analyzer:
errors:
strong-mode:
implicit-casts: false
linter:
rules:
avoid_renaming_method_parameters: true
avoid_returning_null_for_future: true
avoid_returning_null_for_void: true
avoid_returning_this: true
avoid_setters_without_getters: true
await_only_futures: true
camel_case_types: true
cancel_subscriptions: true
close_sinks: true
constant_identifier_names: true
empty_statements: true
hash_and_equals: true
iterable_contains_unrelated_type: true
list_remove_unrelated_type: true
no_adjacent_strings_in_list: true
non_constant_identifier_names: true
only_throw_errors: true
overridden_fields: true
prefer_inlined_adds: true
prefer_interpolation_to_compose_strings: true
prefer_null_aware_operators: true
prefer_relative_imports: true
prefer_typing_uninitialized_variables: true
sort_pub_dependencies: true
test_types_in_equals: true
unnecessary_brace_in_string_interps: true
unnecessary_getters_setters: true
unnecessary_parenthesis: true
unnecessary_statements: true
use_function_type_syntax_for_parameters: true
void_checks: true

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.ttf"}]}]

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

37
example/.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

31
example/README.md Normal file
View File

@ -0,0 +1,31 @@
# Lottie Flutter examples
### Simple usage
```dart
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/sample_app/assets/Mobilo/A.json'),
],
),
),
);
}
}
```

View File

@ -0,0 +1,8 @@
# Lottie Flutter examples
### Simple usage
```dart
import 'lib/examples/examples.dart';
```

7
example/android/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java

View File

@ -0,0 +1,66 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new Exception("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
applicationId "com.github.xvrh.lottie.sample"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.xvrh.lottie.sample">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,30 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.xvrh.lottie.sample">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

View File

@ -0,0 +1,12 @@
package com.github.xvrh.lottie.sample
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.xvrh.lottie.sample">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,31 @@
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View File

@ -0,0 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

View File

@ -0,0 +1,15 @@
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}

View File

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

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