Compare commits

...

4 Commits

Author SHA1 Message Date
8a9ef53c63 v2.5 2023-07-17 22:08:46 +02:00
6ffeaa603f Allow shape to be null (#291) 2023-07-17 22:06:30 +02:00
08e629adaa Fix TextLayer opacity calculation (#285) 2023-07-17 20:17:35 +02:00
bf3118b4cf Add layer-level opacity option to LottieOptions (#286) 2023-06-16 15:17:07 +02:00
30 changed files with 16405 additions and 52 deletions

View File

@ -1,3 +1,7 @@
## 2.5.0
- Add layer-level opacity option to LottieOptions
- Fix TextLayer opacity calculation
## 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"v":"5.1.20","fr":30,"ip":0,"op":100,"w":600,"h":400,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"test Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":30,"s":[0],"e":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":50,"s":[0],"e":[100]},{"t":80}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,200,0],"ix":2},"a":{"a":0,"k":[400,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-66.274],[66.274,0],[0,66.274],[-66.274,0]],"o":[[0,66.274],[-66.274,0],[0,-66.274],[66.274,0]],"v":[[120,0],[0,120],[-120,0],[0,-120]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[488,300],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-66.274],[66.274,0],[0,66.274],[-66.274,0]],"o":[[0,66.274],[-66.274,0],[0,-66.274],[66.274,0]],"v":[[120,0],[0,120],[-120,0],[0,-120]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40800000359,0.40800000359,0.40800000359,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[312,300],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":100,"st":0,"bm":0}],"markers":[]}

File diff suppressed because one or more lines are too long

View File

@ -81,14 +81,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.2"
file:
dependency: transitive
description:
name: file
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
flutter:
dependency: "direct main"
description: flutter
@ -106,10 +98,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.0.2"
flutter_test:
dependency: "direct dev"
description: flutter
@ -127,10 +119,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "4c3f04bfb64d3efd508d06b41b825542f08122d30bda4933fb95c069d22a4fa3"
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.1.0"
http_parser:
dependency: transitive
description:
@ -151,10 +143,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
logging:
dependency: "direct main"
description:
@ -169,7 +161,7 @@ packages:
path: ".."
relative: true
source: path
version: "2.4.0"
version: "2.5.0"
matcher:
dependency: transitive
description:
@ -222,10 +214,10 @@ packages:
dependency: transitive
description:
name: path_provider_foundation
sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3"
sha256: "916731ccbdce44d545414dd9961f26ba5fbaa74bcbb55237d8e65a623a8c7297"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
version: "2.2.4"
path_provider_linux:
dependency: transitive
description:
@ -246,10 +238,10 @@ packages:
dependency: transitive
description:
name: path_provider_windows
sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6
sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96"
url: "https://pub.dev"
source: hosted
version: "2.1.6"
version: "2.1.7"
platform:
dependency: transitive
description:
@ -274,14 +266,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.7.3"
process:
dependency: transitive
description:
name: process
sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
url: "https://pub.dev"
source: hosted
version: "4.2.4"
sky_engine:
dependency: transitive
description: flutter
@ -355,18 +339,18 @@ packages:
dependency: transitive
description:
name: win32
sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c"
sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee
url: "https://pub.dev"
source: hosted
version: "4.1.4"
version: "5.0.5"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.0.1"
sdks:
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"

View File

@ -302,6 +302,7 @@ class Lottie extends StatefulWidget {
/// Some options to enable/disable some feature of Lottie
/// - enableMergePaths: Enable merge path support
/// - enableApplyingOpacityToLayers: Enable layer-level opacity
final LottieOptions? options;
/// Indicate to automatically add a `RepaintBoundary` widget around the animation.

View File

@ -219,6 +219,7 @@ class LottieBuilder extends StatefulWidget {
/// Some options to enable/disable some feature of Lottie
/// - enableMergePaths: Enable merge path support
/// - enableApplyingOpacityToLayers: Enable layer-level opacity
final LottieOptions? options;
/// A builder function responsible for creating the widget that represents

View File

@ -100,7 +100,7 @@ class TextLayer extends BaseLayer {
canvas.save();
canvas.transform(parentMatrix.storage);
_configurePaint(documentData, parentMatrix);
_configurePaint(documentData, parentAlpha);
if (lottieDrawable.useTextGlyphs) {
_drawTextWithGlyphs(documentData, parentMatrix, font, canvas);
@ -111,7 +111,7 @@ class TextLayer extends BaseLayer {
canvas.restore();
}
void _configurePaint(DocumentData documentData, Matrix4 parentMatrix) {
void _configurePaint(DocumentData documentData, int parentAlpha) {
Color fillPaintColor;
if (_colorCallbackAnimation != null) {
fillPaintColor = _colorCallbackAnimation!.value;
@ -133,7 +133,7 @@ class TextLayer extends BaseLayer {
_strokePaint.color = strokePaintColor.withAlpha(_strokePaint.color.alpha);
var opacity = transform.opacity?.value ?? 100;
var alpha = (opacity * 255 / 100).round();
var alpha = opacity * 255 / 100 * parentAlpha ~/ 255;
_fillPaint.setAlpha(alpha);
_strokePaint.setAlpha(alpha);

View File

@ -6,6 +6,16 @@ class LottieOptions {
/// instead of using merge paths.
final bool enableMergePaths;
LottieOptions({bool? enableMergePaths})
: enableMergePaths = enableMergePaths ?? false;
/// Enable layer-level opacity.
///
/// Add the ability to render opacity on the layer level rather than the shape level.
/// Opacity is normally applied directly to a shape. In cases where translucent shapes overlap,
/// applying opacity to a layer will be more accurate at the expense of performance.
/// Details: https://github.com/airbnb/lottie-android/issues/902
final bool enableApplyingOpacityToLayers;
LottieOptions({
this.enableMergePaths = false,
this.enableApplyingOpacityToLayers = false,
});
}

View File

@ -39,8 +39,10 @@ class FontCharacterParser {
case 0:
reader.beginArray();
while (reader.hasNext()) {
shapes.add(ContentModelParser.parse(reader, composition)!
as ShapeGroup);
if (ContentModelParser.parse(reader, composition)
case var shape?) {
shapes.add(shape as ShapeGroup);
}
}
reader.endArray();
default:

View File

@ -86,6 +86,7 @@ class RawLottie extends LeafRenderObjectWidget {
composition: composition,
delegates: delegates,
enableMergePaths: options?.enableMergePaths,
enableApplyingOpacityToLayers: options?.enableApplyingOpacityToLayers,
progress: progress,
frameRate: frameRate,
width: width,
@ -105,6 +106,7 @@ class RawLottie extends LeafRenderObjectWidget {
frameRate: frameRate,
delegates: delegates,
enableMergePaths: options?.enableMergePaths,
enableApplyingOpacityToLayers: options?.enableApplyingOpacityToLayers,
filterQuality: filterQuality,
)
..width = width

View File

@ -13,6 +13,7 @@ class RenderLottie extends RenderBox {
required LottieComposition? composition,
LottieDelegates? delegates,
bool? enableMergePaths,
bool? enableApplyingOpacityToLayers,
double progress = 0.0,
FrameRate? frameRate,
double? width,
@ -26,6 +27,8 @@ class RenderLottie extends RenderBox {
..setProgress(progress, frameRate: frameRate)
..delegates = delegates
..enableMergePaths = enableMergePaths ?? false
..isApplyingOpacityToLayersEnabled =
enableApplyingOpacityToLayers ?? false
..filterQuality = filterQuality)
: null,
_width = width,
@ -42,9 +45,11 @@ class RenderLottie extends RenderBox {
required FrameRate? frameRate,
required LottieDelegates? delegates,
bool? enableMergePaths,
bool? enableApplyingOpacityToLayers,
FilterQuality? filterQuality}) {
var drawable = _drawable;
enableMergePaths ??= false;
enableApplyingOpacityToLayers ??= false;
var needsLayout = false;
var needsPaint = false;
@ -71,6 +76,12 @@ class RenderLottie extends RenderBox {
drawable.enableMergePaths = enableMergePaths;
needsPaint = true;
}
if (enableApplyingOpacityToLayers !=
drawable.isApplyingOpacityToLayersEnabled) {
drawable.isApplyingOpacityToLayersEnabled =
enableApplyingOpacityToLayers;
needsPaint = true;
}
if (filterQuality != drawable.filterQuality) {
drawable.filterQuality = filterQuality;
needsPaint = true;
@ -91,6 +102,7 @@ class RenderLottie extends RenderBox {
/// aspect ratio.
double? get width => _width;
double? _width;
set width(double? value) {
if (value == _width) {
return;
@ -105,6 +117,7 @@ class RenderLottie extends RenderBox {
/// aspect ratio.
double? get height => _height;
double? _height;
set height(double? value) {
if (value == _height) {
return;
@ -116,6 +129,7 @@ class RenderLottie extends RenderBox {
/// How to inscribe the composition into the space allocated during layout.
BoxFit? get fit => _fit;
BoxFit? _fit;
set fit(BoxFit? value) {
if (value == _fit) {
return;
@ -130,6 +144,7 @@ class RenderLottie extends RenderBox {
/// not be null.
AlignmentGeometry get alignment => _alignment;
AlignmentGeometry _alignment;
set alignment(AlignmentGeometry value) {
if (value == _alignment) {
return;

View File

@ -5,18 +5,18 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a
sha256: "0816708f5fbcacca324d811297153fe3c8e047beb5c6752e12292d2974c17045"
url: "https://pub.dev"
source: hosted
version: "61.0.0"
version: "62.0.0"
analyzer:
dependency: "direct dev"
description:
name: analyzer
sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562
sha256: "21862995c9932cd082f89d72ae5f5e2c110d1a0204ad06e4ebaee8307b76b834"
url: "https://pub.dev"
source: hosted
version: "5.13.0"
version: "6.0.0"
archive:
dependency: "direct main"
description:
@ -29,10 +29,10 @@ packages:
dependency: transitive
description:
name: args
sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
async:
dependency: transitive
description:
@ -89,14 +89,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.3"
dart_internal:
dependency: transitive
description:
name: dart_internal
sha256: dae3976f383beddcfcd07ad5291a422df2c8c0a8a03c52cda63ac7b4f26e0f4e
url: "https://pub.dev"
source: hosted
version: "0.2.8"
dart_style:
dependency: "direct dev"
description:
name: dart_style
sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad
sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.2"
fake_async:
dependency: transitive
description:
@ -122,10 +130,10 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
version: "2.0.2"
flutter_test:
dependency: "direct dev"
description: flutter
@ -151,10 +159,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
matcher:
dependency: transitive
description:
@ -297,5 +305,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.0.0 <4.0.0"
dart: ">=3.0.0 <3.2.0"
flutter: ">=3.10.0"

View File

@ -1,6 +1,6 @@
name: lottie
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
version: 2.4.0
version: 2.5.0
repository: https://github.com/xvrh/lottie-flutter
environment:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 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: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 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: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.0 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: 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: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,40 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lottie/lottie.dart';
import 'package:path/path.dart' as p;
void main() {
testWidgets('Opacity layer option', (tester) async {
var size = const Size(500, 800);
tester.view.physicalSize = size;
tester.view.devicePixelRatio = 1.0;
var bytes =
File('example/assets/Tests/opacity_layers.json').readAsBytesSync();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Lottie.memory(
bytes,
options: LottieOptions(enableApplyingOpacityToLayers: true),
),
Lottie.memory(
bytes,
),
],
),
),
),
);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
await expectLater(find.byType(Scaffold),
matchesGoldenFile(p.join('goldens/opacity_layers.png')));
});
}