Compare commits

...

15 Commits

Author SHA1 Message Date
434ae88aa8 Revert Setup github publishing
It doesn't work for flutter packages
2023-06-02 21:43:14 +02:00
6b752d829c Setup github publishing 2023-06-02 21:38:17 +02:00
124ba6997b Allow RoundedCorners name to be null (#283)
Fixes
https://github.com/xvrh/lottie-flutter/issues/270#issuecomment-1573958860
2023-06-02 21:28:52 +02:00
fdc4018f57 Add an example on how to cache animation as List<Image> (#282) 2023-06-02 13:45:22 +02:00
b61ea14116 Upgrade to Flutter 3.10 & update lints (#280) 2023-05-10 23:09:40 +02:00
9c266bb98b Fix bitwise comparaison on web (#274)
Fixes #273
2023-04-06 16:07:37 +02:00
cd4cc910c4 Use a default value for ShapeTrimPathType (#272) 2023-03-28 10:50:38 +02:00
92502f1358 Fix an assertion for null ShapeTrimPathType.type (#271)
Fixes #270
2023-03-27 22:44:26 +02:00
4520221a28 Update changelog 2023-03-14 15:20:09 +01:00
3f5422d44b Update point text y offset (#268) 2023-03-14 15:07:42 +01:00
61668b0509 perf: makes static compositions not animate by default (#265) 2023-03-01 14:39:06 +01:00
1e9861e43f Pub upgrade 2023-02-28 13:52:27 +01:00
c32550cf15 Use AssetLottie in README.md (#261)
Update documentation to use `AssetLottie(...).load()` instead of
`LottieComposition.fromByteData(...)`

Resolves https://github.com/xvrh/lottie-flutter/issues/215
2023-01-27 22:42:31 +01:00
9d4e66ea6b Run pub upgrade (#262) 2023-01-27 22:27:34 +01:00
f58f3888da Fixed a failed assertion (dirty: is not true) when calling setState inside onLoaded callback. (#259)
Fixes #258
2023-01-16 20:52:41 +01:00
105 changed files with 1636 additions and 629 deletions

View File

@ -12,8 +12,6 @@ jobs:
with:
channel: 'stable'
- run: flutter pub get
- run: flutter pub run tool/publish/comment_dependency_overrides.dart
- run: flutter pub get
- run: flutter pub run tool/publish/check_version.dart ${GITHUB_REF}
- name: Setup credentials
run: |

View File

@ -1,5 +1,19 @@
## 2.4.0
- Require minimum Dart 3.0.0 and Flutter 3.10.0
- Fix a parsing bug when the name property in RoundedCorner was null
## [2.2.0]
## 2.3.2
- Fix a bug when running on the web due to [bitwise operations difference](https://dart.dev/guides/language/numbers#bitwise-operations).
## 2.3.1
- Fix an assertion for null `ShapeTrimPathType.type`.
## 2.3.0
- Fixed a failed assertion (`dirty: is not true`) when calling `setState` inside `onLoaded` callback.
- Update point text y offset
- Makes static compositions not animate by default
## 2.2.0
Apply the latest fixes from Lottie-Android:
- Overhaul text layout
@ -8,7 +22,7 @@ Apply the latest fixes from Lottie-Android:
- Allow interpolating between gradients with different opacity stops
- Add support for gradient opacity stops
## [2.1.0]
## 2.1.0
- Improve the cache to ensure that there is not an empty frame each time we load an animation.
The method `AssetLottie('anim.json').load()` returns a `SynchronousFuture` if it has been loaded previously.
- Expose the `LottieCache` singleton.
@ -22,7 +36,7 @@ void main() {
}
```
## [2.0.0]
## 2.0.0
- **Breaking change**: the lottie widget will be smaller if it relies on the intrinsic size of the composition.
Previously the lottie parser was automatically multiplying the size of the composition by `window.devicePixelRatio`.
@ -44,19 +58,19 @@ Scaffold(
);
```
## [1.4.3]
## 1.4.3
- Fixed some lints with Flutter 3.3.
## [1.4.2]
## 1.4.2
- Use `FilterQuality.low` as default to draw image layers.
## [1.4.1]
## 1.4.1
- Allow `AlignmentGeometry` for `alignment`.
## [1.4.0]
## 1.4.0
- Added `filterQuality` property to control the performance vs quality trade-off to use when drawing images
## [1.3.0]
## 1.3.0
- Added support for rounded corners on shapes and rects
- Add support for text in dynamic properties (`ValueDelegate`)
@ -78,13 +92,13 @@ Lottie.asset(
- Add support for reversed polystar paths
- Enforce order of operations to avoid rounding errors
## [1.2.2]
## 1.2.2
- Internal maintenance: fix lints for Flutter 2.10
## [1.2.1]
## 1.2.1
- Fix: Revert Cubic to `PathInterpolator.cubic`
## [1.2.0]
## 1.2.0
- Add support for gaussian blurs.
Example to blur some elements dynamically:
@ -121,7 +135,7 @@ Lottie.asset(
)
```
## [1.1.0]
## 1.1.0
- Add `errorBuilder` callback to provide an alternative widget in case an error occurs during loading.
```dart
Lottie.network(
@ -143,25 +157,25 @@ Lottie.network(
```
- Various bug fixes
## [1.0.1]
## 1.0.1
- Implement `RenderBox.computeDryLayout`
## [1.0.0]
## 1.0.0
- Migrate to null safety
- Fix some rendering bugs
- Add an image delegate to dynamically change images
- Allow to use an imageProviderFactory with a zip file
## [0.7.1]
## 0.7.1
- Fix a crash for some lottie file with empty paths.
## [0.7.0+1]
## 0.7.0+1
- Fix Flutter Web compilation error
## [0.7.0]
## 0.7.0
- Performance improvement for complex animations.
## [0.6.0]
## 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
@ -172,20 +186,20 @@ Lottie.network(
- 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]
## 0.5.1
- Remove direct dependencies on dart:io to support Flutter Web
## [0.5.0]
## 0.5.0
- Support loading animation from network in a web app
- Fix a couple of bugs with the web dev compiler
## [0.4.1]
## 0.4.1
- Support color value stored as RGB, not RGBA
## [0.4.0+1]
## 0.4.0+1
- Support latest version of the `characters` package
## [0.4.0]
## 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
@ -198,62 +212,62 @@ Lottie.asset('file.json', options: LottieOptions(enableMergePaths: true));
```
## [0.3.6]
## 0.3.6
- Export the `Marker` class
## [0.3.5]
## 0.3.5
- Fix a bug with a wrongly clipped rectangle.
## [0.3.4]
## 0.3.4
- Fix a bug with dashed path
## [0.3.3]
## 0.3.3
- Fix a bug with rounded rectangle shape
## [0.3.2]
## 0.3.2
- Fix a bug with "repeater" content
## [0.3.1]
## 0.3.1
- Support dashed path
## [0.3.0+1]
## 0.3.0+1
- Specify a version range for the dependency on `characters`.
## [0.3.0]
## 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]
## 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]
## 0.2.1
- Fix a big bug in the path transformation code. A lot more animations look correct now.
## [0.2.0+1]
## 0.2.0+1
- Improve readme
- (internal) Add golden tests
## [0.2.0]
## 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]
## 0.1.4
- Support images in animation
- Basic support for text in animation (work in progress)
## [0.1.3]
## 0.1.3
- Support Polystar shape
- Reorganize examples.
## [0.1.2]
## 0.1.2
- Implement `Lottie.network`, `Lottie.file` and `Lottie.memory`
## [0.1.1]
## 0.1.1
- Fix analysis lints
## [0.1.0]
## 0.1.0
- Initial conversion of [lottie-android](https://github.com/airbnb/lottie-android) to Dart/Flutter

View File

@ -129,8 +129,7 @@ animation.
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.
Sometime you may prefer to have full control over the loading of the file. Use `AssetLottie` (or `NetworkLottie`, `MemoryLottie`) to load a lottie composition from a json file.
This example shows how to load and parse a Lottie composition from a json file.
@ -149,12 +148,7 @@ class _MyWidgetState extends State<MyWidget> {
void initState() {
super.initState();
_composition = _loadComposition();
}
Future<LottieComposition> _loadComposition() async {
var assetData = await rootBundle.load('assets/LottieLogo1.json');
return await LottieComposition.fromByteData(assetData);
_composition = AssetLottie('assets/LottieLogo1.json').load();
}
@override

View File

@ -51,8 +51,7 @@ animation.
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.
Sometime you may prefer to have full control over the loading of the file. Use `AssetLottie` (or `NetworkLottie`, `MemoryLottie`) to load a lottie composition from a json file.
This example shows how to load and parse a Lottie composition from a json file.

View File

@ -1,33 +1,59 @@
include: package:flutter_lints/flutter.yaml
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
language:
strict-casts: true
strict-inference: true
linter:
rules:
avoid_print: false
always_declare_return_types: true
avoid_bool_literals_in_conditional_expressions: true
avoid_double_and_int_checks: true
avoid_dynamic_calls: true
avoid_equals_and_hash_code_on_mutable_classes: true
avoid_escaping_inner_quotes: true
avoid_final_parameters: true
avoid_function_literals_in_foreach_calls: true
avoid_js_rounded_ints: true
avoid_positional_boolean_parameters: true
avoid_redundant_argument_values: true
avoid_returning_null_for_future: true
avoid_setters_without_getters: true
avoid_type_to_string: true
avoid_unused_constructor_parameters: true
cancel_subscriptions: true
cast_nullable_to_non_nullable: true
close_sinks: true
collection_methods_unrelated_type: true
combinators_ordering: true
conditional_uri_does_not_exist: true
dangling_library_doc_comments: true
deprecated_consistency: true
implicit_reopen: true
invalid_case_patterns: true
leading_newlines_in_multiline_strings: true
library_annotations: true
no_adjacent_strings_in_list: true
no_default_cases: true
noop_primitive_operations: true
omit_local_variable_types: true
only_throw_errors: true
prefer_if_elements_to_conditional_expressions: true
prefer_relative_imports: true
prefer_single_quotes: true
sort_child_properties_last: true
sort_pub_dependencies: true
test_types_in_equals: true
unawaited_futures: true
unnecessary_breaks: true
unnecessary_library_directive: true
unnecessary_parenthesis: true
unnecessary_statements: true
unnecessary_to_list_in_spreads: true
unsafe_html: true
use_enums: true
use_if_null_to_convert_nulls_to_bools: true
use_named_constants: true
use_raw_strings: true
use_super_parameters: true

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,243 @@
{
"layers": [
{
"ddd": 0,
"ty": 4,
"ind": 0,
"sr": 1,
"ip": 0,
"op": 180,
"st": 0,
"ks": {
"a": {
"k": [
0,
0
],
"a": 0
},
"p": {
"k": [
0,
0
],
"a": 0
},
"s": {
"k": [
100,
100
],
"a": 0
},
"r": {
"k": 0,
"a": 0
},
"o": {
"k": 100,
"a": 0
},
"sk": {
"k": 0,
"a": 0
},
"sa": {
"k": 0,
"a": 0
}
},
"ao": 0,
"bm": 0,
"shapes": [
{
"ty": "gr",
"it": [
{
"ty": "sh",
"d": 1,
"ks": {
"k": {
"c": false,
"i": [
[
0,
0
],
[
32,
-32
],
[
-64,
-64
],
[
64,
64
]
],
"o": [
[
64,
64
],
[
-32,
32
],
[
-64,
64
],
[
0,
0
]
],
"v": [
[
256,
128
],
[
256,
376
],
[
256,
256
],
[
128,
376
]
]
},
"a": 0
}
},
{
"ty": "st",
"lc": 2,
"lj": 2,
"ml": 0,
"o": {
"k": 100,
"a": 0
},
"w": {
"k": 5,
"a": 0
},
"c": {
"k": [
1,
0,
0,
1
],
"a": 0
}
},
{
"ty": "tr",
"a": {
"k": [
0,
0
],
"a": 0
},
"p": {
"k": [
0,
0
],
"a": 0
},
"s": {
"k": [
100,
100
],
"a": 0
},
"r": {
"k": 0,
"a": 0
},
"o": {
"k": 100,
"a": 0
},
"sk": {
"k": 0,
"a": 0
},
"sa": {
"k": 0,
"a": 0
}
}
]
},
{
"ty": "tm",
"s": {
"k": 0,
"a": 0
},
"e": {
"k": 50,
"a": 0
},
"o": {
"a": 1,
"k": [
{
"t": 0,
"i": {
"x": [
1
],
"y": [
1
]
},
"o": {
"x": [
0
],
"y": [
0
]
},
"s": [
0
],
"e": [
360
]
},
{
"t": 180,
"s": [
360
]
}
]
}
}
]
}
],
"v": "5.5.2",
"fr": 60,
"ip": 0,
"op": 180,
"w": 968,
"h": 1090,
"ddd": 0,
"assets": []
}

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(const MyApp());
@ -32,12 +31,7 @@ class _MyWidgetState extends State<MyWidget> {
void initState() {
super.initState();
_composition = _loadComposition();
}
Future<LottieComposition> _loadComposition() async {
var assetData = await rootBundle.load('assets/LottieLogo1.json');
return await LottieComposition.fromByteData(assetData);
_composition = AssetLottie('assets/LottieLogo1.json').load();
}
@override

View File

@ -0,0 +1,130 @@
import 'dart:ui';
import 'package:flutter/material.dart' hide Image;
import 'package:flutter/material.dart' as material;
import 'package:lottie/lottie.dart';
/// This example shows how to cache the animation as a List<Image>.
/// After the initial cache of each frame, drawing the animation is almost free
/// in term of CPU usage.
/// The animation will run at a specific framerate (not FrameRate.max) and specific size
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Pre-load the animation for simplicity in this example
var animation = await AssetLottie('assets/AndroidWave.json').load();
// Pick a specific size for our cache.
// In a real app, we may want to defer choosing the size after an initial
// Layout (ie. using LayoutBuilder)
var cachedAnimation = CachedLottie(const Size(150, 200), animation);
runApp(_Example(
lottie: cachedAnimation,
));
}
class _Example extends StatelessWidget {
final CachedLottie lottie;
const _Example({required this.lottie});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Cache'),
),
body: ListView(
children: [
for (var i = 0; i < 20; i++)
Stack(
children: [
for (var j = 0; j < 50; j++)
Transform.translate(
offset: Offset(j.toDouble() * 20, 0),
child: CachedLottiePlayer(
lottie: lottie,
),
)
],
),
],
),
),
);
}
}
class CachedLottie {
final Size size;
final LottieComposition composition;
final List<Image?> images;
late final _drawable = LottieDrawable(composition);
CachedLottie(this.size, this.composition)
: images = List.filled(composition.durationFrames.ceil(), null);
Duration get duration => composition.duration;
Image imageAt(BuildContext context, double progress) {
var index = (images.length * progress).round() % images.length;
return images[index] ??= _takeImage(context, progress);
}
Image _takeImage(BuildContext context, double progress) {
var recorder = PictureRecorder();
var canvas = Canvas(recorder);
var devicePixelRatio = View.of(context).devicePixelRatio;
_drawable
..setProgress(progress)
..draw(canvas, Offset.zero & (size * devicePixelRatio));
var picture = recorder.endRecording();
return picture.toImageSync((size.width * devicePixelRatio).round(),
(size.height * devicePixelRatio).round());
}
}
class CachedLottiePlayer extends StatefulWidget {
final CachedLottie lottie;
final AnimationController? controller;
const CachedLottiePlayer({
super.key,
required this.lottie,
this.controller,
});
@override
State<CachedLottiePlayer> createState() => _CachedLottiePlayerState();
}
class _CachedLottiePlayerState extends State<CachedLottiePlayer>
with TickerProviderStateMixin {
late final AnimationController _autoController =
AnimationController(vsync: this, duration: widget.lottie.duration)
..repeat();
@override
Widget build(BuildContext context) {
var controller = widget.controller ?? _autoController;
return AnimatedBuilder(
animation: controller,
builder: (context, _) {
var image = widget.lottie.imageAt(context, controller.value);
return material.RawImage(
image: image,
width: widget.lottie.size.width,
height: widget.lottie.size.height,
);
},
);
}
@override
void dispose() {
_autoController.dispose();
super.dispose();
}
}

View File

@ -43,18 +43,32 @@ final files = [
'assets/Tests/Airbnb.zip',
'assets/Tests/Airbnb400.zip',
'assets/Tests/Airbnb800.zip',
'assets/Tests/AnimatedShadow.json',
'assets/Tests/BeyondBounds.json',
'assets/Tests/BoxPosition.json',
'assets/Tests/CheckSwitch.json',
'assets/Tests/DifferentPointsCount.json',
'assets/Tests/DynamicGradient.json',
'assets/Tests/DynamicText.json',
'assets/Tests/EditedColor.json',
'assets/Tests/EllipseDirection.json',
'assets/Tests/EmbeddedFont.zip',
'assets/Tests/EndFrame.json',
'assets/Tests/Fill.json',
'assets/Tests/FillBlur.json',
'assets/Tests/Font_Text_Justification_Translate_Scale_Rotation_Test.json',
'assets/Tests/Frame.json',
'assets/Tests/Framerate.json',
'assets/Tests/GradientFill.json',
'assets/Tests/GradientFillBlur.json',
'assets/Tests/GradientOneColor.json',
'assets/Tests/GradientOpacityInterpolation.json',
'assets/Tests/GradientStrokeBlur.json',
'assets/Tests/Heart.json',
'assets/Tests/InterpolateBetweenOpacityStops.json',
'assets/Tests/InterpolatorLoopBack.json',
'assets/Tests/KeyframeTypes.json',
'assets/Tests/LargeComposition.json',
'assets/Tests/Laugh4.json',
'assets/Tests/LoopPlayOnce.json',
'assets/Tests/Marker.json',
@ -65,39 +79,66 @@ final files = [
'assets/Tests/MatteTimeStretchLine.json',
'assets/Tests/MatteTimeStretchScan.json',
'assets/Tests/MiterLimit.json',
'assets/Tests/Multiline.json',
'assets/Tests/OpacityStops.json',
'assets/Tests/OverlapShapeWithOpacity.json',
'assets/Tests/Parenting.json',
'assets/Tests/PrecompBlur.json',
'assets/Tests/PrecompBlurDecimapPrecompSize.json',
'assets/Tests/Precomps.json',
'assets/Tests/RGB.json',
'assets/Tests/RGBMarker.json',
'assets/Tests/Rect1.json',
'assets/Tests/Rect3.json',
'assets/Tests/Rect4.json',
'assets/Tests/Rect5.json',
'assets/Tests/Rect6.json',
'assets/Tests/Rect7.json',
'assets/Tests/Rect8.json',
'assets/Tests/Rect9.json',
'assets/Tests/Remap.json',
'assets/Tests/Repeater.json',
'assets/Tests/ReversedStar.json',
'assets/Tests/RoundedCorners.json',
'assets/Tests/RoundedWithAlreadyRoundedCorners.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/SplitPathTransform.json',
'assets/Tests/Squares.json',
'assets/Tests/StarSkew.json',
'assets/Tests/StartEndFrame.json',
'assets/Tests/StaticShadow.json',
'assets/Tests/Stroke.json',
'assets/Tests/StrokeBlur.json',
'assets/Tests/TelegramAlphaCompat.json',
'assets/Tests/Text.json',
'assets/Tests/TextBaseline.json',
'assets/Tests/TextWithPsCenter.json',
'assets/Tests/TextWithPsLeft.json',
'assets/Tests/Text_Justification_Translate_Scale_Rotation_Text.json',
'assets/Tests/TgsWithoutOpacity.json',
'assets/Tests/Thumb.json',
'assets/Tests/TimeRemapAndStartOffset.json',
'assets/Tests/TimeStretch.json',
'assets/Tests/TimeStretchAndStartOffset.json',
'assets/Tests/TimeStretchMask.json',
'assets/Tests/TimeStretchPrecomp.json',
'assets/Tests/TimeStretchPrecomp2.json',
'assets/Tests/TrackMattes.json',
'assets/Tests/TransformWithoutEndValues.json',
'assets/Tests/TrimPathWrapAround.json',
'assets/Tests/TrimPaths.json',
'assets/Tests/TrimPathsInsideAndOutsideGroup.json',
'assets/Tests/WeAccept.json',
'assets/Tests/WeAcceptInlineImage.json',
'assets/Tests/ZipInlineImage.zip',
'assets/Tests/adrock.json',
'assets/Tests/adrock_converted.json',
'assets/Tests/anim_jpg.zip',
'assets/Tests/august_view_pulse.zip',
'assets/Tests/bm.json',
'assets/Tests/bm_converted.json',
@ -105,8 +146,11 @@ final files = [
'assets/Tests/catrim_converted.json',
'assets/Tests/dalek.json',
'assets/Tests/dalek_converted.json',
'assets/Tests/exported_with_flow.json',
'assets/Tests/hd.json',
'assets/Tests/map.zip',
'assets/Tests/rect2.json',
'assets/Tests/wile.json',
'assets/TwitterHeartButton.json',
'assets/battery_optimizations.json',
'assets/bluetoothscanning.json',
@ -221,6 +265,7 @@ final files = [
'assets/lottiefiles/la_calavera.json',
'assets/lottiefiles/landing_page.json',
'assets/lottiefiles/lego_loader.json',
'assets/lottiefiles/lf20_fteywrno.json',
'assets/lottiefiles/light.json',
'assets/lottiefiles/lightsaber.json',
'assets/lottiefiles/little_girl_jumping_-_loader.json',

View File

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

View File

@ -1,4 +1,4 @@
platform :osx, '10.11'
platform :osx, '10.14'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -1,22 +1,23 @@
PODS:
- FlutterMacOS (1.0.0)
- path_provider_macos (0.0.1):
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
path_provider_macos:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
SPEC CHECKSUMS:
FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
COCOAPODS: 1.11.3
COCOAPODS: 1.12.1

View File

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {
/* Begin PBXAggregateTarget section */
@ -203,7 +203,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
@ -256,6 +256,7 @@
/* Begin PBXShellScriptBuildPhase section */
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -320,11 +321,11 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/path_provider_macos/path_provider_macos.framework",
"${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_macos.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@ -405,7 +406,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
@ -488,7 +489,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@ -535,7 +536,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -5,77 +5,88 @@ packages:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
url: "https://pub.dev"
source: hosted
version: "3.3.5"
version: "3.3.7"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.9.0"
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
source: hosted
version: "1.16.0"
version: "1.17.1"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.3"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.0.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
flutter:
@ -87,14 +98,16 @@ packages:
dependency: "direct main"
description:
name: flutter_colorpicker
url: "https://pub.dartlang.org"
sha256: "458a6ed8ea480eb16ff892aedb4b7092b2804affd7e046591fb03127e8d8ef8b"
url: "https://pub.dev"
source: hosted
version: "1.0.3"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
url: "https://pub.dev"
source: hosted
version: "2.0.1"
flutter_test:
@ -106,154 +119,167 @@ packages:
dependency: "direct dev"
description:
name: golden_toolkit
url: "https://pub.dartlang.org"
sha256: "8f74adab33154fe7b731395782797021f97d2edc52f7bfb85ff4f1b5c4a215f0"
url: "https://pub.dev"
source: hosted
version: "0.14.0"
version: "0.15.0"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
sha256: "4c3f04bfb64d3efd508d06b41b825542f08122d30bda4933fb95c069d22a4fa3"
url: "https://pub.dev"
source: hosted
version: "0.13.5"
version: "1.0.0"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.5"
version: "0.6.7"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.1.0"
logging:
dependency: "direct main"
description:
name: logging
url: "https://pub.dartlang.org"
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.2.0"
lottie:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "2.2.0"
version: "2.4.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
source: hosted
version: "0.12.12"
version: "0.12.15"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
url: "https://pub.dev"
source: hosted
version: "0.1.5"
version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.8.0"
version: "1.9.1"
path:
dependency: "direct main"
description:
name: path
url: "https://pub.dartlang.org"
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
version: "1.8.3"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2"
url: "https://pub.dev"
source: hosted
version: "2.0.11"
version: "2.0.15"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86"
url: "https://pub.dev"
source: hosted
version: "2.0.22"
path_provider_ios:
version: "2.0.27"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
name: path_provider_foundation
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
url: "https://pub.dev"
source: hosted
version: "2.0.11"
version: "2.2.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57
url: "https://pub.dev"
source: hosted
version: "2.1.7"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
version: "2.1.11"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec"
url: "https://pub.dev"
source: hosted
version: "2.0.5"
version: "2.0.6"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.6"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
pointycastle:
dependency: transitive
description:
name: pointycastle
url: "https://pub.dartlang.org"
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.6.2"
version: "3.7.3"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
url: "https://pub.dev"
source: hosted
version: "4.2.4"
sky_engine:
@ -265,72 +291,82 @@ packages:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.dev"
source: hosted
version: "0.4.12"
version: "0.5.1"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "4.1.4"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
url: "https://pub.dev"
source: hosted
version: "0.2.0+2"
version: "1.0.0"
sdks:
dart: ">=2.18.4 <3.0.0"
flutter: ">=3.3.0"
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"

View File

@ -3,7 +3,7 @@ description: A sample app for the Lottie player
publish_to: none
environment:
sdk: ">=2.18.0 <3.0.0"
sdk: "^3.0.0"
dependencies:
flutter:

View File

@ -10,7 +10,7 @@ export 'src/options.dart' show LottieOptions;
export 'src/providers/asset_provider.dart' show AssetLottie;
export 'src/providers/file_provider.dart' show FileLottie;
export 'src/providers/load_image.dart' show LottieImageProviderFactory;
export 'src/providers/lottie_provider.dart' show LottieProvider, LottieCache;
export 'src/providers/lottie_provider.dart' show LottieCache, LottieProvider;
export 'src/providers/memory_provider.dart' show MemoryLottie;
export 'src/providers/network_provider.dart' show NetworkLottie;
export 'src/raw_lottie.dart' show RawLottie;

View File

@ -144,7 +144,7 @@ abstract class BaseStrokeContent
}
var alpha =
((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255).round();
paint.setAlpha(alpha.clamp(0, 255).toInt());
paint.setAlpha(alpha.clamp(0, 255));
paint.strokeWidth = _widthAnimation.value * parentMatrix.getScale();
if (paint.strokeWidth <= 0) {
// Android draws a hairline stroke for 0, After Effects doesn't.

View File

@ -58,12 +58,14 @@ class ContentGroup implements DrawingContent, PathContent, KeyPathElement {
lottieDrawable,
layer,
shapeGroup.name,
shapeGroup.hidden,
contentsFromModels(lottieDrawable, layer, shapeGroup.items),
findTransform(shapeGroup.items));
findTransform(shapeGroup.items),
hidden: shapeGroup.hidden);
ContentGroup.copy(this._lottieDrawable, BaseLayer layer, this.name,
this._hidden, this._contents, AnimatableTransform? transform) {
this._contents, AnimatableTransform? transform,
{required bool hidden})
: _hidden = hidden {
if (transform != null) {
_transformAnimation = transform.createAnimation()
..addAnimationsToLayer(layer)

View File

@ -89,7 +89,7 @@ class FillContent implements DrawingContent, KeyPathElementContent {
_paint.color = _colorAnimation.value;
var alpha =
((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255).round();
_paint.setAlpha(alpha.clamp(0, 255).toInt());
_paint.setAlpha(alpha.clamp(0, 255));
if (lottieDrawable.antiAliasingSuggested) {
_paint.isAntiAlias = true;
}

View File

@ -135,7 +135,7 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
var alpha =
((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255).round();
_paint.setAlpha(alpha.clamp(0, 255).toInt());
_paint.setAlpha(alpha.clamp(0, 255));
if (lottieDrawable.antiAliasingSuggested) {
_paint.isAntiAlias = true;
}
@ -175,8 +175,7 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
var gradientColor = _colorAnimation.value;
var colors = _applyDynamicColorsIfNeeded(gradientColor.colors);
var positions = gradientColor.positions;
gradient = Gradient.linear(
startPoint, endPoint, colors, positions, TileMode.clamp);
gradient = Gradient.linear(startPoint, endPoint, colors, positions);
_linearGradientCache[gradientHash] = gradient;
return gradient;
}
@ -200,8 +199,7 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
if (radius <= 0) {
radius = 0.001;
}
gradient =
Gradient.radial(startPoint, radius, colors, positions, TileMode.clamp);
gradient = Gradient.radial(startPoint, radius, colors, positions);
_radialGradientCache[gradientHash] = gradient;
return gradient;
}

View File

@ -50,19 +50,14 @@ class MergePathsContent implements PathContent, GreedyContent {
switch (_mergePaths.mode) {
case MergePathsMode.merge:
_addPaths();
break;
case MergePathsMode.add:
_opFirstPathWithRest(PathOperation.union);
break;
case MergePathsMode.substract:
_opFirstPathWithRest(PathOperation.reverseDifference);
break;
case MergePathsMode.intersect:
_opFirstPathWithRest(PathOperation.intersect);
break;
case MergePathsMode.excludeIntersections:
_opFirstPathWithRest(PathOperation.xor);
break;
}
return _path;

View File

@ -108,10 +108,8 @@ class PolystarContent implements PathContent, KeyPathElementContent {
switch (_polystarShape.type) {
case PolystarShapeType.star:
_createStarPath();
break;
case PolystarShapeType.polygon:
_createPolygonPath();
break;
}
_path.close();
@ -253,7 +251,7 @@ class PolystarContent implements PathContent, KeyPathElementContent {
_path.moveTo(x, y);
currentAngle += anglePerPoint;
var numPoints = points.ceil().toDouble();
var numPoints = points.toDouble();
for (var i = 0; i < numPoints; i++) {
previousX = x;
previousY = y;

View File

@ -79,7 +79,8 @@ class RepeaterContent
newContents = newContents.reversed.toList();
_contentGroup = ContentGroup.copy(
lottieDrawable, layer, 'Repeater', _repeater.hidden, newContents, null);
lottieDrawable, layer, 'Repeater', newContents, null,
hidden: _repeater.hidden);
}
@override

View File

@ -6,6 +6,7 @@ import '../../model/content/shape_data.dart';
import '../../model/cubic_curve_data.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../keyframe/base_keyframe_animation.dart';
import 'content.dart';
import 'shape_modifier_content.dart';
@ -215,22 +216,9 @@ class RoundedCornersContent implements ShapeModifierContent {
this.shapeData = shapeData =
ShapeData(newCurves, initialPoint: Offset.zero, closed: false);
}
shapeData.setClosed(isClosed);
shapeData.isClosed = isClosed;
return shapeData;
}
/// Copied from the API 24+ AOSP source.
static int floorMod(int x, int y) {
return x - floorDiv(x, y) * y;
}
/// Copied from the API 24+ AOSP source.
static int floorDiv(int x, int y) {
var r = x ~/ y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
}
return r;
}
static int floorMod(int x, int y) => MiscUtils.floorModInt(x, y);
}

View File

@ -441,17 +441,22 @@ class _LottieBuilderState extends State<LottieBuilder> {
void _load() {
var provider = widget.lottie;
_loadingFuture = widget.lottie.load().then((composition) {
if (mounted && widget.lottie == provider) {
var onWarning = widget.onWarning;
composition.onWarning = onWarning;
if (onWarning != null) {
for (var warning in composition.warnings) {
onWarning(warning);
// LottieProvier.load() can return a Synchronous future and the onLoaded
// callback can call setState, so we wrap it in a microtask to avoid an
// "!_isDirty" error.
scheduleMicrotask(() {
if (mounted && widget.lottie == provider) {
var onWarning = widget.onWarning;
composition.onWarning = onWarning;
if (onWarning != null) {
for (var warning in composition.warnings) {
onWarning(warning);
}
}
}
widget.onLoaded?.call(composition);
}
widget.onLoaded?.call(composition);
}
});
return composition;
});
@ -472,12 +477,14 @@ class _LottieBuilderState extends State<LottieBuilder> {
}
var composition = snapshot.data;
var animate = widget.animate;
animate ??= (composition?.durationFrames ?? 0) > 1.0;
Widget result = Lottie(
composition: composition,
controller: widget.controller,
frameRate: widget.frameRate,
animate: widget.animate,
animate: animate,
reverse: widget.reverse,
repeat: widget.repeat,
delegates: widget.delegates,

View File

@ -5,12 +5,12 @@ import '../cubic_curve_data.dart';
class ShapeData {
final List<CubicCurveData> curves;
Offset _initialPoint;
bool _closed;
bool isClosed;
ShapeData(List<CubicCurveData> curves, {Offset? initialPoint, bool? closed})
: curves = curves.toList(),
_initialPoint = initialPoint ?? Offset.zero,
_closed = closed ?? false;
isClosed = closed ?? false;
ShapeData.empty() : this([]);
@ -22,17 +22,9 @@ class ShapeData {
return _initialPoint;
}
void setClosed(bool closed) {
_closed = closed;
}
bool get isClosed {
return _closed;
}
void interpolateBetween(
ShapeData shapeData1, ShapeData shapeData2, double percentage) {
_closed = shapeData1.isClosed || shapeData2.isClosed;
isClosed = shapeData1.isClosed || shapeData2.isClosed;
if (shapeData1.curves.length != shapeData2.curves.length) {
// TODO(xha): decide what to do? We don't have access to the LottieDrawble
@ -86,7 +78,7 @@ class ShapeData {
String toString() {
return 'ShapeData{'
'numCurves=${curves.length}'
'closed=$_closed'
'closed=$isClosed'
'}';
}
}

View File

@ -1,7 +1,9 @@
import 'dart:ui';
import 'package:flutter/foundation.dart';
enum Justification { leftAlign, rightAlign, center }
@immutable
class DocumentData {
final String text;
final String? fontName;
@ -19,7 +21,7 @@ class DocumentData {
final Offset? boxPosition;
final Offset? boxSize;
DocumentData({
const DocumentData({
required this.text,
this.fontName,
required this.size,

View File

@ -1,5 +1,7 @@
import 'package:flutter/foundation.dart';
import 'content/shape_group.dart';
@immutable
class FontCharacter {
static int hashFor(String character, String fontFamily, String style) {
var result = character.hashCode;
@ -15,7 +17,7 @@ class FontCharacter {
final String style;
final String fontFamily;
FontCharacter(
const FontCharacter(
{required this.shapes,
required this.character,
required this.size,

View File

@ -363,7 +363,6 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
_contentPaint.setAlpha(255);
canvas.drawRect(bounds, _contentPaint);
}
break;
case MaskMode.maskModeAdd:
if (mask.isInverted) {
_applyInvertedAddMask(
@ -372,7 +371,6 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
_applyAddMask(
canvas, matrix, mask, maskAnimation, opacityAnimation);
}
break;
case MaskMode.maskModeSubstract:
if (i == 0) {
_contentPaint.color = const ui.Color(0xFF000000);
@ -385,7 +383,6 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
_applySubtractMask(
canvas, matrix, mask, maskAnimation, opacityAnimation);
}
break;
case MaskMode.maskModeIntersect:
if (mask.isInverted) {
_applyInvertedIntersectMask(
@ -394,7 +391,6 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
_applyIntersectMask(
canvas, bounds, matrix, mask, maskAnimation, opacityAnimation);
}
break;
}
}
L.beginSection('Layer#restoreLayer');

View File

@ -50,7 +50,6 @@ class CompositionLayer extends BaseLayer {
case MatteType.add:
case MatteType.invert:
mattedLayer = layer;
break;
case MatteType.luma:
case MatteType.lumaInverted:
case MatteType.none:

View File

@ -195,8 +195,7 @@ class TextLayer extends BaseLayer {
void _drawGlyphTextLine(Characters text, DocumentData documentData, Font font,
Canvas canvas, double parentScale, double fontScale, double tracking) {
for (var c in text) {
var characterHash =
FontCharacter.hashFor(c.toString(), font.family, font.style);
var characterHash = FontCharacter.hashFor(c, font.family, font.style);
var character = _composition.characters[characterHash];
if (character == null) {
// Something is wrong. Potentially, they didn't export the text as a glyph.
@ -261,20 +260,19 @@ class TextLayer extends BaseLayer {
double lineWidth) {
var position = documentData.boxPosition;
var size = documentData.boxSize;
var lineOffset = lineIndex * documentData.lineHeight;
var lineStartY =
position == null ? 0 : documentData.lineHeight + position.dy;
var lineOffset = lineIndex * documentData.lineHeight + lineStartY;
var lineStart = position?.dx ?? 0.0;
var boxWidth = size?.dx ?? 0.0;
switch (documentData.justification) {
case Justification.leftAlign:
canvas.translate(lineStart, lineOffset);
break;
case Justification.rightAlign:
canvas.translate(lineStart + boxWidth - lineWidth, lineOffset);
break;
case Justification.center:
canvas.translate(
lineStart + boxWidth / 2.0 - lineWidth / 2.0, lineOffset);
break;
}
}

View File

@ -47,7 +47,6 @@ class AnimatablePathValueParser {
switch (reader.selectName(_names)) {
case 0:
pathAnimation = AnimatablePathValueParser.parse(reader, composition);
break;
case 1:
if (reader.peek() == Token.string) {
hasExpressions = true;
@ -55,7 +54,6 @@ class AnimatablePathValueParser {
} else {
xAnimation = AnimatableValueParser.parseFloat(reader, composition);
}
break;
case 2:
if (reader.peek() == Token.string) {
hasExpressions = true;
@ -63,7 +61,6 @@ class AnimatablePathValueParser {
} else {
yAnimation = AnimatableValueParser.parseFloat(reader, composition);
}
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -21,7 +21,6 @@ class AnimatableTextPropertiesParser {
switch (reader.selectName(_propertiesNames)) {
case 0:
anim = _parseAnimatableTextProperties(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();
@ -47,16 +46,12 @@ class AnimatableTextPropertiesParser {
switch (reader.selectName(_animatablePropertiesNames)) {
case 0:
color = AnimatableValueParser.parseColor(reader, composition);
break;
case 1:
stroke = AnimatableValueParser.parseColor(reader, composition);
break;
case 2:
strokeWidth = AnimatableValueParser.parseFloat(reader, composition);
break;
case 3:
tracking = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -45,21 +45,17 @@ class AnimatableTransformParser {
case 0:
anchorPoint =
AnimatablePathValueParser.parse(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
break;
case 1:
position =
AnimatablePathValueParser.parseSplitPath(reader, composition);
break;
case 2:
scale = AnimatableValueParser.parseScale(reader, composition);
break;
case 3:
case 4:
if (name == 3) {
@ -79,33 +75,25 @@ class AnimatableTransformParser {
rotation.keyframes.add(Keyframe(composition,
startValue: 0.0,
endValue: 0.0,
interpolator: null,
startFrame: 0.0,
endFrame: composition.endFrame));
} else if (rotation.keyframes.first.startValue == null) {
rotation.keyframes.first = Keyframe(composition,
startValue: 0.0,
endValue: 0.0,
interpolator: null,
startFrame: 0.0,
endFrame: composition.endFrame);
}
break;
case 5:
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 6:
startOpacity = AnimatableValueParser.parseFloat(reader, composition);
break;
case 7:
endOpacity = AnimatableValueParser.parseFloat(reader, composition);
break;
case 8:
skew = AnimatableValueParser.parseFloat(reader, composition);
break;
case 9:
skewAngle = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -22,7 +22,6 @@ class BlurEffectParser {
}
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
@ -40,7 +39,6 @@ class BlurEffectParser {
switch (reader.selectName(_innerBlurEffectNames)) {
case 0:
isCorrectType = reader.nextInt() == 0;
break;
case 1:
if (isCorrectType) {
blurEffect = BlurEffect(
@ -48,7 +46,6 @@ class BlurEffectParser {
} else {
reader.skipValue();
}
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -25,21 +25,16 @@ class CircleShapeParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
position =
AnimatablePathValueParser.parseSplitPath(reader, composition);
break;
case 2:
size = AnimatableValueParser.parsePoint(reader, composition);
break;
case 3:
hidden = reader.nextBoolean();
break;
case 4:
// "d" is 2 for normal and 3 for reversed.
reversed = reader.nextInt() == 3;
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -37,7 +37,6 @@ class ContentModelParser {
break typeLoop;
case 1:
d = reader.nextInt();
break;
default:
reader.skipName();
reader.skipValue();
@ -52,46 +51,32 @@ class ContentModelParser {
switch (type) {
case 'gr':
model = ShapeGroupParser.parse(reader, composition);
break;
case 'st':
model = ShapeStrokeParser.parse(reader, composition);
break;
case 'gs':
model = GradientStrokeParser.parse(reader, composition);
break;
case 'fl':
model = ShapeFillParser.parse(reader, composition);
break;
case 'gf':
model = GradientFillParser.parse(reader, composition);
break;
case 'tr':
model = AnimatableTransformParser.parse(reader, composition);
break;
case 'sh':
model = ShapePathParser.parse(reader, composition);
break;
case 'el':
model = CircleShapeParser.parse(reader, composition, d);
break;
case 'rc':
model = RectangleShapeParser.parse(reader, composition);
break;
case 'tm':
model = ShapeTrimPathParser.parse(reader, composition);
break;
case 'sr':
model = PolystarShapeParser.parse(reader, composition, d: d);
break;
case 'mm':
model = MergePathsParser.parse(reader);
break;
case 'rp':
model = RepeaterParser.parse(reader, composition);
break;
case 'rd':
model = RoundedCornersParser.parse(reader, composition);
break;
default:
composition.addWarning('Unknown shape type $type');
}

View File

@ -39,13 +39,10 @@ DocumentData documentDataParser(JsonReader reader) {
switch (reader.selectName(_names)) {
case 0:
text = reader.nextString();
break;
case 1:
fontName = reader.nextString();
break;
case 2:
size = reader.nextDouble();
break;
case 3:
var justificationInt = reader.nextInt();
if (justificationInt > Justification.center.index ||
@ -54,38 +51,28 @@ DocumentData documentDataParser(JsonReader reader) {
} else {
justification = Justification.values[justificationInt];
}
break;
case 4:
tracking = reader.nextInt();
break;
case 5:
lineHeight = reader.nextDouble();
break;
case 6:
baselineShift = reader.nextDouble();
break;
case 7:
fillColor = JsonUtils.jsonToColor(reader);
break;
case 8:
strokeColor = JsonUtils.jsonToColor(reader);
break;
case 9:
strokeWidth = reader.nextDouble();
break;
case 10:
strokeOverFill = reader.nextBoolean();
break;
case 11:
reader.beginArray();
boxPosition = Offset(reader.nextDouble(), reader.nextDouble());
reader.endArray();
break;
case 12:
reader.beginArray();
boxSize = Offset(reader.nextDouble(), reader.nextDouble());
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -27,7 +27,6 @@ class DropShadowEffectParser {
_maybeParseInnerEffect(reader, composition);
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
@ -62,30 +61,23 @@ class DropShadowEffectParser {
switch (reader.selectName(_innerEffectNames)) {
case 0:
currentEffectName = reader.nextString();
break;
case 1:
switch (currentEffectName) {
case 'Shadow Color':
_color = AnimatableValueParser.parseColor(reader, composition);
break;
case 'Opacity':
_opacity = AnimatableValueParser.parseFloat(reader, composition);
break;
case 'Direction':
_direction =
AnimatableValueParser.parseFloat(reader, composition);
break;
case 'Distance':
_distance = AnimatableValueParser.parseFloat(reader, composition);
break;
case 'Softness':
_radius = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipValue();
break;
}
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -24,19 +24,14 @@ class FontCharacterParser {
switch (reader.selectName(_names)) {
case 0:
character = reader.nextString();
break;
case 1:
size = reader.nextDouble();
break;
case 2:
width = reader.nextDouble();
break;
case 3:
style = reader.nextString();
break;
case 4:
fontFamily = reader.nextString();
break;
case 5:
reader.beginObject();
while (reader.hasNext()) {
@ -48,14 +43,12 @@ class FontCharacterParser {
as ShapeGroup);
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -18,16 +18,12 @@ class FontParser {
switch (reader.selectName(_names)) {
case 0:
family = reader.nextString();
break;
case 1:
name = reader.nextString();
break;
case 2:
style = reader.nextString();
break;
case 3:
ascent = reader.nextDouble();
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -69,17 +69,13 @@ class GradientColorParser {
case 0:
// position
positions[colorIndex] = value;
break;
case 1:
r = (value * 255).round();
break;
case 2:
g = (value * 255).round();
break;
case 3:
var b = (value * 255).round();
colors[colorIndex] = Color.fromARGB(255, r, g, b);
break;
}
}

View File

@ -31,7 +31,6 @@ class GradientFillParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
var points = -1;
reader.beginObject();
@ -39,39 +38,30 @@ class GradientFillParser {
switch (reader.selectName(_gradientNames)) {
case 0:
points = reader.nextInt();
break;
case 1:
color = AnimatableValueParser.parseGradientColor(
reader, composition, points);
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
break;
case 2:
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 3:
gradientType =
reader.nextInt() == 1 ? GradientType.linear : GradientType.radial;
break;
case 4:
startPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case 5:
endPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case 6:
fillType = reader.nextInt() == 1
? PathFillType.nonZero
: PathFillType.evenOdd;
break;
case 7:
hidden = reader.nextBoolean();
break;
default:
reader.skipName();
reader.skipValue();
@ -90,8 +80,6 @@ class GradientFillParser {
opacity: opacity,
startPoint: startPoint!,
endPoint: endPoint!,
highlightLength: null,
highlightAngle: null,
hidden: hidden,
);
}

View File

@ -40,7 +40,6 @@ class GradientStrokeParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
var points = -1;
reader.beginObject();
@ -48,46 +47,34 @@ class GradientStrokeParser {
switch (reader.selectName(_gradientNames)) {
case 0:
points = reader.nextInt();
break;
case 1:
color = AnimatableValueParser.parseGradientColor(
reader, composition, points);
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
break;
case 2:
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 3:
gradientType =
reader.nextInt() == 1 ? GradientType.linear : GradientType.radial;
break;
case 4:
startPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case 5:
endPoint = AnimatableValueParser.parsePoint(reader, composition);
break;
case 6:
width = AnimatableValueParser.parseFloat(reader, composition);
break;
case 7:
capType = LineCapType.values[reader.nextInt() - 1];
break;
case 8:
joinType = LineJoinType.values[reader.nextInt() - 1];
break;
case 9:
miterLimit = reader.nextDouble();
break;
case 10:
hidden = reader.nextBoolean();
break;
case 11:
reader.beginArray();
while (reader.hasNext()) {
@ -98,10 +85,8 @@ class GradientStrokeParser {
switch (reader.selectName(_dashPatternNames)) {
case 0:
n = reader.nextString();
break;
case 1:
val = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();
@ -121,7 +106,6 @@ class GradientStrokeParser {
// If there is only 1 value then it is assumed to be equal parts on and off.
lineDashPattern.add(lineDashPattern[0]);
}
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -35,8 +35,14 @@ class JsonUtils {
return _jsonArrayToPoint(reader);
case Token.beginObject:
return _jsonObjectToPoint(reader);
// ignore: no_default_cases
default:
case Token.nullToken:
return Offset.zero;
case Token.endArray:
case Token.endObject:
case Token.name:
case Token.string:
case Token.boolean:
case Token.endDocument:
throw Exception('Unknown point starts with ${reader.peek()}');
}
}
@ -73,10 +79,8 @@ class JsonUtils {
switch (reader.selectName(_pointNames)) {
case 0:
x = valueFromObject(reader);
break;
case 1:
y = valueFromObject(reader);
break;
default:
reader.skipName();
reader.skipValue();
@ -99,8 +103,14 @@ class JsonUtils {
}
reader.endArray();
return val;
// ignore: no_default_cases
default:
case Token.endArray:
case Token.beginObject:
case Token.endObject:
case Token.name:
case Token.string:
case Token.boolean:
case Token.nullToken:
case Token.endDocument:
throw Exception('Unknown value for token of type $token');
}
}

View File

@ -58,28 +58,20 @@ class KeyframeParser {
switch (reader.selectName(_names)) {
case 0:
startFrame = reader.nextDouble();
break;
case 1:
startValue = valueParser(reader);
break;
case 2:
endValue = valueParser(reader);
break;
case 3:
cp1 = JsonUtils.jsonToPoint(reader);
break;
case 4:
cp2 = JsonUtils.jsonToPoint(reader);
break;
case 5:
hold = reader.nextInt() == 1;
break;
case 6:
pathCp1 = JsonUtils.jsonToPoint(reader);
break;
case 7:
pathCp2 = JsonUtils.jsonToPoint(reader);
break;
default:
reader.skipValue();
}
@ -96,12 +88,13 @@ class KeyframeParser {
interpolator = _linearInterpolator;
}
var keyframe = Keyframe<T>(composition,
startValue: startValue,
endValue: endValue,
interpolator: interpolator,
startFrame: startFrame,
endFrame: null);
var keyframe = Keyframe<T>(
composition,
startValue: startValue,
endValue: endValue,
interpolator: interpolator,
startFrame: startFrame,
);
keyframe.pathCp1 = pathCp1;
keyframe.pathCp2 = pathCp2;
return keyframe;
@ -136,13 +129,10 @@ class KeyframeParser {
switch (reader.selectName(_names)) {
case 0: // t
startFrame = reader.nextDouble();
break;
case 1: // s
startValue = valueParser(reader);
break;
case 2: // e
endValue = valueParser(reader);
break;
case 3: // o
if (reader.peek() == Token.beginObject) {
reader.beginObject();
@ -166,7 +156,6 @@ class KeyframeParser {
}
reader.endArray();
}
break;
case 1: // y
if (reader.peek() == Token.number) {
xCp1y = reader.nextDouble();
@ -181,7 +170,6 @@ class KeyframeParser {
}
reader.endArray();
}
break;
default:
reader.skipValue();
}
@ -192,7 +180,6 @@ class KeyframeParser {
} else {
cp1 = JsonUtils.jsonToPoint(reader);
}
break;
case 4: // i
if (reader.peek() == Token.beginObject) {
reader.beginObject();
@ -216,7 +203,6 @@ class KeyframeParser {
}
reader.endArray();
}
break;
case 1: // y
if (reader.peek() == Token.number) {
xCp2y = reader.nextDouble();
@ -231,7 +217,6 @@ class KeyframeParser {
}
reader.endArray();
}
break;
default:
reader.skipValue();
}
@ -242,16 +227,12 @@ class KeyframeParser {
} else {
cp2 = JsonUtils.jsonToPoint(reader);
}
break;
case 5: // h
hold = reader.nextInt() == 1;
break;
case 6: // to
pathCp1 = JsonUtils.jsonToPoint(reader);
break;
case 7: // ti
pathCp2 = JsonUtils.jsonToPoint(reader);
break;
default:
reader.skipValue();
}

View File

@ -44,7 +44,6 @@ class KeyframesParser {
keyframes.add(KeyframeParser.parse(reader, composition, valueParser,
animated: false, multiDimensional: multiDimensional));
}
break;
default:
reader.skipValue();
}

View File

@ -58,7 +58,6 @@ class LayerParser {
id: -1,
layerType: LayerType.preComp,
parentId: -1,
refId: null,
masks: <Mask>[],
transform: AnimatableTransform(),
solidWidth: 0,
@ -68,11 +67,8 @@ class LayerParser {
startFrame: 0,
preCompWidth: bounds.width,
preCompHeight: bounds.height,
text: null,
textProperties: null,
inOutKeyframes: <Keyframe<double>>[],
matteType: MatteType.none,
timeRemapping: null,
isHidden: false);
}
@ -117,13 +113,10 @@ class LayerParser {
switch (reader.selectName(_names)) {
case 0:
layerName = reader.nextString();
break;
case 1:
layerId = reader.nextInt();
break;
case 2:
refId = reader.nextString();
break;
case 3:
var layerTypeInt = reader.nextInt();
if (layerTypeInt < LayerType.unknown.index) {
@ -131,23 +124,17 @@ class LayerParser {
} else {
layerType = LayerType.unknown;
}
break;
case 4:
parentId = reader.nextInt();
break;
case 5:
solidWidth = reader.nextInt();
break;
case 6:
solidHeight = reader.nextInt();
break;
case 7:
solidColor = MiscUtils.parseColor(reader.nextString(),
warningCallback: composition.addWarning);
break;
case 8:
transform = AnimatableTransformParser.parse(reader, composition);
break;
case 9:
var matteTypeIndex = reader.nextInt();
if (matteTypeIndex >= MatteType.values.length) {
@ -161,7 +148,6 @@ class LayerParser {
composition.addWarning('Unsupported matte type: Luma Inverted');
}
composition.incrementMatteOrMaskCount(1);
break;
case 10:
reader.beginArray();
while (reader.hasNext()) {
@ -169,7 +155,6 @@ class LayerParser {
}
composition.incrementMatteOrMaskCount(masks.length);
reader.endArray();
break;
case 11:
reader.beginArray();
while (reader.hasNext()) {
@ -179,7 +164,6 @@ class LayerParser {
}
}
reader.endArray();
break;
case 12:
reader.beginObject();
while (reader.hasNext()) {
@ -187,7 +171,6 @@ class LayerParser {
case 0:
text = AnimatableValueParser.parseDocumentData(
reader, composition);
break;
case 1:
reader.beginArray();
if (reader.hasNext()) {
@ -198,14 +181,12 @@ class LayerParser {
reader.skipValue();
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
break;
case 13:
reader.beginArray();
var effectNames = <String>[];
@ -221,11 +202,9 @@ class LayerParser {
dropShadowEffect =
DropShadowEffectParser().parse(reader, composition);
}
break;
case 1:
var effectName = reader.nextString();
effectNames.add(effectName);
break;
default:
reader.skipName();
reader.skipValue();
@ -238,34 +217,24 @@ class LayerParser {
"Lottie doesn't support layer effects. If you are using them for "
' fills, strokes, trim paths etc. then try adding them directly as contents '
' in your shape. Found: $effectNames');
break;
case 14:
timeStretch = reader.nextDouble();
break;
case 15:
startFrame = reader.nextDouble();
break;
case 16:
preCompWidth = reader.nextInt();
break;
case 17:
preCompHeight = reader.nextInt();
break;
case 18:
inFrame = reader.nextDouble();
break;
case 19:
outFrame = reader.nextDouble();
break;
case 20:
timeRemapping = AnimatableValueParser.parseFloat(reader, composition);
break;
case 21:
cl = reader.nextString();
break;
case 22:
hidden = reader.nextBoolean();
break;
default:
reader.skipName();
reader.skipValue();
@ -277,11 +246,7 @@ class LayerParser {
// Before the in frame
if (inFrame > 0) {
var preKeyframe = Keyframe<double>(composition,
startValue: 0.0,
endValue: 0.0,
interpolator: null,
startFrame: 0.0,
endFrame: inFrame);
startValue: 0.0, endValue: 0.0, startFrame: 0.0, endFrame: inFrame);
inOutKeyframes.add(preKeyframe);
}
@ -289,7 +254,6 @@ class LayerParser {
var visibleKeyframe = Keyframe<double>(composition,
startValue: 1.0,
endValue: 1.0,
interpolator: null,
startFrame: inFrame,
endFrame: outFrame);
inOutKeyframes.add(visibleKeyframe);
@ -297,7 +261,6 @@ class LayerParser {
var outKeyframe = Keyframe<double>(composition,
startValue: 0.0,
endValue: 0.0,
interpolator: null,
startFrame: outFrame,
endFrame: double.maxFinite);
inOutKeyframes.add(outKeyframe);

View File

@ -33,20 +33,15 @@ class LottieCompositionParser {
while (reader.hasNext()) {
switch (reader.selectName(_names)) {
case 0:
parameters.bounds.width = (reader.nextInt()).round();
break;
parameters.bounds.width = reader.nextInt();
case 1:
parameters.bounds.height = (reader.nextInt()).round();
break;
parameters.bounds.height = reader.nextInt();
case 2:
parameters.startFrame = reader.nextDouble();
break;
case 3:
parameters.endFrame = reader.nextDouble() - 0.01;
break;
case 4:
parameters.frameRate = reader.nextDouble();
break;
case 5:
var version = reader.nextString();
var versions = version.split('.');
@ -57,24 +52,18 @@ class LottieCompositionParser {
majorVersion, minorVersion, patchVersion, 4, 4, 0)) {
composition.addWarning('Lottie only supports bodymovin >= 4.4.0');
}
break;
case 6:
_parseLayers(
reader, composition, parameters.layers, parameters.layerMap);
break;
case 7:
_parseAssets(
reader, composition, parameters.precomps, parameters.images);
break;
case 8:
_parseFonts(reader, parameters.fonts);
break;
case 9:
_parseChars(reader, composition, parameters.characters);
break;
case 10:
_parseMarkers(reader, composition, parameters.markers);
break;
default:
reader.skipName();
reader.skipValue();
@ -136,7 +125,6 @@ class LottieCompositionParser {
switch (reader.selectName(_assetsNames)) {
case 0:
id = reader.nextString();
break;
case 1:
reader.beginArray();
while (reader.hasNext()) {
@ -145,19 +133,14 @@ class LottieCompositionParser {
layers.add(layer);
}
reader.endArray();
break;
case 2:
width = reader.nextInt();
break;
case 3:
height = reader.nextInt();
break;
case 4:
imageFileName = reader.nextString();
break;
case 5:
relativeFolder = reader.nextString();
break;
default:
reader.skipName();
reader.skipValue();
@ -192,7 +175,6 @@ class LottieCompositionParser {
fonts[font.name] = font;
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
@ -226,13 +208,10 @@ class LottieCompositionParser {
switch (reader.selectName(_markerNames)) {
case 0:
comment = reader.nextString();
break;
case 1:
frame = reader.nextDouble();
break;
case 2:
durationFrames = reader.nextDouble();
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -23,33 +23,25 @@ class MaskParser {
switch (modeName) {
case 'a':
maskMode = MaskMode.maskModeAdd;
break;
case 's':
maskMode = MaskMode.maskModeSubstract;
break;
case 'n':
maskMode = MaskMode.maskModeNone;
break;
case 'i':
composition.addWarning(
'Animation contains intersect masks. They are not supported but will be treated like add masks.');
maskMode = MaskMode.maskModeIntersect;
break;
default:
composition.addWarning(
'Unknown mask mode $modeName. Defaulting to Add.');
maskMode = MaskMode.maskModeAdd;
}
break;
case 'pt':
maskPath = AnimatableValueParser.parseShapeData(reader, composition);
break;
case 'o':
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 'inv':
inverted = reader.nextBoolean();
break;
default:
reader.skipValue();
}

View File

@ -16,13 +16,10 @@ class MergePathsParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
mode = MergePaths.modeForId(reader.nextInt());
break;
case 2:
hidden = reader.nextBoolean();
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -43,7 +43,6 @@ class JsonScope {
..write('[')
..write(pathIndices[i])
..write(']');
break;
case emptyObject:
case danglingName:
@ -52,7 +51,6 @@ class JsonScope {
if (pathNames[i] != null) {
result.write(pathNames[i]);
}
break;
case nonEmptyDocument:
case emptyDocument:

View File

@ -200,7 +200,6 @@ class JsonUtf8Reader extends JsonReader {
return _peeked = peekedEndArray;
case $semicolon:
_checkLenient();
break;
case $comma:
break;
default:
@ -218,7 +217,6 @@ class JsonUtf8Reader extends JsonReader {
return _peeked = peekedEndObject;
case $semicolon:
_checkLenient(); // fall-through
break;
case $comma:
break;
default:
@ -262,7 +260,6 @@ class JsonUtf8Reader extends JsonReader {
if (buffer.request(1) && buffer.getByte(0) == $greaterThan) {
buffer.readByte(); // Consume '>'.
}
break;
default:
throw syntaxError("Expected ':'");
}

View File

@ -31,41 +31,30 @@ class PolystarShapeParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
type = PolystarShapeType.forValue(reader.nextInt());
break;
case 2:
points = AnimatableValueParser.parseFloat(reader, composition);
break;
case 3:
position =
AnimatablePathValueParser.parseSplitPath(reader, composition);
break;
case 4:
rotation = AnimatableValueParser.parseFloat(reader, composition);
break;
case 5:
outerRadius = AnimatableValueParser.parseFloat(reader, composition);
break;
case 6:
outerRoundedness =
AnimatableValueParser.parseFloat(reader, composition);
break;
case 7:
innerRadius = AnimatableValueParser.parseFloat(reader, composition);
break;
case 8:
innerRoundedness =
AnimatableValueParser.parseFloat(reader, composition);
break;
case 9:
hidden = reader.nextBoolean();
break;
case 10:
// "d" is 2 for normal and 3 for reversed.
reversed = reader.nextInt() == 3;
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -25,20 +25,15 @@ class RectangleShapeParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
position =
AnimatablePathValueParser.parseSplitPath(reader, composition);
break;
case 2:
size = AnimatableValueParser.parsePoint(reader, composition);
break;
case 3:
roundedness = AnimatableValueParser.parseFloat(reader, composition);
break;
case 4:
hidden = reader.nextBoolean();
break;
default:
reader.skipValue();
}

View File

@ -23,19 +23,14 @@ class RepeaterParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
copies = AnimatableValueParser.parseFloat(reader, composition);
break;
case 2:
offset = AnimatableValueParser.parseFloat(reader, composition);
break;
case 3:
transform = AnimatableTransformParser.parse(reader, composition);
break;
case 4:
hidden = reader.nextBoolean();
break;
default:
reader.skipValue();
}

View File

@ -21,18 +21,15 @@ class RoundedCornersParser {
switch (reader.selectName(_names)) {
case 0: //nm
name = reader.nextString();
break;
case 1: // r
cornerRadius = AnimatableValueParser.parseFloat(reader, composition);
break;
case 2: // hd
hidden = reader.nextBoolean();
break;
default:
reader.skipValue();
}
}
return hidden ? null : RoundedCorners(name!, cornerRadius!);
return hidden ? null : RoundedCorners(name ?? '', cornerRadius!);
}
}

View File

@ -23,16 +23,12 @@ ShapeData shapeDataParser(JsonReader reader) {
switch (reader.selectName(_names)) {
case 0:
closed = reader.nextBoolean();
break;
case 1:
pointsArray = JsonUtils.jsonToPoints(reader);
break;
case 2:
inTangents = JsonUtils.jsonToPoints(reader);
break;
case 3:
outTangents = JsonUtils.jsonToPoints(reader);
break;
default:
reader.skipName();
reader.skipValue();
@ -51,7 +47,7 @@ ShapeData shapeDataParser(JsonReader reader) {
if (pointsArray.isEmpty) {
return ShapeData(<CubicCurveData>[],
initialPoint: const Offset(0, 0), closed: false);
initialPoint: Offset.zero, closed: false);
}
var length = pointsArray.length;

View File

@ -25,22 +25,16 @@ class ShapeFillParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
color = AnimatableValueParser.parseColor(reader, composition);
break;
case 2:
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 3:
fillEnabled = reader.nextBoolean();
break;
case 4:
fillTypeInt = reader.nextInt();
break;
case 5:
hidden = reader.nextBoolean();
break;
default:
reader.skipName();
reader.skipValue();

View File

@ -18,10 +18,8 @@ class ShapeGroupParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
hidden = reader.nextBoolean();
break;
case 2:
reader.beginArray();
while (reader.hasNext()) {
@ -31,7 +29,6 @@ class ShapeGroupParser {
}
}
reader.endArray();
break;
default:
reader.skipValue();
}

View File

@ -20,16 +20,12 @@ class ShapePathParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
ind = reader.nextInt();
break;
case 2:
shape = AnimatableValueParser.parseShapeData(reader, composition);
break;
case 3:
hidden = reader.nextBoolean();
break;
default:
reader.skipValue();
}

View File

@ -32,28 +32,20 @@ class ShapeStrokeParser {
switch (reader.selectName(_names)) {
case 0:
name = reader.nextString();
break;
case 1:
color = AnimatableValueParser.parseColor(reader, composition);
break;
case 2:
width = AnimatableValueParser.parseFloat(reader, composition);
break;
case 3:
opacity = AnimatableValueParser.parseInteger(reader, composition);
break;
case 4:
capType = LineCapType.values[reader.nextInt() - 1];
break;
case 5:
joinType = LineJoinType.values[reader.nextInt() - 1];
break;
case 6:
miterLimit = reader.nextDouble();
break;
case 7:
hidden = reader.nextBoolean();
break;
case 8:
reader.beginArray();
while (reader.hasNext()) {
@ -65,10 +57,8 @@ class ShapeStrokeParser {
switch (reader.selectName(_dashPatternNames)) {
case 0:
n = reader.nextString();
break;
case 1:
val = AnimatableValueParser.parseFloat(reader, composition);
break;
default:
reader.skipName();
reader.skipValue();
@ -79,12 +69,10 @@ class ShapeStrokeParser {
switch (n) {
case 'o':
offset = val;
break;
case 'd':
case 'g':
composition.hasDashPattern = true;
lineDashPattern.add(val!);
break;
}
}
reader.endArray();
@ -93,7 +81,6 @@ class ShapeStrokeParser {
// If there is only 1 value then it is assumed to be equal parts on and off.
lineDashPattern.add(lineDashPattern.first);
}
break;
default:
reader.skipValue();
}

View File

@ -20,22 +20,16 @@ class ShapeTrimPathParser {
switch (reader.selectName(_names)) {
case 0:
start = AnimatableValueParser.parseFloat(reader, composition);
break;
case 1:
end = AnimatableValueParser.parseFloat(reader, composition);
break;
case 2:
offset = AnimatableValueParser.parseFloat(reader, composition);
break;
case 3:
name = reader.nextString();
break;
case 4:
type = ShapeTrimPath.typeForId(reader.nextInt());
break;
case 5:
hidden = reader.nextBoolean();
break;
default:
reader.skipValue();
}
@ -43,7 +37,7 @@ class ShapeTrimPathParser {
return ShapeTrimPath(
name: name,
type: type!,
type: type ?? ShapeTrimPathType.simultaneously,
start: start!,
end: end!,
offset: offset!,

View File

@ -8,6 +8,7 @@ import '../lottie_image_asset.dart';
import 'load_image.dart';
import 'lottie_provider.dart';
@immutable
class AssetLottie extends LottieProvider {
AssetLottie(
this.assetName, {

View File

@ -1,4 +1,5 @@
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:path/path.dart' as p;
import '../composition.dart';
import '../lottie_image_asset.dart';
@ -6,6 +7,7 @@ import 'load_image.dart';
import 'lottie_provider.dart';
import 'provider_io.dart' if (dart.library.html) 'provider_web.dart' as io;
@immutable
class FileLottie extends LottieProvider {
FileLottie(this.file, {super.imageProviderFactory});

View File

@ -1,5 +1,5 @@
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:path/path.dart' as p;
import '../composition.dart';
@ -7,6 +7,7 @@ import '../lottie_image_asset.dart';
import 'load_image.dart';
import 'lottie_provider.dart';
@immutable
class MemoryLottie extends LottieProvider {
MemoryLottie(this.bytes, {super.imageProviderFactory});

View File

@ -8,6 +8,7 @@ import 'load_image.dart';
import 'lottie_provider.dart';
import 'provider_io.dart' if (dart.library.html) 'provider_web.dart' as network;
@immutable
class NetworkLottie extends LottieProvider {
NetworkLottie(this.url, {this.headers, super.imageProviderFactory});

View File

@ -13,7 +13,7 @@ class GammaEvaluator {
// IEC 61966-2-1:1999
return linear <= 0.0031308
? linear * 12.92
: ((pow(linear, 1.0 / 2.4) * 1.055) - 0.055).toDouble();
: ((pow(linear, 1.0 / 2.4) * 1.055) - 0.055);
}
// Electro-optical conversion function for the sRGB color space

View File

@ -52,7 +52,7 @@ class MiscUtils {
}
static Color parseColor(String colorString,
{required Function(String) warningCallback}) {
{required void Function(String) warningCallback}) {
if (colorString.isNotEmpty && colorString[0] == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
var color = int.parse(colorString.substring(1), radix: 16);
@ -71,12 +71,19 @@ class MiscUtils {
}
static int floorMod(double x, double y) {
return x.toInt() - y.toInt() * _floorDiv(x.toInt(), y.toInt());
var xInt = x.toInt();
var yInt = y.toInt();
return xInt - yInt * _floorDiv(xInt, yInt);
}
static int floorModInt(int x, int y) {
return x - y * _floorDiv(x, y);
}
static int _floorDiv(int x, int y) {
var r = x ~/ y;
var sameSign = (x ^ y) >= 0;
var sameSign = x.sign == y.sign;
var mod = x % y;
if (!sameSign && mod != 0) {
r--;

View File

@ -104,16 +104,13 @@ class Utils {
newStart -= length;
}
var tempPath =
pathMeasure.extractPath(newStart, newEnd, startWithMoveTo: true);
var tempPath = pathMeasure.extractPath(newStart, newEnd);
if (newEnd > length) {
var tempPath2 =
pathMeasure.extractPath(0, newEnd % length, startWithMoveTo: true);
var tempPath2 = pathMeasure.extractPath(0, newEnd % length);
tempPath.addPath(tempPath2, Offset.zero);
} else if (newStart < 0) {
var tempPath2 = pathMeasure.extractPath(length + newStart, length,
startWithMoveTo: true);
var tempPath2 = pathMeasure.extractPath(length + newStart, length);
tempPath.addPath(tempPath2, Offset.zero);
}
path.set(tempPath);

View File

@ -1,5 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
@immutable
class DropShadow {
final Color color;
final double direction;

View File

@ -5,100 +5,114 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a
url: "https://pub.dev"
source: hosted
version: "50.0.0"
version: "61.0.0"
analyzer:
dependency: "direct dev"
description:
name: analyzer
url: "https://pub.dartlang.org"
sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562
url: "https://pub.dev"
source: hosted
version: "5.2.0"
version: "5.13.0"
archive:
dependency: "direct main"
description:
name: archive
url: "https://pub.dartlang.org"
sha256: "0c8368c9b3f0abbc193b9d6133649a614204b528982bebc7026372d61677ce3a"
url: "https://pub.dev"
source: hosted
version: "3.3.5"
version: "3.3.7"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.4.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.9.0"
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
source: hosted
version: "1.16.0"
version: "1.17.1"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.3"
dart_style:
dependency: "direct dev"
description:
name: dart_style
url: "https://pub.dartlang.org"
sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad
url: "https://pub.dev"
source: hosted
version: "2.2.4"
version: "2.3.1"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "7.0.0"
flutter:
dependency: "direct main"
description: flutter
@ -108,7 +122,8 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
url: "https://pub.dev"
source: hosted
version: "2.0.1"
flutter_test:
@ -120,72 +135,82 @@ packages:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
version: "0.6.5"
version: "0.6.7"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.1.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
source: hosted
version: "0.12.12"
version: "0.12.15"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
url: "https://pub.dev"
source: hosted
version: "0.1.5"
version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.8.0"
version: "1.9.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
path:
dependency: "direct main"
description:
name: path
url: "https://pub.dartlang.org"
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
version: "1.8.3"
pointycastle:
dependency: transitive
description:
name: pointycastle
url: "https://pub.dartlang.org"
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.6.2"
version: "3.7.3"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.4"
sky_engine:
dependency: transitive
description: flutter
@ -195,72 +220,82 @@ packages:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.dev"
source: hosted
version: "0.4.12"
version: "0.5.1"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
vector_math:
dependency: "direct main"
description:
name: vector_math
url: "https://pub.dartlang.org"
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "1.1.0"
yaml:
dependency: "direct dev"
description:
name: yaml
url: "https://pub.dartlang.org"
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.1.2"
sdks:
dart: ">=2.18.0 <3.0.0"
flutter: ">=3.3.0"
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"

View File

@ -1,11 +1,11 @@
name: lottie
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
version: 2.2.0
version: 2.4.0
repository: https://github.com/xvrh/lottie-flutter
environment:
sdk: '>=2.18.0 <3.0.0'
flutter: '>=3.3.0'
sdk: '^3.0.0'
flutter: '>=3.10.0'
dependencies:
archive: ^3.0.0

View File

@ -0,0 +1,689 @@
{
"v": "5.6.6",
"ip": 0,
"op": 1,
"fr": 60,
"w": 953,
"h": 272,
"layers": [
{
"ind": 2345,
"nm": "surface13687",
"ao": 0,
"ip": 0,
"op": 60,
"st": 0,
"ty": 4,
"ks": {
"ty": "tr",
"o": { "k": 100 },
"r": { "k": 0 },
"p": { "k": [0, 0] },
"a": { "k": [0, 0] },
"s": { "k": [133.33, 133.33] },
"sk": { "k": 0 },
"sa": { "k": 0 }
},
"shapes": [
{
"ty": "gr",
"hd": false,
"nm": "surface13687",
"it": [
{
"ty": "gr",
"hd": false,
"it": [
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[20, -0.05],
[0.73, 0.64],
[0, 0]
],
"o": [
[0, 0],
[0, 0],
[-20.01, 0.05],
[-1.14, 0.25],
[0, 0],
[0, 0]
],
"v": [
[79.56, 177.9],
[110.31, 147.43],
[163.43, 200.61],
[103.41, 200.64],
[100.84, 199.21],
[79.55, 177.9]
],
"c": true
}
}
},
{
"ty": "fl",
"o": { "k": 100 },
"c": { "k": [0.03, 0.35, 0.61, 1] }
},
{
"ty": "tr",
"o": { "k": 100 },
"r": { "k": 0 },
"p": { "k": [0, 0] },
"a": { "k": [0, 0] },
"s": { "k": [100, 100] },
"sk": { "k": 0 },
"sa": { "k": 0 },
"hd": false
}
]
},
{
"ty": "gr",
"hd": false,
"it": [
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"v": [
[49.02, 147.35],
[79.55, 116.86],
[110.18, 147.3],
[110.31, 147.43],
[79.56, 177.9]
],
"c": true
}
}
},
{
"ty": "fl",
"o": { "k": 100 },
"c": { "k": [0.12, 0.74, 0.99, 1] }
},
{
"ty": "tr",
"o": { "k": 100 },
"r": { "k": 0 },
"p": { "k": [0, 0] },
"a": { "k": [0, 0] },
"s": { "k": [100, 100] },
"sk": { "k": 0 },
"sa": { "k": 0 },
"hd": false
}
]
},
{
"ty": "gr",
"hd": false,
"it": [
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[17.48, -0.07],
[0.15, -1.03],
[0, 0],
[-1.04, -0.16],
[0, 0],
[0, 0],
[13.93, -0.01],
[2.05, -0.36],
[0, 0],
[4.49, 0.1],
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0],
[-17.47, 0],
[-1.34, 0.44],
[0, 0],
[0.44, 1.33],
[0, 0],
[0, 0],
[-13.93, -0.01],
[-2.07, -0.01],
[0, 0],
[-4.49, -0.18],
[0, 0],
[0, 0],
[0, 0]
],
"v": [
[249.55, 45.91],
[316.33, 45.93],
[316.32, 59.08],
[263.9, 59.1],
[263.05, 62.24],
[263.1, 97.61],
[266.25, 98.46],
[311.07, 98.44],
[311.07, 111.57],
[269.28, 111.57],
[263.07, 111.79],
[262.91, 161.71],
[249.44, 161.6],
[249.43, 48.03],
[249.55, 45.91]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[4.45, -0.12],
[0, 1.84],
[0, 0]
],
"o": [
[0, 0],
[0, 0],
[0, 0],
[-4.46, -0.08],
[-0.34, -1.83],
[0, 0],
[0, 0]
],
"v": [
[332.52, 45.93],
[346.23, 45.93],
[346.24, 124.5],
[346.09, 161.5],
[332.71, 161.51],
[332.51, 155.98],
[332.52, 45.93]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[-6.71, -0.54],
[0.07, -4.17],
[6.68, 0.1],
[0, 0],
[-4.17, -2.21],
[-4.51, 2.61],
[0, 0],
[5.33, 0.73],
[2.27, 7.45],
[0.03, 4.26],
[0, 0],
[0, 0],
[4.75, 0.17],
[-0.27, 4.24],
[-4.82, 0.37]
],
"o": [
[0, 0],
[0, 0],
[6.73, 0.16],
[-0.19, 4.17],
[-6.69, 0.02],
[0, 0],
[0.14, 4.29],
[4.76, 2.71],
[0, 0],
[-4.96, 2.25],
[-7.52, -1.15],
[-1.51, -4.08],
[0, 0],
[0, 0],
[-4.75, -0.25],
[0.03, -4.25],
[4.83, -0.08],
[0, 0]
],
"v": [
[466.71, 55.67],
[480.46, 55.68],
[480.49, 78.93],
[500.69, 79.16],
[500.59, 91.68],
[480.53, 91.64],
[480.48, 137.95],
[485.71, 149.63],
[500.83, 148.46],
[500.83, 161.93],
[484.87, 163.72],
[467.88, 150],
[466.69, 137.26],
[466.66, 92.16],
[466.32, 91.78],
[452.05, 91.65],
[452.16, 78.92],
[466.66, 78.77]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[-4.57, -0.16],
[0, 0],
[-0.41, -7.62],
[-6.51, 0.04],
[0, 0],
[6.55, 0.04],
[0, 0],
[-3.97, -2.02],
[-4.52, 2.71],
[0, 0],
[5.2, 0.6],
[3.18, 6.19],
[0.14, 3.58],
[0, 0],
[4.74, 0.02],
[0, 0],
[-4.67, -0.16],
[-0.29, 7.79]
],
"o": [
[4.57, 0.16],
[0, 0],
[0.17, 7.64],
[6.52, -0.12],
[0, 0],
[-6.55, 0.25],
[0, 0],
[-0.01, 4.1],
[4.87, 2.66],
[0, 0],
[-4.82, 2.18],
[-6.76, -0.9],
[-1.53, -3.24],
[0, 0],
[-4.75, -0.01],
[0, 0],
[4.67, 0.13],
[0.5, -7.77],
[0, 0]
],
"v": [
[524.82, 55.62],
[538.54, 55.73],
[538.86, 56.07],
[539.04, 78.99],
[558.58, 78.93],
[558.63, 91.57],
[538.94, 91.63],
[538.87, 138.74],
[544.01, 149.71],
[559.3, 148.29],
[559.29, 161.84],
[543.82, 163.83],
[527.28, 152.93],
[524.75, 142.52],
[524.75, 91.69],
[510.52, 91.69],
[510.55, 78.89],
[524.57, 79.01],
[524.82, 55.63]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[-9.7, -3.3],
[-3.15, -11.24],
[0.29, -6.48],
[0, 0],
[-4.83, -5.22],
[-9.97, 3.14],
[-3.59, 6.19],
[-3.96, -1.82],
[11.57, -2.22],
[8.71, 4.7],
[2.22, 12.3],
[-3.55, 8.97],
[-9.7, 4.25]
],
"o": [
[9.5, -3.94],
[11.11, 3.83],
[2.06, 6.23],
[0, 0],
[0.54, 6.95],
[6.86, 8],
[7, -2.06],
[3.98, 1.78],
[-5.41, 10.32],
[-9.5, 1.78],
[-11.31, -5.62],
[-1.61, -9.45],
[3.73, -9.85],
[0, 0]
],
"v": [
[591.59, 79.36],
[621.73, 78.65],
[644.59, 103.42],
[646.27, 122.75],
[580.98, 122.82],
[588.43, 142.08],
[617.08, 149.91],
[633.13, 136.27],
[644.93, 141.9],
[618.09, 162.64],
[589.48, 159.77],
[568.16, 130.41],
[570.61, 101.99],
[591.58, 79.36]
],
"c": false
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[1.61, -8.46],
[0, 0],
[4.05, 4],
[9.3, -4.04]
],
"o": [
[-7.99, 3.69],
[0, 0],
[-0.8, -5.53],
[-7.09, -7.61],
[0, 0]
],
"v": [
[596.75, 91.22],
[582.01, 111.57],
[632.08, 111.41],
[625.27, 96.27],
[596.75, 91.23]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[-12.7, -5.32],
[0, 0],
[5.63, -1.66],
[2.18, -7.55],
[-0.06, -5.23],
[0.44, -6.76],
[-0.5, -5.85],
[4.66, -0.16],
[0.07, 17.64],
[0, 0],
[-4.38, -0.11],
[-0.73, -4.37]
],
"o": [
[5.23, -12.7],
[0, 0],
[-5.33, -2.1],
[-7.7, 2.29],
[-1.5, 5.1],
[-0.59, 6.77],
[0.36, 5.84],
[-4.66, 0.23],
[-0.27, -17.63],
[0, 0],
[4.37, 0.12],
[0.4, 4.38],
[0, 0]
],
"v": [
[675.99, 92.31],
[709.98, 78.26],
[709.98, 93.08],
[693.04, 91.34],
[677.46, 108.05],
[676.59, 123.7],
[676.44, 144],
[676.62, 161.54],
[662.63, 161.68],
[662.52, 108.76],
[662.62, 79.07],
[675.75, 79.16],
[675.99, 92.31]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[-4.63, -0.52],
[0, 0],
[-4.16, -4.66],
[-7.34, 2.35],
[0.39, 10.38],
[0, 0],
[0, 0],
[0, 0],
[4.43, 0.05],
[0, 0],
[4.12, -2.27],
[9.44, 2.72],
[3.05, 5.58],
[0.21, 6.99],
[0, 0]
],
"o": [
[4.65, 0.2],
[0, 0],
[-0.05, 6.01],
[5.36, 5.94],
[9.8, -3.51],
[0, 0],
[0, 0],
[0, 0],
[-4.44, -0.07],
[0, 0],
[-2.87, 3.61],
[-8.43, 5.32],
[-6.09, -1.84],
[-3.62, -6.14],
[0, 0],
[0, 0]
],
"v": [
[365.89, 78.91],
[379.86, 79.15],
[379.79, 128.31],
[384.75, 145.54],
[406.54, 150.22],
[422.78, 125.95],
[422.93, 78.91],
[436.93, 78.94],
[436.85, 161.48],
[423.55, 161.43],
[423.5, 149.68],
[413.49, 159.21],
[384.93, 162.51],
[370.48, 150.83],
[365.73, 130.45],
[365.9, 78.91]
],
"c": true
}
}
},
{ "ty": "fl", "o": { "k": 54 }, "c": { "k": [0, 0, 0, 1] } },
{
"ty": "tr",
"o": { "k": 100 },
"r": { "k": 0 },
"p": { "k": [0, 0] },
"a": { "k": [0, 0] },
"s": { "k": [100, 100] },
"sk": { "k": 0 },
"sa": { "k": 0 },
"hd": false
}
]
},
{
"ty": "gr",
"hd": false,
"it": [
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"o": [
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"v": [
[102.21, 3.07],
[163.46, 3],
[60.7, 105.71],
[33.92, 132.34],
[3.45, 101.83]
],
"c": true
}
}
},
{
"ty": "sh",
"ks": {
"k": {
"i": [
[0, 0],
[-1.11, 0.14],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"o": [
[0.8, -1.05],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]
],
"v": [
[101.64, 94.78],
[105.01, 94.11],
[163.41, 94.12],
[110.18, 147.3],
[79.55, 116.86],
[101.64, 94.78]
],
"c": true
}
}
},
{
"ty": "fl",
"o": { "k": 100 },
"c": { "k": [0.27, 0.82, 0.99, 1] }
},
{
"ty": "tr",
"o": { "k": 100 },
"r": { "k": 0 },
"p": { "k": [0, 0] },
"a": { "k": [0, 0] },
"s": { "k": [100, 100] },
"sk": { "k": 0 },
"sa": { "k": 0 },
"hd": false
}
]
},
{
"ty": "tr",
"o": { "k": 100 },
"r": { "k": 0 },
"p": { "k": [0, 0] },
"a": { "k": [0, 0] },
"s": { "k": [100, 100] },
"sk": { "k": 0 },
"sa": { "k": 0 },
"hd": false
}
]
}
]
}
],
"meta": { "g": "LF SVG to Lottie" }
}

View File

@ -9,8 +9,8 @@ import 'utils.dart';
void main() {
testWidgets('Can specify ImageProvider with zip file ', (tester) async {
var size = const Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var callCount = 0;
ImageProvider imageProviderFactory(LottieImageAsset image) {
@ -32,8 +32,8 @@ void main() {
testWidgets('Can specify image delegate', (tester) async {
var size = const Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var image = await tester.runAsync(() async =>
loadImage(FileImage(File('example/assets/Images/WeAccept/img_0.png'))));

View File

@ -276,7 +276,7 @@ void main() {
testGolden(
'Null Color Filter',
ValueDelegate.colorFilter(['**'], value: null),
ValueDelegate.colorFilter(['**']),
);
testGolden(
@ -320,8 +320,8 @@ void main() {
testWidgets('warningShimmer', (tester) async {
var size = const Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var composition = await LottieComposition.fromBytes(
File('test/data/warningShimmer.json').readAsBytesSync());

View File

@ -10,8 +10,8 @@ void main() {
testWidgets('Mirror animation', (tester) async {
var size = const Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var composition = (await tester.runAsync(() =>
FileLottie(File('$root/Tests/MatteTimeStretchScan.json')).load()))!;

View File

@ -9,8 +9,8 @@ import 'utils.dart';
void main() {
testWidgets('Animations with stroke', (tester) async {
var size = const Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var composition = await LottieComposition.fromBytes(
File('example/assets/17297-fireworks.json').readAsBytesSync());

View File

@ -14,8 +14,8 @@ void main() {
.where((f) => const ['.json', '.zip'].contains(p.extension(f.path)))) {
testWidgets('Goldens ${asset.path}', (tester) async {
var size = const Size(500, 400);
tester.binding.window.physicalSizeTestValue = size;
tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var composition =
(await tester.runAsync(() => FileLottie(asset).load()))!;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

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