Compare commits

...

2 Commits

Author SHA1 Message Date
bf7d0ebf05 Increase version to 0.7.0 (#107) 2020-10-23 18:43:56 +02:00
57faea6f5e Fill Performance Improvements and other fixes (#100)
This PR improves some fill performance issues I found with various Lottie animations.
I think the real issue comes down to the render performance of Path.addPath(). The performance issue happens in the Render thread and seems directly related to how large the animation is on-screen. Flutter might be caching pre-rendered textures and running out of memory.

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

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

There are a couple of other changes:

- I fixed a bug with the casing of "weather" in pubspec.yaml. Without this fix, the examples don't build on Ubuntu Linux.
The debugging class MeanCalculator wasn't initializing its fields, causing a null pointer exception when debugging.
- I added antiAliasingSuggested to LottieDrawable to allow fill paints to be anti-aliased. It is off by default. It also provides some minor performance improvements without any noticeable loss in quality. It is only applied to fills right now.
- I added PathFactory to create Paths rather than just new-ing them. path_factory.dart allows you to switch out the normal Path creation with a debug logging implementation so you can see all of the Path calls that are performed during a frame. Just create a DebugPath in the factory rather than Path.
2020-09-10 14:18:56 +02:00
105 changed files with 390 additions and 109 deletions

View File

@ -10,7 +10,7 @@ jobs:
name: Flutter analyze
strategy:
matrix:
flutter: ['stable', 'dev']
flutter: ['stable']
runs-on: macos-latest
steps:
- uses: actions/checkout@v2

View File

@ -1,3 +1,6 @@
## [0.7.0]
- Performance improvement for complex animations.
## [0.6.0]
- Runs the animation at the frame rate specified in the json file (ie. An animation encoded with a 20 FPS will only
be paint 20 times per seconds even though the AnimationController will invalidate the widget 60 times per seconds).

View File

@ -21,42 +21,42 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.2"
version: "2.5.0-nullsafety.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0-nullsafety.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety"
version: "1.1.0-nullsafety.3"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
version: "1.2.0-nullsafety.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.1.0-nullsafety.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0-nullsafety"
version: "1.15.0-nullsafety.3"
convert:
dependency: transitive
description:
@ -77,7 +77,14 @@ packages:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0-nullsafety.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file:
dependency: transitive
description:
@ -143,35 +150,35 @@ packages:
path: ".."
relative: true
source: path
version: "0.6.0"
version: "0.7.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.8"
version: "0.12.10-nullsafety.1"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety"
version: "1.3.0-nullsafety.3"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.8.0-nullsafety.1"
path_provider:
dependency: "direct main"
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.11"
version: "1.6.21"
path_provider_linux:
dependency: transitive
description:
@ -185,14 +192,21 @@ packages:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+3"
version: "0.0.4+4"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
version: "1.0.3"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+1"
pedantic:
dependency: transitive
description:
@ -213,7 +227,7 @@ packages:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
version: "1.0.3"
process:
dependency: transitive
description:
@ -232,63 +246,70 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.8.0-nullsafety.2"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.5"
version: "1.10.0-nullsafety.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0-nullsafety.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
version: "1.1.0-nullsafety.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0-nullsafety.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.17"
version: "0.2.19-nullsafety.2"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety"
version: "1.3.0-nullsafety.3"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety"
version: "2.1.0-nullsafety.3"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.3"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0"
version: "0.1.2"
sdks:
dart: ">=2.9.0-18.0 <2.9.0"
dart: ">=2.10.0-110 <2.11.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0"

View File

@ -8,11 +8,11 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_colorpicker:
http:
lottie:
path: ../
flutter_colorpicker:
path_provider:
http:
dev_dependencies:
flutter_test:
@ -34,7 +34,7 @@ flutter:
- assets/Logo/
- assets/Images/
- assets/Images/WeAccept/
- assets/Weather/
- assets/weather/
- assets/example_with_images/
- assets/example_with_images/images/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 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: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 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: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 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: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 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: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 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: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -13,6 +13,7 @@ import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/dash_path.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../utils/utils.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
@ -25,8 +26,8 @@ import 'trim_path_content.dart';
abstract class BaseStrokeContent
implements KeyPathElementContent, DrawingContent {
final Path _path = Path();
final Path _trimPathPath = Path();
final Path _path = PathFactory.create();
final Path _trimPathPath = PathFactory.create();
final LottieDrawable lottieDrawable;
final BaseLayer layer;
final List<_PathGroup> _pathGroups = <_PathGroup>[];

View File

@ -9,6 +9,7 @@ import '../../model/key_path.dart';
import '../../model/key_path_element.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/transform_keyframe_animation.dart';
import 'content.dart';
@ -43,7 +44,7 @@ class ContentGroup implements DrawingContent, PathContent, KeyPathElement {
}
final Matrix4 _matrix = Matrix4.identity();
final Path _path = Path();
final Path _path = PathFactory.create();
@override
final String name;

View File

@ -7,6 +7,7 @@ import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import 'compound_trim_path_content.dart';
@ -18,7 +19,7 @@ import 'trim_path_content.dart';
class EllipseContent implements PathContent, KeyPathElementContent {
static final double _ellipseControlPointPercentage = 0.55228;
final Path _path = Path();
final Path _path = PathFactory.create();
@override
final String name;

View File

@ -8,6 +8,7 @@ import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import '../keyframe/value_callback_keyframe_animation.dart';
@ -17,7 +18,7 @@ import 'key_path_element_content.dart';
import 'path_content.dart';
class FillContent implements DrawingContent, KeyPathElementContent {
final Path _path = Path();
final Path _path = PathFactory.create();
final Paint _paint = Paint();
final BaseLayer layer;
@override
@ -70,6 +71,9 @@ class FillContent implements DrawingContent, KeyPathElementContent {
var alpha =
((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255).round();
_paint.setAlpha(alpha.clamp(0, 255).toInt());
if (lottieDrawable.antiAliasingSuggested) {
_paint.isAntiAlias = true;
}
if (_colorFilterAnimation != null) {
_paint.colorFilter = _colorFilterAnimation.value;
@ -77,11 +81,13 @@ class FillContent implements DrawingContent, KeyPathElementContent {
_path.reset();
for (var i = 0; i < _paths.length; i++) {
_path.addPath(_paths[i].getPath(), Offset.zero,
matrix4: parentMatrix.storage);
_path.addPath(_paths[i].getPath(), Offset.zero);
}
canvas.save();
canvas.transform(parentMatrix.storage);
canvas.drawPath(_path, _paint);
canvas.restore();
L.endSection('FillContent#draw');
}

View File

@ -10,6 +10,7 @@ import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import '../keyframe/value_callback_keyframe_animation.dart';
@ -25,7 +26,7 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
final GradientFill _fill;
final _linearGradientCache = <int, Gradient>{};
final _radialGradientCache = <int, Gradient>{};
final _path = Path();
final _path = PathFactory.create();
final _paint = Paint();
final _paths = <PathContent>[];
final BaseKeyframeAnimation<GradientColor, GradientColor> _colorAnimation;
@ -85,15 +86,14 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
L.beginSection('GradientFillContent#draw');
_path.reset();
for (var i = 0; i < _paths.length; i++) {
_path.addPath(_paths[i].getPath(), Offset.zero,
matrix4: parentMatrix.storage);
_path.addPath(_paths[i].getPath(), Offset.zero);
}
Gradient gradient;
if (_fill.gradientType == GradientType.linear) {
gradient = _getLinearGradient(parentMatrix);
gradient = _getLinearGradient();
} else {
gradient = _getRadialGradient(parentMatrix);
gradient = _getRadialGradient();
}
_paint.shader = gradient;
@ -105,8 +105,14 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
var alpha =
((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255).round();
_paint.setAlpha(alpha.clamp(0, 255).toInt());
if (lottieDrawable.antiAliasingSuggested) {
_paint.isAntiAlias = true;
}
canvas.save();
canvas.transform(parentMatrix.storage);
canvas.drawPath(_path, _paint);
canvas.restore();
L.endSection('GradientFillContent#draw');
}
@ -124,8 +130,8 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
outBounds.right + 1, outBounds.bottom + 1);
}
Gradient _getLinearGradient(Matrix4 parentMatrix) {
var gradientHash = _getGradientHash(parentMatrix);
Gradient _getLinearGradient() {
var gradientHash = _getGradientHash();
var gradient = _linearGradientCache[gradientHash];
if (gradient != null) {
return gradient;
@ -135,14 +141,14 @@ 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, parentMatrix.storage);
gradient = Gradient.linear(
startPoint, endPoint, colors, positions, TileMode.clamp);
_linearGradientCache[gradientHash] = gradient;
return gradient;
}
Gradient _getRadialGradient(Matrix4 parentMatrix) {
var gradientHash = _getGradientHash(parentMatrix);
Gradient _getRadialGradient() {
var gradientHash = _getGradientHash();
var gradient = _radialGradientCache[gradientHash];
if (gradient != null) {
return gradient;
@ -160,13 +166,13 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
if (radius <= 0) {
radius = 0.001;
}
gradient = Gradient.radial(startPoint, radius, colors, positions,
TileMode.clamp, parentMatrix.storage);
gradient =
Gradient.radial(startPoint, radius, colors, positions, TileMode.clamp);
_radialGradientCache[gradientHash] = gradient;
return gradient;
}
int _getGradientHash(Matrix4 parentMatrix) {
int _getGradientHash() {
var startPointProgress =
(_startPointAnimation.progress * _cacheSteps).round();
var endPointProgress = (_endPointAnimation.progress * _cacheSteps).round();
@ -181,7 +187,6 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
if (colorProgress != 0) {
hash = hash * 31 * colorProgress;
}
hash *= 31 * parentMatrix.hashCode;
return hash;
}

View File

@ -1,15 +1,16 @@
import 'dart:ui';
import '../../model/content/merge_paths.dart';
import '../../utils.dart';
import '../../utils/path_factory.dart';
import 'content.dart';
import 'content_group.dart';
import 'greedy_content.dart';
import 'path_content.dart';
class MergePathsContent implements PathContent, GreedyContent {
final Path _firstPath = Path();
final Path _remainderPath = Path();
final Path _path = Path();
final Path _firstPath = PathFactory.create();
final Path _remainderPath = PathFactory.create();
final Path _path = PathFactory.create();
final List<PathContent> _pathContents = <PathContent>[];
final MergePaths _mergePaths;

View File

@ -8,6 +8,7 @@ import '../../model/content/shape_trim_path.dart';
import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import 'compound_trim_path_content.dart';
@ -23,7 +24,7 @@ class PolystarContent implements PathContent, KeyPathElementContent {
/// work otherwise.
static final _polystarMagicNumber = .47829;
static final _polygonMagicNumber = .25;
final _path = Path();
final _path = PathFactory.create();
final LottieDrawable lottieDrawable;
final PolystarShape _polystarShape;

View File

@ -8,6 +8,7 @@ import '../../model/content/shape_trim_path.dart';
import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import 'compound_trim_path_content.dart';
@ -17,7 +18,7 @@ import 'path_content.dart';
import 'trim_path_content.dart';
class RectangleContent implements KeyPathElementContent, PathContent {
final _path = Path();
final _path = PathFactory.create();
@override
final String name;

View File

@ -7,6 +7,7 @@ import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import '../keyframe/transform_keyframe_animation.dart';
@ -24,7 +25,7 @@ class RepeaterContent
GreedyContent,
KeyPathElementContent {
final Matrix4 _matrix = Matrix4.identity();
final _path = Path();
final _path = PathFactory.create();
final LottieDrawable lottieDrawable;
final BaseLayer layer;

View File

@ -4,6 +4,7 @@ import '../../model/content/shape_path.dart';
import '../../model/content/shape_trim_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/path_factory.dart';
import '../keyframe/base_keyframe_animation.dart';
import 'compound_trim_path_content.dart';
import 'content.dart';
@ -11,7 +12,7 @@ import 'path_content.dart';
import 'trim_path_content.dart';
class ShapeContent implements PathContent {
final _path = Path();
final _path = PathFactory.create();
final ShapePath _shape;

View File

@ -1,12 +1,13 @@
import 'dart:ui';
import '../../model/content/shape_data.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/keyframe.dart';
import 'base_keyframe_animation.dart';
class ShapeKeyframeAnimation extends BaseKeyframeAnimation<ShapeData, Path> {
final ShapeData _tempShapeData = ShapeData.empty();
final Path _tempPath = Path();
final Path _tempPath = PathFactory.create();
ShapeKeyframeAnimation(List<Keyframe<ShapeData>> keyframes)
: super(keyframes);

View File

@ -18,6 +18,9 @@ class LottieDrawable {
bool _isDirty = true;
final bool enableMergePaths;
/// Gives a suggestion whether to paint with anti-aliasing, or not. Default is true.
bool antiAliasingSuggested = true;
LottieDrawable(this.composition,
{LottieDelegates delegates, bool enableMergePaths})
: size = Size(composition.bounds.width.toDouble(),

View File

@ -5,13 +5,14 @@ import '../../animation/keyframe/value_callback_keyframe_animation.dart';
import '../../lottie_drawable.dart';
import '../../lottie_property.dart';
import '../../utils.dart';
import '../../utils/path_factory.dart';
import '../../value/lottie_value_callback.dart';
import 'base_layer.dart';
import 'layer.dart';
class SolidLayer extends BaseLayer {
final Paint paint = Paint()..style = PaintingStyle.fill;
final Path path = Path();
final Path path = PathFactory.create();
BaseKeyframeAnimation<ColorFilter, ColorFilter> /*?*/ _colorFilterAnimation;
SolidLayer(LottieDrawable lottieDrawable, Layer layerModel)

View File

@ -1,6 +1,7 @@
import 'dart:math';
import 'dart:ui';
import 'package:meta/meta.dart';
import 'path_factory.dart';
Path dashPath(
Path source, {
@ -14,7 +15,7 @@ Path dashPath(
}
phase ??= 0;
var dest = Path();
var dest = PathFactory.create();
for (final metric in source.computeMetrics()) {
for (var dash in _dashes(metric.length, intervals, phase)) {
dest.addPath(metric.extractPath(dash.left, dash.right), Offset.zero);

View File

@ -1,6 +1,6 @@
class MeanCalculator {
double _sum;
int _n;
double _sum = 0;
int _n = 0;
double get mean => _n == 0 ? 0 : _sum / _n;

View File

@ -0,0 +1,195 @@
import 'dart:typed_data';
import 'dart:ui';
class PathFactory {
static Path create() {
return Path();
}
}
class DebugPath extends Path {
void _log(String methodName) {
print('Path.$methodName');
}
@override
void addArc(Rect oval, double startAngle, double sweepAngle) {
_log('addArc');
super.addArc(oval, startAngle, sweepAngle);
}
@override
void addOval(Rect oval) {
_log('addOval');
super.addOval(oval);
}
@override
void addPath(Path path, Offset offset, {Float64List matrix4}) {
_log('addPath');
super.addPath(path, offset, matrix4: matrix4);
}
@override
void addPolygon(List<Offset> points, bool close) {
_log('addPolygon');
super.addPolygon(points, close);
}
@override
void addRRect(RRect rrect) {
_log('addRRect');
super.addRRect(rrect);
}
@override
void addRect(Rect rect) {
_log('addRect');
super.addRect(rect);
}
@override
void arcTo(
Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) {
_log('arcTo');
super.arcTo(rect, startAngle, sweepAngle, forceMoveTo);
}
@override
void arcToPoint(Offset arcEnd,
{Radius radius = Radius.zero,
double rotation = 0.0,
bool largeArc = false,
bool clockwise = true}) {
_log('arcToPoint');
super.arcToPoint(arcEnd,
radius: radius,
rotation: rotation,
largeArc: largeArc,
clockwise: clockwise);
}
@override
void close() {
_log('close');
super.close();
}
@override
PathMetrics computeMetrics({bool forceClosed = false}) {
_log('computeMetrics');
return super.computeMetrics();
}
@override
void conicTo(double x1, double y1, double x2, double y2, double w) {
_log('conicTo');
super.conicTo(x1, y1, x2, y2, w);
}
@override
bool contains(Offset point) {
_log('contains');
return super.contains(point);
}
@override
void cubicTo(
double x1, double y1, double x2, double y2, double x3, double y3) {
_log('cubicTo');
super.cubicTo(x1, y1, x2, y2, x3, y3);
}
@override
void extendWithPath(Path path, Offset offset, {Float64List matrix4}) {
_log('extendWithPath');
super.extendWithPath(path, offset, matrix4: matrix4);
}
@override
Rect getBounds() {
_log('getBounds');
return super.getBounds();
}
@override
void lineTo(double x, double y) {
_log('lineTo');
super.lineTo(x, y);
}
@override
void moveTo(double x, double y) {
_log('moveTo');
super.moveTo(x, y);
}
@override
void quadraticBezierTo(double x1, double y1, double x2, double y2) {
_log('quadraticBezierTo');
super.quadraticBezierTo(x1, y1, x2, y2);
}
@override
void relativeArcToPoint(Offset arcEndDelta,
{Radius radius = Radius.zero,
double rotation = 0.0,
bool largeArc = false,
bool clockwise = true}) {
_log('relativeArcToPoint');
super.relativeArcToPoint(arcEndDelta,
radius: radius,
rotation: rotation,
largeArc: largeArc,
clockwise: clockwise);
}
@override
void relativeConicTo(double x1, double y1, double x2, double y2, double w) {
_log('relativeConicTo');
super.relativeConicTo(x1, y1, x2, y2, w);
}
@override
void relativeCubicTo(
double x1, double y1, double x2, double y2, double x3, double y3) {
_log('relativeCubicTo');
super.relativeCubicTo(x1, y1, x2, y2, x3, y3);
}
@override
void relativeLineTo(double dx, double dy) {
_log('relativeLineTo');
super.relativeLineTo(dx, dy);
}
@override
void relativeMoveTo(double dx, double dy) {
_log('relativeMoveTo');
super.relativeMoveTo(dx, dy);
}
@override
void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) {
_log('relativeQuadraticBezierTo');
super.relativeQuadraticBezierTo(x1, y1, x2, y2);
}
@override
void reset() {
_log('reset');
super.reset();
}
@override
Path shift(Offset offset) {
_log('shift');
return super.shift(offset);
}
@override
Path transform(Float64List matrix4) {
_log('transform');
return super.transform(matrix4);
}
}

View File

@ -1,5 +1,6 @@
import 'dart:ui';
import 'package:flutter/animation.dart';
import 'path_factory.dart';
class PathInterpolator extends Curve {
/// Governs the accuracy of the approximation of the {@link Path}.
@ -72,7 +73,7 @@ class PathInterpolator extends Curve {
static Path _createCubic(
double controlX1, double controlY1, double controlX2, double controlY2) {
final path = Path();
final path = PathFactory.create();
path.moveTo(0.0, 0.0);
path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0, 1.0);
return path;

View File

@ -4,11 +4,12 @@ import '../animation/content/trim_path_content.dart';
import '../l.dart';
import '../utils.dart';
import 'misc.dart';
import 'path_factory.dart';
class Utils {
static Path createPath(
Offset startPoint, Offset endPoint, Offset cp1, Offset cp2) {
var path = Path();
var path = PathFactory.create();
path.moveTo(startPoint.dx, startPoint.dy);
if (cp1 != null &&

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