mirror of
https://github.com/xvrh/lottie-flutter.git
synced 2025-08-06 16:39:36 +08:00
Compare commits
29 Commits
xha/text_t
...
v2.7.0
Author | SHA1 | Date | |
---|---|---|---|
9e9de6d5b6 | |||
f19e86d644 | |||
ab9b5833c3 | |||
fe0032a6c2 | |||
b0bc35196e | |||
0600c44384 | |||
8a9ef53c63 | |||
6ffeaa603f | |||
08e629adaa | |||
bf3118b4cf | |||
434ae88aa8 | |||
6b752d829c | |||
124ba6997b | |||
fdc4018f57 | |||
b61ea14116 | |||
9c266bb98b | |||
cd4cc910c4 | |||
92502f1358 | |||
4520221a28 | |||
3f5422d44b | |||
61668b0509 | |||
1e9861e43f | |||
c32550cf15 | |||
9d4e66ea6b | |||
f58f3888da | |||
dc43a532b0 | |||
1b752bf341 | |||
21f34e6334 | |||
8dcb052fe1 |
9
.github/dependabot.yml
vendored
Normal file
9
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Dependabot configuration file.
|
||||
# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
6
.github/workflows/analyze-and-test.yaml
vendored
6
.github/workflows/analyze-and-test.yaml
vendored
@ -11,9 +11,9 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
flutter: ['stable']
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: ${{ matrix.flutter }}
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
name: Check that the web version can compile
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
|
9
.github/workflows/publish-on-pub.yaml
vendored
9
.github/workflows/publish-on-pub.yaml
vendored
@ -7,23 +7,22 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: subosito/flutter-action@v2
|
||||
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: |
|
||||
cat <<EOF > $PUB_CACHE/credentials.json
|
||||
mkdir -p $XDG_CONFIG_HOME/dart
|
||||
cat <<EOF > $XDG_CONFIG_HOME/dart/pub-credentials.json
|
||||
{
|
||||
"accessToken":"${{ secrets.OAUTH_ACCESS_TOKEN }}",
|
||||
"refreshToken":"${{ secrets.OAUTH_REFRESH_TOKEN }}",
|
||||
"tokenEndpoint":"https://accounts.google.com/o/oauth2/token",
|
||||
"scopes": [ "openid", "https://www.googleapis.com/auth/userinfo.email" ],
|
||||
"expiration": 1580681402856
|
||||
"expiration": 1691492965565
|
||||
}
|
||||
EOF
|
||||
- name: Publish package
|
||||
|
128
CHANGELOG.md
128
CHANGELOG.md
@ -1,4 +1,56 @@
|
||||
## [2.0.0]
|
||||
## 2.7.0
|
||||
- Support loading Fonts from a zip file
|
||||
- Fix a bug in Text with strokes
|
||||
- Fix gradient interpolation for opacity stops beyond the last color stop
|
||||
- Add color value callback to solid layer
|
||||
|
||||
## 2.6.0
|
||||
- Accept `List<int>` instead of `Uint8List` in `LottieComposition.fromBytes`
|
||||
- Stroke line cap defaults to butt instead of square
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
- Fix rounded corners modifying already rounded corners
|
||||
- Support box position in Document Data
|
||||
- Allow interpolating between gradients with different opacity stops
|
||||
- Add support for gradient opacity stops
|
||||
|
||||
## 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.
|
||||
It allows to change the cache behaviour and clear the entries.
|
||||
|
||||
```dart
|
||||
void main() {
|
||||
Lottie.cache.maximumSize = 10;
|
||||
Lottie.cache.clear();
|
||||
Lottie.cache.evict(NetworkLottie('https://lottie.com/anim.json'));
|
||||
}
|
||||
```
|
||||
|
||||
## 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`.
|
||||
@ -20,19 +72,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`)
|
||||
|
||||
@ -54,13 +106,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:
|
||||
@ -97,7 +149,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(
|
||||
@ -119,25 +171,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
|
||||
@ -148,20 +200,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
|
||||
@ -174,62 +226,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
|
||||
|
10
README.md
10
README.md
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,32 +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
|
||||
|
441
example/assets/GradientColorInterpolation.json
Normal file
441
example/assets/GradientColorInterpolation.json
Normal file
@ -0,0 +1,441 @@
|
||||
{
|
||||
"v": "4.8.0",
|
||||
"meta": {
|
||||
"g": "LottieFiles AE 3.1.1",
|
||||
"a": "",
|
||||
"k": "",
|
||||
"d": "",
|
||||
"tc": ""
|
||||
},
|
||||
"fr": 30,
|
||||
"ip": 0,
|
||||
"op": 151,
|
||||
"w": 430,
|
||||
"h": 932,
|
||||
"nm": "Sticker Unpack",
|
||||
"ddd": 1,
|
||||
"assets": [
|
||||
{
|
||||
"id": "comp_0",
|
||||
"layers": [
|
||||
]
|
||||
}
|
||||
],
|
||||
"layers": [
|
||||
{
|
||||
"ddd": 1,
|
||||
"ind": 1,
|
||||
"ty": 0,
|
||||
"nm": "Pc_Sticker Pack",
|
||||
"refId": "comp_0",
|
||||
"sr": 1,
|
||||
"ks": {
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100,
|
||||
"ix": 11
|
||||
},
|
||||
"rx": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.421
|
||||
],
|
||||
"y": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.55
|
||||
],
|
||||
"y": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"t": 1,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.985
|
||||
],
|
||||
"y": [
|
||||
0.168
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.857
|
||||
],
|
||||
"y": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"t": 21,
|
||||
"s": [
|
||||
-1.9
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 41,
|
||||
"s": [
|
||||
24.3
|
||||
]
|
||||
}
|
||||
],
|
||||
"ix": 8
|
||||
},
|
||||
"ry": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.421
|
||||
],
|
||||
"y": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.55
|
||||
],
|
||||
"y": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"t": 1,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.985
|
||||
],
|
||||
"y": [
|
||||
-0.28
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.857
|
||||
],
|
||||
"y": [
|
||||
0
|
||||
]
|
||||
},
|
||||
"t": 21,
|
||||
"s": [
|
||||
3.7
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 41,
|
||||
"s": [
|
||||
16
|
||||
]
|
||||
}
|
||||
],
|
||||
"ix": 9
|
||||
},
|
||||
"rz": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 10
|
||||
},
|
||||
"or": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ix": 7
|
||||
},
|
||||
"p": {
|
||||
"s": true,
|
||||
"x": {
|
||||
"a": 0,
|
||||
"k": 215,
|
||||
"ix": 3
|
||||
},
|
||||
"y": {
|
||||
"a": 0,
|
||||
"k": 466,
|
||||
"ix": 4
|
||||
},
|
||||
"z": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 5
|
||||
}
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
221,
|
||||
307.5,
|
||||
0
|
||||
],
|
||||
"ix": 1
|
||||
},
|
||||
"s": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.421,
|
||||
0.421,
|
||||
0.667
|
||||
],
|
||||
"y": [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.55,
|
||||
0.55,
|
||||
0.333
|
||||
],
|
||||
"y": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"t": 0,
|
||||
"s": [
|
||||
64.6,
|
||||
64.6,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.985,
|
||||
0.985,
|
||||
0.667
|
||||
],
|
||||
"y": [
|
||||
0.192,
|
||||
0.192,
|
||||
1
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.857,
|
||||
0.857,
|
||||
0.333
|
||||
],
|
||||
"y": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"t": 20,
|
||||
"s": [
|
||||
74.2,
|
||||
74.2,
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 40,
|
||||
"s": [
|
||||
7,
|
||||
7,
|
||||
100
|
||||
]
|
||||
}
|
||||
],
|
||||
"ix": 6
|
||||
}
|
||||
},
|
||||
"ao": 0,
|
||||
"w": 442,
|
||||
"h": 615,
|
||||
"ip": 0,
|
||||
"op": 41,
|
||||
"st": 0,
|
||||
"bm": 0
|
||||
},
|
||||
{
|
||||
"ddd": 0,
|
||||
"ind": 14,
|
||||
"ty": 4,
|
||||
"nm": "Shape Layer 2",
|
||||
"parent": 1,
|
||||
"sr": 1,
|
||||
"ks": {
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100,
|
||||
"ix": 11
|
||||
},
|
||||
"r": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 10
|
||||
},
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
221,
|
||||
307.5,
|
||||
0
|
||||
],
|
||||
"ix": 2
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ix": 1
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
538.543,
|
||||
538.543,
|
||||
100
|
||||
],
|
||||
"ix": 6
|
||||
}
|
||||
},
|
||||
"ao": 0,
|
||||
"shapes": [
|
||||
{
|
||||
"ty": "gr",
|
||||
"it": [
|
||||
{
|
||||
"ty": "rc",
|
||||
"d": 1,
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
294,
|
||||
403
|
||||
],
|
||||
"ix": 2
|
||||
},
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ix": 3
|
||||
},
|
||||
"r": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 4
|
||||
},
|
||||
"nm": "Rectangle Path 1",
|
||||
"mn": "ADBE Vector Shape - Rect",
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "gf",
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100,
|
||||
"ix": 10
|
||||
},
|
||||
"r": 1,
|
||||
"bm": 0,
|
||||
"g": {
|
||||
"p": 3,
|
||||
"k": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0.373,
|
||||
0.024,
|
||||
0.898,
|
||||
0.359,
|
||||
0.186,
|
||||
0.012,
|
||||
0.449,
|
||||
0.998,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0.5,
|
||||
0.5,
|
||||
1,
|
||||
0
|
||||
],
|
||||
"ix": 9
|
||||
}
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ix": 5
|
||||
},
|
||||
"e": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
149,
|
||||
0
|
||||
],
|
||||
"ix": 6
|
||||
},
|
||||
"t": 2,
|
||||
"h": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 7
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 8
|
||||
},
|
||||
"nm": "Gradient Fill 1",
|
||||
"mn": "ADBE Vector Graphic - G-Fill",
|
||||
"hd": false
|
||||
}
|
||||
],
|
||||
"nm": "Rectangle 1",
|
||||
"np": 3,
|
||||
"cix": 2,
|
||||
"bm": 0,
|
||||
"ix": 1,
|
||||
"mn": "ADBE Vector Group",
|
||||
"hd": false
|
||||
}
|
||||
],
|
||||
"ip": 0,
|
||||
"op": 42,
|
||||
"st": 0,
|
||||
"bm": 0
|
||||
}
|
||||
],
|
||||
"markers": []
|
||||
}
|
1
example/assets/Tests/1669133489622.json
Normal file
1
example/assets/Tests/1669133489622.json
Normal file
File diff suppressed because one or more lines are too long
1
example/assets/Tests/BeyondBounds.json
Normal file
1
example/assets/Tests/BeyondBounds.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.8.2","fr":23.9759979248047,"ip":0,"op":71.9999937681822,"w":400,"h":400,"nm":"BeyondBounds","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,200,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[510.547,510.547],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"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":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":71.9999937681822,"st":0,"bm":0}],"markers":[]}
|
1
example/assets/Tests/BoxPosition.json
Normal file
1
example/assets/Tests/BoxPosition.json
Normal file
File diff suppressed because one or more lines are too long
5855
example/assets/Tests/DefaultLineJoinCap.json
Normal file
5855
example/assets/Tests/DefaultLineJoinCap.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
example/assets/Tests/EmbeddedFont.zip
Normal file
BIN
example/assets/Tests/EmbeddedFont.zip
Normal file
Binary file not shown.
1
example/assets/Tests/Framerate.json
Normal file
1
example/assets/Tests/Framerate.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.6","fr":3,"ip":0,"op":3,"w":200,"h":200,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[30,30,0],"to":[21.667,21.667,0],"ti":[-21.667,-21.667,0]},{"t":2,"s":[160,160,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[58.742,58.742],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3,"st":0,"ct":1,"bm":0}],"markers":[]}
|
1
example/assets/Tests/Heart.json
Normal file
1
example/assets/Tests/Heart.json
Normal file
File diff suppressed because one or more lines are too long
1038
example/assets/Tests/InterpolateBetweenOpacityStops.json
Executable file
1038
example/assets/Tests/InterpolateBetweenOpacityStops.json
Executable file
File diff suppressed because it is too large
Load Diff
1
example/assets/Tests/LargeComposition.json
Normal file
1
example/assets/Tests/LargeComposition.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.8.1","fr":25,"ip":0,"op":2,"w":2000,"h":4000,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000,2000,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1554.562,597.062],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.220496237278,1,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1.281,-21.469],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1780.188,3801.75],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.116727701823,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[2.094,12.875],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":2,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":1,"nm":"Red Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1000,2000,0],"ix":2,"l":2},"a":{"a":0,"k":[1000,2000,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"sw":2000,"sh":4000,"sc":"#ff0000","ip":0,"op":2,"st":0,"bm":0}],"markers":[]}
|
1
example/assets/Tests/Multiline.json
Normal file
1
example/assets/Tests/Multiline.json
Normal file
File diff suppressed because one or more lines are too long
494
example/assets/Tests/OpacityStops.json
Normal file
494
example/assets/Tests/OpacityStops.json
Normal file
@ -0,0 +1,494 @@
|
||||
{
|
||||
"tgs": 1,
|
||||
"v": "5.5.2",
|
||||
"fr": 60,
|
||||
"ip": 0,
|
||||
"op": 180,
|
||||
"w": 512,
|
||||
"h": 512,
|
||||
"nm": "02_ricl_klass - 3:00",
|
||||
"ddd": 0,
|
||||
"assets": [],
|
||||
"layers": [
|
||||
{
|
||||
"ddd": 0,
|
||||
"ind": 6,
|
||||
"ty": 4,
|
||||
"parent": 5,
|
||||
"sr": 1,
|
||||
"ks": {
|
||||
"o": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": -105,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": -104,
|
||||
"s": [
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 34,
|
||||
"s": [
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 35,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 75,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 76,
|
||||
"s": [
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 214,
|
||||
"s": [
|
||||
100
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 215,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
-0.031,
|
||||
0
|
||||
]
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
-87,
|
||||
-18.182,
|
||||
0
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
50,
|
||||
33,
|
||||
100
|
||||
]
|
||||
}
|
||||
},
|
||||
"ao": 0,
|
||||
"shapes": [
|
||||
{
|
||||
"ty": "gr",
|
||||
"it": [
|
||||
{
|
||||
"ind": 0,
|
||||
"ty": "sh",
|
||||
"ks": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": 0.833,
|
||||
"y": 0.833
|
||||
},
|
||||
"o": {
|
||||
"x": 0.167,
|
||||
"y": 0.167
|
||||
},
|
||||
"t": 213,
|
||||
"s": [
|
||||
{
|
||||
"i": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
]
|
||||
],
|
||||
"o": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
]
|
||||
],
|
||||
"v": [
|
||||
[
|
||||
571.25,
|
||||
-298.22
|
||||
],
|
||||
[
|
||||
-192.5,
|
||||
-267.902
|
||||
],
|
||||
[
|
||||
-182.875,
|
||||
510.152
|
||||
],
|
||||
[
|
||||
575.125,
|
||||
547.848
|
||||
]
|
||||
],
|
||||
"c": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 214,
|
||||
"s": [
|
||||
{
|
||||
"i": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
]
|
||||
],
|
||||
"o": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
]
|
||||
],
|
||||
"v": [
|
||||
[
|
||||
122.25,
|
||||
-242.159
|
||||
],
|
||||
[
|
||||
-192.5,
|
||||
-267.902
|
||||
],
|
||||
[
|
||||
-181.875,
|
||||
178.333
|
||||
],
|
||||
[
|
||||
175.125,
|
||||
141.788
|
||||
]
|
||||
],
|
||||
"c": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "gf",
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100
|
||||
},
|
||||
"r": 1,
|
||||
"bm": 0,
|
||||
"g": {
|
||||
"p": 5,
|
||||
"k": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0.832,
|
||||
0.275,
|
||||
0.89,
|
||||
0.086,
|
||||
|
||||
0.86,
|
||||
0.275,
|
||||
0.89,
|
||||
0.086,
|
||||
|
||||
0.887,
|
||||
0.275,
|
||||
0.89,
|
||||
0.086,
|
||||
|
||||
0.944,
|
||||
0.275,
|
||||
0.89,
|
||||
0.086,
|
||||
|
||||
1,
|
||||
0.275,
|
||||
0.89,
|
||||
0.086,
|
||||
|
||||
0.65,
|
||||
0,
|
||||
|
||||
0.785,
|
||||
0.5,
|
||||
|
||||
0.84,
|
||||
1,
|
||||
|
||||
0.862,
|
||||
1,
|
||||
|
||||
0.885,
|
||||
1,
|
||||
|
||||
0.896,
|
||||
0.5,
|
||||
|
||||
0.908,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
457.898,
|
||||
-71.143
|
||||
]
|
||||
},
|
||||
"e": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
-182.411,
|
||||
-47.941
|
||||
]
|
||||
},
|
||||
"t": 2,
|
||||
"h": {
|
||||
"a": 0,
|
||||
"k": 0
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": 97.679
|
||||
},
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "tr",
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
100,
|
||||
100
|
||||
]
|
||||
},
|
||||
"r": {
|
||||
"a": 0,
|
||||
"k": 0
|
||||
},
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100
|
||||
},
|
||||
"sk": {
|
||||
"a": 0,
|
||||
"k": 0
|
||||
},
|
||||
"sa": {
|
||||
"a": 0,
|
||||
"k": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"bm": 0,
|
||||
"hd": false
|
||||
}
|
||||
],
|
||||
"ip": 0,
|
||||
"op": 180,
|
||||
"st": -120,
|
||||
"bm": 0
|
||||
}
|
||||
]
|
||||
}
|
1
example/assets/Tests/PrecompBlurDecimapPrecompSize.json
Normal file
1
example/assets/Tests/PrecompBlurDecimapPrecompSize.json
Normal file
File diff suppressed because one or more lines are too long
386
example/assets/Tests/RoundedWithAlreadyRoundedCorners.json
Normal file
386
example/assets/Tests/RoundedWithAlreadyRoundedCorners.json
Normal file
@ -0,0 +1,386 @@
|
||||
{
|
||||
"v": "5.9.1",
|
||||
"fr": 60,
|
||||
"ip": 0,
|
||||
"op": 56,
|
||||
"w": 1080,
|
||||
"h": 1080,
|
||||
"nm": "Warning",
|
||||
"ddd": 0,
|
||||
"assets": [
|
||||
{
|
||||
"id": "comp_0",
|
||||
"nm": "Warning_2",
|
||||
"fr": 60,
|
||||
"layers": [
|
||||
{
|
||||
"ddd": 0,
|
||||
"ind": 3,
|
||||
"ty": 4,
|
||||
"nm": "CERCHIO contorni",
|
||||
"sr": 1,
|
||||
"ks": {
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100,
|
||||
"ix": 11
|
||||
},
|
||||
"r": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 10
|
||||
},
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
24.5,
|
||||
24.5,
|
||||
0
|
||||
],
|
||||
"ix": 2,
|
||||
"l": 2
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
29.5,
|
||||
29.5,
|
||||
0
|
||||
],
|
||||
"ix": 1,
|
||||
"l": 2
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
100,
|
||||
100,
|
||||
100
|
||||
],
|
||||
"ix": 6,
|
||||
"l": 2
|
||||
}
|
||||
},
|
||||
"ao": 0,
|
||||
"shapes": [
|
||||
{
|
||||
"ty": "gr",
|
||||
"it": [
|
||||
{
|
||||
"ind": 0,
|
||||
"ty": "sh",
|
||||
"ix": 1,
|
||||
"ks": {
|
||||
"a": 0,
|
||||
"k": {
|
||||
"i": [
|
||||
[
|
||||
-12.15,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
-12.15
|
||||
],
|
||||
[
|
||||
12.15,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
12.15
|
||||
]
|
||||
],
|
||||
"o": [
|
||||
[
|
||||
12.15,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
12.15
|
||||
],
|
||||
[
|
||||
-12.15,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
-12.15
|
||||
]
|
||||
],
|
||||
"v": [
|
||||
[
|
||||
0,
|
||||
-22
|
||||
],
|
||||
[
|
||||
22,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
22
|
||||
],
|
||||
[
|
||||
-22,
|
||||
0
|
||||
]
|
||||
],
|
||||
"c": true
|
||||
},
|
||||
"ix": 2
|
||||
},
|
||||
"nm": "Tracciato 1",
|
||||
"mn": "ADBE Vector Shape - Group",
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "st",
|
||||
"c": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
0.956862804936,
|
||||
0.290196078431,
|
||||
0.239215701234,
|
||||
1
|
||||
],
|
||||
"ix": 3
|
||||
},
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100,
|
||||
"ix": 4
|
||||
},
|
||||
"w": {
|
||||
"a": 0,
|
||||
"k": 3,
|
||||
"ix": 5
|
||||
},
|
||||
"lc": 2,
|
||||
"lj": 2,
|
||||
"bm": 0,
|
||||
"nm": "Traccia 1",
|
||||
"mn": "ADBE Vector Graphic - Stroke",
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "tr",
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
29.5,
|
||||
29.5
|
||||
],
|
||||
"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": "Gruppo 1",
|
||||
"np": 2,
|
||||
"cix": 2,
|
||||
"bm": 0,
|
||||
"ix": 1,
|
||||
"mn": "ADBE Vector Group",
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "tm",
|
||||
"s": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 0,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 36,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"ix": 1
|
||||
},
|
||||
"e": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{
|
||||
"i": {
|
||||
"x": [
|
||||
0.833
|
||||
],
|
||||
"y": [
|
||||
0.833
|
||||
]
|
||||
},
|
||||
"o": {
|
||||
"x": [
|
||||
0.167
|
||||
],
|
||||
"y": [
|
||||
0.167
|
||||
]
|
||||
},
|
||||
"t": 0,
|
||||
"s": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"t": 36,
|
||||
"s": [
|
||||
100
|
||||
]
|
||||
}
|
||||
],
|
||||
"ix": 2
|
||||
},
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 3
|
||||
},
|
||||
"m": 1,
|
||||
"ix": 2,
|
||||
"nm": "Taglia tracciati 1",
|
||||
"mn": "ADBE Vector Filter - Trim",
|
||||
"hd": false
|
||||
},
|
||||
{
|
||||
"ty": "rd",
|
||||
"nm": "Angoli arrotondati 1",
|
||||
"r": {
|
||||
"a": 0,
|
||||
"k": 10,
|
||||
"ix": 1
|
||||
},
|
||||
"ix": 3,
|
||||
"mn": "ADBE Vector Filter - RC",
|
||||
"hd": false
|
||||
}
|
||||
],
|
||||
"ip": 0,
|
||||
"op": 57,
|
||||
"st": 0,
|
||||
"bm": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"layers": [
|
||||
{
|
||||
"ddd": 0,
|
||||
"ind": 1,
|
||||
"ty": 0,
|
||||
"nm": "Warning_2",
|
||||
"refId": "comp_0",
|
||||
"sr": 1,
|
||||
"ks": {
|
||||
"o": {
|
||||
"a": 0,
|
||||
"k": 100,
|
||||
"ix": 11
|
||||
},
|
||||
"r": {
|
||||
"a": 0,
|
||||
"k": 0,
|
||||
"ix": 10
|
||||
},
|
||||
"p": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
530,
|
||||
530,
|
||||
0
|
||||
],
|
||||
"ix": 2,
|
||||
"l": 2
|
||||
},
|
||||
"a": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
24,
|
||||
24,
|
||||
0
|
||||
],
|
||||
"ix": 1,
|
||||
"l": 2
|
||||
},
|
||||
"s": {
|
||||
"a": 0,
|
||||
"k": [
|
||||
2000,
|
||||
2000,
|
||||
100
|
||||
],
|
||||
"ix": 6,
|
||||
"l": 2
|
||||
}
|
||||
},
|
||||
"ao": 0,
|
||||
"w": 48,
|
||||
"h": 48,
|
||||
"ip": 0,
|
||||
"op": 57,
|
||||
"st": 0,
|
||||
"bm": 0
|
||||
}
|
||||
],
|
||||
"markers": []
|
||||
}
|
1
example/assets/Tests/SplitPathTransform.json
Normal file
1
example/assets/Tests/SplitPathTransform.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.7.4","fr":60,"ip":0,"op":63,"w":400,"h":400,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.984],"y":[0.777]},"o":{"x":[0.411],"y":[0.047]},"t":0,"s":[200]},{"t":62,"s":[460]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.926],"y":[0.943]},"o":{"x":[0.028],"y":[1.152]},"t":0,"s":[200]},{"t":62,"s":[460]}],"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[119.332,119.332],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-130.404,-126.932],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":63,"st":0,"bm":0}],"markers":[]}
|
2039
example/assets/Tests/TextWithPsCenter.json
Normal file
2039
example/assets/Tests/TextWithPsCenter.json
Normal file
File diff suppressed because it is too large
Load Diff
1626
example/assets/Tests/TextWithPsLeft.json
Normal file
1626
example/assets/Tests/TextWithPsLeft.json
Normal file
File diff suppressed because it is too large
Load Diff
1
example/assets/Tests/Thumb.json
Normal file
1
example/assets/Tests/Thumb.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.6","fr":29.9700012207031,"ip":0,"op":190.000007738859,"w":24,"h":24,"nm":"Thumb","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":1,"d":1,"pt":{"a":0,"k":5,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"ir":{"a":0,"k":5,"ix":6},"is":{"a":0,"k":0,"ix":8},"or":{"a":0,"k":12,"ix":7},"os":{"a":0,"k":0,"ix":9},"ix":1,"nm":"Polystar Path 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.922702133656,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"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":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":190.000007738859,"st":0,"ct":1,"bm":0}],"markers":[]}
|
1
example/assets/Tests/TimeStretchAndStartOffset.json
Normal file
1
example/assets/Tests/TimeStretchAndStartOffset.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.5.8","fr":60,"ip":0,"op":166,"w":828,"h":1215,"nm":"Залитые дуги 10 + opacity","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Sinie 2","td":1,"sr":1.53474205216067,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[413.199,607.88,0],"ix":2},"a":{"a":0,"k":[168.949,195.88,0],"ix":1},"s":{"a":0,"k":[207.219,207.219,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[11.998,6.913],[13.844,0.193],[-28.149,-0.401]],"o":[[-11.991,-6.921],[14.447,24.162],[-7.102,-11.886]],"v":[[5.137,-8.915],[-34.263,-19.764],[34.265,19.754]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-14.745,-25.464],[0.311,-0.18],[0.113,0],[14.745,25.466],[-0.31,0.179],[-0.114,0]],"o":[[29.425,0.007],[0.178,0.311],[-0.098,0.056],[-29.427,-0.005],[-0.179,-0.31],[0.099,-0.057],[0,0]],"v":[[-35.4,-21.063],[35.964,20.09],[35.725,20.977],[35.403,21.063],[-35.963,-20.09],[-35.725,-20.976],[-35.401,-21.063]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.894117706897,0,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[132.535,174.966],"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":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":48,"op":166,"st":-37.8760708166762,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Krug siniy 2","tt":1,"sr":0.98917079207921,"ks":{"o":{"a":0,"k":50,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[412.455,610.955,0],"ix":2},"a":{"a":0,"k":[135.603,464.717,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[0.252,0.252,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":55,"s":[0,0,100]},{"t":111.000102732441,"s":[79.385,79.385,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,105.185],[105.185,0],[0,-105.185],[-105.186,0]],"o":[[0,-105.185],[-105.186,0],[0,105.185],[105.185,0]],"v":[[190.455,0],[0,-190.455],[-190.455,0],[0,190.456]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[135.603,464.717],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[174.179,174.179],"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,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":48,"op":166,"st":25.2165841584158,"bm":0}],"markers":[]}
|
BIN
example/assets/Tests/ZipInlineImage.zip
Normal file
BIN
example/assets/Tests/ZipInlineImage.zip
Normal file
Binary file not shown.
BIN
example/assets/Tests/anim_jpg.zip
Normal file
BIN
example/assets/Tests/anim_jpg.zip
Normal file
Binary file not shown.
16284
example/assets/Tests/issue_288.json
Normal file
16284
example/assets/Tests/issue_288.json
Normal file
File diff suppressed because it is too large
Load Diff
1
example/assets/Tests/opacity_layers.json
Normal file
1
example/assets/Tests/opacity_layers.json
Normal 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":[]}
|
1
example/assets/Tests/text_with_parent_alpha.json
Normal file
1
example/assets/Tests/text_with_parent_alpha.json
Normal file
File diff suppressed because one or more lines are too long
2492
example/assets/Tests/wile.json
Normal file
2492
example/assets/Tests/wile.json
Normal file
File diff suppressed because it is too large
Load Diff
243
example/assets/issue270.json
Normal file
243
example/assets/issue270.json
Normal 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": []
|
||||
}
|
1
example/assets/pass_loading.json
Normal file
1
example/assets/pass_loading.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.12.1","fr":60,"ip":0,"op":120,"w":853,"h":480,"nm":"Comp 1","ddd":0,"assets":[],"fonts":{"list":[{"fName":"Pretendard-Bold","fFamily":"Pretendard","fStyle":"Bold","ascent":70.7131249997765}]},"layers":[{"ddd":0,"ind":1,"ty":5,"nm":"PASS","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[426,235.889,0],"ix":2,"l":2},"a":{"a":0,"k":[6.157,-60.098,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"t":{"d":{"k":[{"s":{"s":170,"f":"Pretendard-Bold","t":"PASS","ca":0,"j":2,"tr":49,"lh":317,"ls":0,"fc":[1,1,1],"sc":[0.941,0.941,0.941],"sw":0.00999999977648,"of":true},"t":0}]},"p":{},"m":{"g":1,"a":{"a":0,"k":[0,0],"ix":2}},"a":[{"nm":"Animator 1","s":{"t":0,"xe":{"a":0,"k":0,"ix":7},"ne":{"a":0,"k":0,"ix":8},"a":{"a":0,"k":100,"ix":4},"b":1,"rn":0,"sh":1,"sm":{"a":0,"k":100,"ix":6},"s":{"a":1,"k":[{"i":{"x":[0.205],"y":[1]},"o":{"x":[0.77],"y":[0]},"t":10,"s":[0]},{"t":47,"s":[100]}],"ix":1},"r":1},"a":{"p":{"a":0,"k":[0,88,0],"ix":2},"o":{"a":0,"k":0,"ix":9},"t":{"a":0,"k":-66,"ix":89}}},{"nm":"Animator 2","s":{"t":0,"xe":{"a":0,"k":0,"ix":7},"ne":{"a":0,"k":0,"ix":8},"a":{"a":0,"k":100,"ix":4},"b":1,"rn":0,"sh":1,"sm":{"a":0,"k":100,"ix":6},"r":1},"a":{"t":{"a":1,"k":[{"i":{"x":[0.092],"y":[1]},"o":{"x":[0.887],"y":[0]},"t":46,"s":[-7]},{"t":90,"s":[4]}],"ix":89}}}]},"ip":10,"op":130,"st":10,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":1,"nm":"Dark Turquoise Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[426.5,240,0],"ix":2,"l":2},"a":{"a":0,"k":[75,50,0],"ix":1,"l":2},"s":{"a":0,"k":[568.667,480,100],"ix":6,"l":2}},"ao":0,"sw":150,"sh":100,"sc":"#003626","ip":0,"op":120,"st":0,"bm":0}],"markers":[],"props":{},"chars":[{"ch":"P","size":170,"style":"Bold","w":62.3,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,14.16],[16.113,0],[0,0]],"o":[[0,0],[0,0],[0,0],[16.309,0],[0,-13.965],[0,0],[0,0]],"v":[[5.957,0],[20.605,0],[20.605,-23.047],[33.301,-23.047],[58.984,-46.875],[33.691,-70.703],[5.957,-70.703]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,-7.031],[8.691,0]],"o":[[0,0],[0,0],[8.691,0],[0,7.129],[0,0]],"v":[[20.605,-34.863],[20.605,-58.691],[30.957,-58.691],[43.848,-46.875],[30.957,-34.863]],"c":true},"ix":2},"nm":"P","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"P","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Pretendard"},{"ch":"A","size":170,"style":"Bold","w":71.78,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[17.773,0],[23.145,-16.309],[48.73,-16.309],[54.004,0],[69.727,0],[45.312,-70.703],[26.465,-70.703],[1.953,0]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[26.855,-27.734],[35.645,-54.785],[36.133,-54.785],[45.02,-27.734]],"c":true},"ix":2},"nm":"A","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"A","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Pretendard"},{"ch":"S","size":170,"style":"Bold","w":62.99,"data":{"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.586,-5.566],[0,0],[15.625,0],[0,-12.891],[-11.914,-2.93],[0,0],[0,-4.785],[7.715,0],[0.488,7.129],[0,0],[-17.09,0],[0,12.988],[12.109,2.734],[0,0],[-0.098,5.078],[-7.422,0]],"o":[[0,0],[-0.195,-12.5],[-15.43,0],[0,10.352],[0,0],[7.715,1.953],[0,5.273],[-7.812,0],[0,0],[0.391,15.137],[17.188,0],[0,-11.816],[0,0],[-6.055,-1.367],[0.098,-4.688],[7.129,0]],"v":[[44.336,-50.488],[58.398,-50.488],[32.227,-71.68],[5.469,-50.293],[24.707,-31.055],[32.422,-29.199],[44.531,-20.215],[31.836,-11.328],[17.871,-22.07],[3.613,-22.07],[32.031,0.977],[59.375,-20.215],[38.184,-40.918],[31.836,-42.48],[20.508,-51.27],[32.129,-59.375]],"c":true},"ix":2},"nm":"S","mn":"ADBE Vector Shape - Group","hd":false}],"nm":"S","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}]},"fFamily":"Pretendard"}]}
|
BIN
example/assets/vegan_font.zip
Normal file
BIN
example/assets/vegan_font.zip
Normal file
Binary file not shown.
59
example/lib/examples/cache.dart
Normal file
59
example/lib/examples/cache.dart
Normal file
@ -0,0 +1,59 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lottie/lottie.dart';
|
||||
|
||||
void main() => runApp(const App());
|
||||
|
||||
class App extends StatelessWidget {
|
||||
const App({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(body: _Page()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Page extends StatefulWidget {
|
||||
@override
|
||||
__PageState createState() => __PageState();
|
||||
}
|
||||
|
||||
class __PageState extends State<_Page> {
|
||||
var _animationKey = UniqueKey();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Lottie.network(
|
||||
'https://assets10.lottiefiles.com/datafiles/QeC7XD39x4C1CIj/data.json',
|
||||
key: _animationKey,
|
||||
fit: BoxFit.contain,
|
||||
width: 200,
|
||||
height: 200,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
Lottie.cache.clear();
|
||||
Lottie.cache.maximumSize = 10;
|
||||
},
|
||||
child: const Text('Clear cache'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_animationKey = UniqueKey();
|
||||
});
|
||||
},
|
||||
child: const Text('Recreate animation'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
130
example/lib/examples/draw_cache.dart
Normal file
130
example/lib/examples/draw_cache.dart
Normal 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();
|
||||
}
|
||||
}
|
@ -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',
|
||||
|
@ -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"))
|
||||
|
@ -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'
|
||||
|
@ -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: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
|
||||
|
||||
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
|
||||
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.12.1
|
||||
|
@ -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 = 1430;
|
||||
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;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1000"
|
||||
LastUpgradeVersion = "1430"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -5,72 +5,82 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.3.2"
|
||||
version: "3.4.6"
|
||||
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: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
version: "1.17.2"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
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: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
version: "2.1.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -80,16 +90,18 @@ 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: ad76540d21c066228ee3f9d1dad64a9f7e46530e8bb7c85011a88bc1fd874bc5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.0.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -99,142 +111,161 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: golden_toolkit
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "8f74adab33154fe7b731395782797021f97d2edc52f7bfb85ff4f1b5c4a215f0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.0"
|
||||
version: "0.15.0"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
version: "1.1.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
|
||||
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.7"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.0.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.0.0"
|
||||
version: "2.7.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.12"
|
||||
version: "0.12.16"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
version: "0.5.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: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
version: "2.1.1"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.21"
|
||||
path_provider_ios:
|
||||
version: "2.2.0"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
name: path_provider_foundation
|
||||
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
version: "2.3.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||
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.2.1"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "2.1.1"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
version: "2.2.1"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.1.3"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
process:
|
||||
version: "2.1.6"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
name: pointycastle
|
||||
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.4"
|
||||
version: "3.7.3"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -244,72 +275,90 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
version: "1.10.0"
|
||||
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: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.12"
|
||||
version: "0.6.0"
|
||||
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"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.4-beta"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
version: "5.0.9"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0+2"
|
||||
version: "1.0.3"
|
||||
sdks:
|
||||
dart: ">=2.18.0 <3.0.0"
|
||||
flutter: ">=3.3.0"
|
||||
dart: ">=3.1.0 <4.0.0"
|
||||
flutter: ">=3.13.0"
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
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;
|
||||
|
@ -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.
|
||||
|
@ -52,18 +52,20 @@ class ContentGroup implements DrawingContent, PathContent, KeyPathElement {
|
||||
List<PathContent>? _pathContents;
|
||||
TransformKeyframeAnimation? _transformAnimation;
|
||||
|
||||
ContentGroup(final LottieDrawable lottieDrawable, BaseLayer layer,
|
||||
ShapeGroup shapeGroup)
|
||||
ContentGroup(
|
||||
LottieDrawable lottieDrawable, BaseLayer layer, ShapeGroup shapeGroup)
|
||||
: this.copy(
|
||||
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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ class GradientStrokeContent extends BaseStrokeContent {
|
||||
ValueCallbackKeyframeAnimation<List<Color>, List<Color>>?
|
||||
_colorCallbackAnimation;
|
||||
|
||||
GradientStrokeContent(final LottieDrawable lottieDrawable, BaseLayer layer,
|
||||
GradientStroke stroke)
|
||||
GradientStrokeContent(
|
||||
LottieDrawable lottieDrawable, BaseLayer layer, GradientStroke stroke)
|
||||
: name = stroke.name,
|
||||
_type = stroke.gradientType,
|
||||
_hidden = stroke.hidden,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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';
|
||||
@ -168,12 +169,12 @@ class RoundedCornersContent implements ShapeModifierContent {
|
||||
var previousCurveData = modifiedCurves[
|
||||
floorMod(modifiedCurvesIndex - 1, modifiedCurves.length)];
|
||||
var currentCurveData = modifiedCurves[modifiedCurvesIndex];
|
||||
previousCurveData.controlPoint2 =
|
||||
Offset(previousCurve.vertex.dx, previousCurve.vertex.dy);
|
||||
previousCurveData.controlPoint2 = Offset(
|
||||
previousCurve.controlPoint2.dx, previousCurve.controlPoint2.dy);
|
||||
previousCurveData.vertex =
|
||||
Offset(previousCurve.vertex.dx, previousCurve.vertex.dy);
|
||||
currentCurveData.controlPoint1 =
|
||||
Offset(startingCurve.vertex.dx, startingCurve.vertex.dy);
|
||||
currentCurveData.controlPoint1 = Offset(
|
||||
startingCurve.controlPoint1.dx, startingCurve.controlPoint1.dy);
|
||||
modifiedCurvesIndex++;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class StrokeContent extends BaseStrokeContent {
|
||||
BaseKeyframeAnimation<ColorFilter, ColorFilter?>? _colorFilterAnimation;
|
||||
|
||||
StrokeContent(
|
||||
final LottieDrawable lottieDrawable, BaseLayer layer, ShapeStroke stroke)
|
||||
LottieDrawable lottieDrawable, BaseLayer layer, ShapeStroke stroke)
|
||||
: name = stroke.name,
|
||||
_hidden = stroke.hidden,
|
||||
_colorAnimation = stroke.color.createAnimation(),
|
||||
|
@ -52,16 +52,19 @@ class _DocumentDataValueCallback extends LottieValueCallback<DocumentData> {
|
||||
? frameInfo.endValue!
|
||||
: frameInfo.startValue!;
|
||||
return DocumentData(
|
||||
text: text,
|
||||
fontName: baseDocumentData.fontName,
|
||||
size: baseDocumentData.size,
|
||||
justification: baseDocumentData.justification,
|
||||
tracking: baseDocumentData.tracking,
|
||||
lineHeight: baseDocumentData.lineHeight,
|
||||
baselineShift: baseDocumentData.baselineShift,
|
||||
color: baseDocumentData.color,
|
||||
strokeColor: baseDocumentData.strokeColor,
|
||||
strokeWidth: baseDocumentData.strokeWidth,
|
||||
strokeOverFill: baseDocumentData.strokeOverFill);
|
||||
text: text,
|
||||
fontName: baseDocumentData.fontName,
|
||||
size: baseDocumentData.size,
|
||||
justification: baseDocumentData.justification,
|
||||
tracking: baseDocumentData.tracking,
|
||||
lineHeight: baseDocumentData.lineHeight,
|
||||
baselineShift: baseDocumentData.baselineShift,
|
||||
color: baseDocumentData.color,
|
||||
strokeColor: baseDocumentData.strokeColor,
|
||||
strokeWidth: baseDocumentData.strokeWidth,
|
||||
strokeOverFill: baseDocumentData.strokeOverFill,
|
||||
boxPosition: baseDocumentData.boxPosition,
|
||||
boxSize: baseDocumentData.boxSize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:ui';
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
@ -41,7 +42,7 @@ class LottieComposition {
|
||||
name: name, imageProviderFactory: imageProviderFactory);
|
||||
}
|
||||
|
||||
static Future<LottieComposition> fromBytes(Uint8List bytes,
|
||||
static Future<LottieComposition> fromBytes(List<int> bytes,
|
||||
{String? name, LottieImageProviderFactory? imageProviderFactory}) async {
|
||||
Archive? archive;
|
||||
if (bytes[0] == 0x50 && bytes[1] == 0x4B) {
|
||||
@ -73,6 +74,14 @@ class LottieComposition {
|
||||
composition, image, MemoryImage(found.content as Uint8List));
|
||||
}
|
||||
}
|
||||
|
||||
for (var font in archive.files.where((f) => f.name.endsWith('.ttf'))) {
|
||||
var fileName = p.basenameWithoutExtension(font.name).toLowerCase();
|
||||
var existingFont = composition.fonts.values
|
||||
.firstWhereOrNull((f) => f.family.toLowerCase() == fileName);
|
||||
await loadFontFromList(font.content as Uint8List,
|
||||
fontFamily: existingFont?.family);
|
||||
}
|
||||
}
|
||||
|
||||
return composition;
|
||||
|
@ -4,6 +4,7 @@ import '../lottie.dart';
|
||||
import 'composition.dart';
|
||||
import 'l.dart';
|
||||
import 'lottie_builder.dart';
|
||||
import 'providers/lottie_provider.dart';
|
||||
|
||||
/// A widget to display a loaded [LottieComposition].
|
||||
/// The [controller] property allows to specify a custom AnimationController that
|
||||
@ -11,6 +12,9 @@ import 'lottie_builder.dart';
|
||||
/// automatically and the behavior could be adjusted with the properties [animate],
|
||||
/// [repeat] and [reverse].
|
||||
class Lottie extends StatefulWidget {
|
||||
/// The cache instance for recently loaded Lottie compositions.
|
||||
static LottieCache get cache => sharedLottieCache;
|
||||
|
||||
const Lottie({
|
||||
super.key,
|
||||
required this.composition,
|
||||
@ -298,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.
|
||||
|
@ -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
|
||||
@ -441,17 +442,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 +478,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,
|
||||
|
@ -5,9 +5,22 @@ import 'lottie_drawable.dart';
|
||||
import 'lottie_image_asset.dart';
|
||||
import 'value_delegate.dart';
|
||||
|
||||
// TODO(xha): recognize style Bold, Medium, Regular, SemiBold, etc...
|
||||
TextStyle defaultTextStyleDelegate(LottieFontStyle font) =>
|
||||
TextStyle(fontFamily: font.fontFamily);
|
||||
TextStyle defaultTextStyleDelegate(LottieFontStyle font) {
|
||||
var style = font.style.toLowerCase();
|
||||
|
||||
var fontStyle = style.contains('italic') ? FontStyle.italic : null;
|
||||
|
||||
FontWeight? fontWeight;
|
||||
if (style.contains('semibold') || style.contains('semi bold')) {
|
||||
fontWeight = FontWeight.w600;
|
||||
} else if (style.contains('bold')) {
|
||||
fontWeight = FontWeight.bold;
|
||||
}
|
||||
return TextStyle(
|
||||
fontFamily: font.fontFamily,
|
||||
fontStyle: fontStyle,
|
||||
fontWeight: fontWeight);
|
||||
}
|
||||
|
||||
@immutable
|
||||
class LottieDelegates {
|
||||
|
@ -1,11 +1,57 @@
|
||||
import '../../animation/keyframe/gradient_color_keyframe_animation.dart';
|
||||
import '../../value/keyframe.dart';
|
||||
import '../content/gradient_color.dart';
|
||||
import 'base_animatable_value.dart';
|
||||
|
||||
class AnimatableGradientColorValue
|
||||
extends BaseAnimatableValue<GradientColor, GradientColor> {
|
||||
AnimatableGradientColorValue.fromKeyframes(super.keyframes)
|
||||
: super.fromKeyframes();
|
||||
AnimatableGradientColorValue.fromKeyframes(
|
||||
List<Keyframe<GradientColor>> keyframes)
|
||||
: super.fromKeyframes(_ensureInterpolatableKeyframes(keyframes));
|
||||
|
||||
static List<Keyframe<GradientColor>> _ensureInterpolatableKeyframes(
|
||||
List<Keyframe<GradientColor>> keyframes) {
|
||||
for (var i = 0; i < keyframes.length; i++) {
|
||||
keyframes[i] = _ensureInterpolatableKeyframe(keyframes[i]);
|
||||
}
|
||||
return keyframes;
|
||||
}
|
||||
|
||||
static Keyframe<GradientColor> _ensureInterpolatableKeyframe(
|
||||
Keyframe<GradientColor> keyframe) {
|
||||
var startValue = keyframe.startValue;
|
||||
var endValue = keyframe.endValue;
|
||||
if (startValue == null ||
|
||||
endValue == null ||
|
||||
startValue.positions.length == endValue.positions.length) {
|
||||
return keyframe;
|
||||
}
|
||||
var mergedPositions =
|
||||
_mergePositions(startValue.positions, endValue.positions);
|
||||
// The start/end has opacity stops which required adding extra positions in between the existing colors.
|
||||
return keyframe.copyWith(startValue.copyWithPositions(mergedPositions),
|
||||
endValue.copyWithPositions(mergedPositions));
|
||||
}
|
||||
|
||||
static List<double> _mergePositions(
|
||||
List<double> startPositions, List<double> endPositions) {
|
||||
var mergedArray =
|
||||
List<double>.filled(startPositions.length + endPositions.length, 0);
|
||||
mergedArray.setRange(0, startPositions.length, startPositions);
|
||||
mergedArray.setRange(startPositions.length,
|
||||
startPositions.length + endPositions.length, endPositions);
|
||||
mergedArray.sort();
|
||||
var uniqueValues = 0;
|
||||
var lastValue = double.nan;
|
||||
for (var i = 0; i < mergedArray.length; i++) {
|
||||
if (mergedArray[i] != lastValue) {
|
||||
mergedArray[uniqueValues] = mergedArray[i];
|
||||
uniqueValues++;
|
||||
lastValue = mergedArray[i];
|
||||
}
|
||||
}
|
||||
return mergedArray.take(uniqueValues).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
GradientColorKeyframeAnimation createAnimation() {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:ui';
|
||||
import '../../utils/collection.dart';
|
||||
import '../../utils/gamma_evaluator.dart';
|
||||
|
||||
class GradientColor {
|
||||
@ -21,4 +22,33 @@ class GradientColor {
|
||||
GammaEvaluator.evaluate(progress, gc1.colors[i], gc2.colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
GradientColor copyWithPositions(List<double> positions) {
|
||||
var colors = List<Color>.filled(positions.length, const Color(0x00000000));
|
||||
for (var i = 0; i < positions.length; i++) {
|
||||
colors[i] = _getColorForPosition(positions[i]);
|
||||
}
|
||||
return GradientColor(positions, colors);
|
||||
}
|
||||
|
||||
Color _getColorForPosition(double position) {
|
||||
var existingIndex = binarySearch(positions, position);
|
||||
if (existingIndex >= 0) {
|
||||
return colors[existingIndex];
|
||||
}
|
||||
// binarySearch returns -insertionPoint - 1 if it is not found.
|
||||
var insertionPoint = -(existingIndex + 1);
|
||||
if (insertionPoint == 0) {
|
||||
return colors[0];
|
||||
} else if (insertionPoint == colors.length - 1) {
|
||||
return colors[colors.length - 1];
|
||||
}
|
||||
var startPosition = positions[insertionPoint - 1];
|
||||
var endPosition = positions[insertionPoint];
|
||||
var startColor = colors[insertionPoint - 1];
|
||||
var endColor = colors[insertionPoint];
|
||||
|
||||
var fraction = (position - startPosition) / (endPosition - startPosition);
|
||||
return GammaEvaluator.evaluate(fraction, startColor, endColor);
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ ui.StrokeCap lineCapTypeToPaintCap(LineCapType? cap) {
|
||||
return ui.StrokeCap.round;
|
||||
case LineCapType.unknown:
|
||||
case null:
|
||||
return ui.StrokeCap.square;
|
||||
return ui.StrokeCap.butt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,27 @@
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
enum Justification { leftAlign, rightAlign, center }
|
||||
|
||||
@immutable
|
||||
class DocumentData {
|
||||
final String text;
|
||||
final String? fontName;
|
||||
final double size;
|
||||
final Justification justification;
|
||||
final int tracking;
|
||||
|
||||
/// Extra space in between lines. */
|
||||
final double lineHeight;
|
||||
final double baselineShift;
|
||||
final Color color;
|
||||
final Color strokeColor;
|
||||
final double strokeWidth;
|
||||
final bool strokeOverFill;
|
||||
final Offset? boxPosition;
|
||||
final Offset? boxSize;
|
||||
|
||||
DocumentData({
|
||||
const DocumentData({
|
||||
required this.text,
|
||||
this.fontName,
|
||||
required this.size,
|
||||
@ -27,22 +33,27 @@ class DocumentData {
|
||||
required this.strokeColor,
|
||||
required this.strokeWidth,
|
||||
required this.strokeOverFill,
|
||||
required this.boxPosition,
|
||||
required this.boxSize,
|
||||
});
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(
|
||||
text,
|
||||
fontName,
|
||||
size,
|
||||
justification.index,
|
||||
tracking,
|
||||
lineHeight,
|
||||
baselineShift,
|
||||
color,
|
||||
strokeColor,
|
||||
strokeWidth,
|
||||
strokeOverFill);
|
||||
text,
|
||||
fontName,
|
||||
size,
|
||||
justification.index,
|
||||
tracking,
|
||||
lineHeight,
|
||||
baselineShift,
|
||||
color,
|
||||
strokeColor,
|
||||
strokeWidth,
|
||||
strokeOverFill,
|
||||
boxPosition,
|
||||
boxSize,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -60,5 +71,7 @@ class DocumentData {
|
||||
color == other.color &&
|
||||
strokeColor == other.strokeColor &&
|
||||
strokeWidth == other.strokeWidth &&
|
||||
strokeOverFill == other.strokeOverFill;
|
||||
strokeOverFill == other.strokeOverFill &&
|
||||
boxPosition == other.boxPosition &&
|
||||
boxSize == other.boxSize;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'content/shape_group.dart';
|
||||
|
||||
@immutable
|
||||
class FontCharacter {
|
||||
static int hashFor(String character, String fontFamily, String style) {
|
||||
var result = 0;
|
||||
result = 31 * result + character.hashCode;
|
||||
var result = character.hashCode;
|
||||
result = 31 * result + fontFamily.hashCode;
|
||||
result = 31 * result + style.hashCode;
|
||||
return result;
|
||||
@ -16,7 +17,7 @@ class FontCharacter {
|
||||
final String style;
|
||||
final String fontFamily;
|
||||
|
||||
FontCharacter(
|
||||
const FontCharacter(
|
||||
{required this.shapes,
|
||||
required this.character,
|
||||
required this.size,
|
||||
|
@ -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');
|
||||
|
@ -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:
|
||||
|
@ -14,6 +14,7 @@ class SolidLayer extends BaseLayer {
|
||||
final Paint paint = Paint()..style = PaintingStyle.fill;
|
||||
final Path path = PathFactory.create();
|
||||
BaseKeyframeAnimation<ColorFilter, ColorFilter?>? _colorFilterAnimation;
|
||||
BaseKeyframeAnimation<Color, Color?>? _colorAnimation;
|
||||
|
||||
SolidLayer(LottieDrawable lottieDrawable, Layer layerModel)
|
||||
: super(lottieDrawable, layerModel) {
|
||||
@ -35,6 +36,9 @@ class SolidLayer extends BaseLayer {
|
||||
255.0)
|
||||
.round();
|
||||
paint.setAlpha(alpha);
|
||||
if (_colorAnimation?.value case var color?) {
|
||||
paint.color = color;
|
||||
}
|
||||
if (_colorFilterAnimation != null) {
|
||||
paint.colorFilter = _colorFilterAnimation!.value;
|
||||
}
|
||||
@ -76,6 +80,14 @@ class SolidLayer extends BaseLayer {
|
||||
_colorFilterAnimation = ValueCallbackKeyframeAnimation(
|
||||
callback as LottieValueCallback<ColorFilter>, null);
|
||||
}
|
||||
} else if (property == LottieProperty.color) {
|
||||
if (callback == null) {
|
||||
_colorAnimation = null;
|
||||
paint.color = layerModel.solidColor;
|
||||
} else {
|
||||
_colorAnimation = ValueCallbackKeyframeAnimation(
|
||||
callback as LottieValueCallback<Color>, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import '../../composition.dart';
|
||||
import '../../lottie_drawable.dart';
|
||||
import '../../lottie_property.dart';
|
||||
import '../../utils.dart';
|
||||
import '../../utils/characters.dart';
|
||||
import '../../value/lottie_value_callback.dart';
|
||||
import '../document_data.dart';
|
||||
import '../font.dart';
|
||||
@ -21,6 +22,9 @@ class TextLayer extends BaseLayer {
|
||||
final _fillPaint = Paint()..style = PaintingStyle.fill;
|
||||
final _strokePaint = Paint()..style = PaintingStyle.stroke;
|
||||
final _contentsForCharacter = <FontCharacter, List<ContentGroup>>{};
|
||||
|
||||
/// If this is paragraph text, one line may wrap depending on the size of the document data box.
|
||||
final _textSubLines = <_TextSubLine>[];
|
||||
final TextKeyframeAnimation _textAnimation;
|
||||
final LottieComposition _composition;
|
||||
|
||||
@ -88,18 +92,26 @@ class TextLayer extends BaseLayer {
|
||||
@override
|
||||
void drawLayer(Canvas canvas, Size size, Matrix4 parentMatrix,
|
||||
{required int parentAlpha}) {
|
||||
canvas.save();
|
||||
if (!lottieDrawable.useTextGlyphs) {
|
||||
canvas.transform(parentMatrix.storage);
|
||||
}
|
||||
var documentData = _textAnimation.value;
|
||||
var font = _composition.fonts[documentData.fontName];
|
||||
if (font == null) {
|
||||
// Something is wrong.
|
||||
canvas.restore();
|
||||
return;
|
||||
}
|
||||
canvas.save();
|
||||
canvas.transform(parentMatrix.storage);
|
||||
|
||||
_configurePaint(documentData, parentAlpha);
|
||||
|
||||
if (lottieDrawable.useTextGlyphs) {
|
||||
_drawTextWithGlyphs(documentData, parentMatrix, font, canvas);
|
||||
} else {
|
||||
_drawTextWithFont(documentData, font, canvas);
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
void _configurePaint(DocumentData documentData, int parentAlpha) {
|
||||
Color fillPaintColor;
|
||||
if (_colorCallbackAnimation != null) {
|
||||
fillPaintColor = _colorCallbackAnimation!.value;
|
||||
@ -121,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);
|
||||
|
||||
@ -130,20 +142,11 @@ class TextLayer extends BaseLayer {
|
||||
} else if (_strokeWidthAnimation != null) {
|
||||
_strokePaint.strokeWidth = _strokeWidthAnimation!.value;
|
||||
} else {
|
||||
var parentScale = parentMatrix.getScale();
|
||||
_strokePaint.strokeWidth = documentData.strokeWidth * parentScale;
|
||||
_strokePaint.strokeWidth = documentData.strokeWidth;
|
||||
}
|
||||
|
||||
if (lottieDrawable.useTextGlyphs) {
|
||||
_drawTextGlyphs(documentData, parentMatrix, font, canvas);
|
||||
} else {
|
||||
_drawTextWithFont(documentData, font, parentMatrix, canvas);
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
void _drawTextGlyphs(DocumentData documentData, Matrix4 parentMatrix,
|
||||
void _drawTextWithGlyphs(DocumentData documentData, Matrix4 parentMatrix,
|
||||
Font font, Canvas canvas) {
|
||||
double textSize;
|
||||
if (_textSizeCallbackAnimation != null) {
|
||||
@ -157,73 +160,54 @@ class TextLayer extends BaseLayer {
|
||||
var parentScale = parentMatrix.getScale();
|
||||
|
||||
var text = documentData.text;
|
||||
canvas.transform(parentMatrix.storage);
|
||||
|
||||
// Line height
|
||||
var lineHeight = documentData.lineHeight;
|
||||
|
||||
// Split full text in multiple lines
|
||||
var textLines = _getTextLines(text);
|
||||
var textLineCount = textLines.length;
|
||||
for (var l = 0; l < textLineCount; l++) {
|
||||
var textLine = textLines[l];
|
||||
var textLineWidth =
|
||||
_getTextLineWidthForGlyphs(textLine, font, fontScale, parentScale);
|
||||
|
||||
canvas.save();
|
||||
|
||||
// Apply horizontal justification
|
||||
_applyJustification(documentData.justification, canvas, textLineWidth);
|
||||
|
||||
// Center text vertically
|
||||
var multilineTranslateY = (textLineCount - 1) * lineHeight / 2;
|
||||
var translateY = l * lineHeight - multilineTranslateY;
|
||||
canvas.translate(0, translateY);
|
||||
|
||||
// Draw each line
|
||||
_drawGlyphTextLine(textLine, documentData, Matrix4.identity(), font, canvas,
|
||||
parentScale, fontScale);
|
||||
|
||||
// Reset canvas
|
||||
canvas.restore();
|
||||
// Add tracking
|
||||
var tracking = documentData.tracking / 10;
|
||||
if (_trackingCallbackAnimation != null) {
|
||||
tracking += _trackingCallbackAnimation!.value;
|
||||
} else if (_trackingAnimation != null) {
|
||||
tracking += _trackingAnimation!.value;
|
||||
}
|
||||
var lineIndex = -1;
|
||||
for (var i = 0; i < textLineCount; i++) {
|
||||
var textLine = textLines[i];
|
||||
var boxWidth = documentData.boxSize?.dx ?? 0.0;
|
||||
var lines = _splitGlyphTextIntoLines(
|
||||
textLine, boxWidth, font, fontScale, tracking, null);
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
var line = lines[j];
|
||||
lineIndex++;
|
||||
|
||||
canvas.restore();
|
||||
canvas.save();
|
||||
|
||||
_offsetCanvas(canvas, documentData, lineIndex, line.width);
|
||||
_drawGlyphTextLine(line.text, documentData, font, canvas, parentScale,
|
||||
fontScale, tracking);
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _drawGlyphTextLine(
|
||||
String text,
|
||||
DocumentData documentData,
|
||||
Matrix4 parentMatrix,
|
||||
Font font,
|
||||
Canvas canvas,
|
||||
double parentScale,
|
||||
double fontScale) {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
var c = text[i];
|
||||
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, 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.
|
||||
continue;
|
||||
}
|
||||
_drawCharacterAsGlyph(
|
||||
character, parentMatrix, fontScale, documentData, canvas);
|
||||
var tx = character.width * fontScale * parentScale;
|
||||
// Add tracking
|
||||
var tracking = documentData.tracking / 10.0;
|
||||
if (_trackingCallbackAnimation != null) {
|
||||
tracking += _trackingCallbackAnimation!.value;
|
||||
} else if (_trackingAnimation != null) {
|
||||
tracking += _trackingAnimation!.value;
|
||||
}
|
||||
tx += tracking * parentScale;
|
||||
_drawCharacterAsGlyph(character, fontScale, documentData, canvas);
|
||||
var tx = character.width * fontScale + tracking;
|
||||
canvas.translate(tx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void _drawTextWithFont(DocumentData documentData, Font font,
|
||||
Matrix4 parentMatrix, Canvas canvas) {
|
||||
void _drawTextWithFont(DocumentData documentData, Font font, Canvas canvas) {
|
||||
var textStyle = lottieDrawable.getTextStyle(font.family, font.style);
|
||||
var text = documentData.text;
|
||||
var textDelegate = lottieDrawable.delegates?.text;
|
||||
@ -240,9 +224,6 @@ class TextLayer extends BaseLayer {
|
||||
}
|
||||
textStyle = textStyle.copyWith(fontSize: textSize);
|
||||
|
||||
// Line height
|
||||
var lineHeight = documentData.lineHeight;
|
||||
|
||||
// Calculate tracking
|
||||
var tracking = documentData.tracking / 10;
|
||||
if (_trackingCallbackAnimation != null) {
|
||||
@ -255,44 +236,59 @@ class TextLayer extends BaseLayer {
|
||||
// Split full text in multiple lines
|
||||
var textLines = _getTextLines(text);
|
||||
var textLineCount = textLines.length;
|
||||
for (var l = 0; l < textLineCount; l++) {
|
||||
var textLine = textLines[l];
|
||||
var textPainter = TextPainter(
|
||||
text: TextSpan(text: textLine, style: textStyle),
|
||||
textDirection: _textDirection);
|
||||
textPainter.layout();
|
||||
var textLineWidth = textPainter.width;
|
||||
// We have to manually add the tracking between characters as the strokePaint ignores it
|
||||
textLineWidth += (textLine.length - 1) * tracking;
|
||||
var lineIndex = -1;
|
||||
for (var i = 0; i < textLineCount; i++) {
|
||||
var textLine = textLines[i];
|
||||
var boxWidth = documentData.boxSize?.dx ?? 0.0;
|
||||
var lines = _splitGlyphTextIntoLines(
|
||||
textLine, boxWidth, font, 0.0, tracking, textStyle);
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
var line = lines[j];
|
||||
lineIndex++;
|
||||
|
||||
canvas.save();
|
||||
canvas.save();
|
||||
|
||||
// Apply horizontal justification
|
||||
_applyJustification(documentData.justification, canvas, textLineWidth);
|
||||
_offsetCanvas(canvas, documentData, lineIndex, line.width);
|
||||
_drawFontTextLine(line.text, textStyle, documentData, canvas, tracking);
|
||||
|
||||
// Center text vertically
|
||||
var multilineTranslateY = (textLineCount - 1) * lineHeight / 2;
|
||||
var translateY = l * lineHeight - multilineTranslateY;
|
||||
canvas.translate(0, translateY);
|
||||
|
||||
// Draw each line
|
||||
_drawFontTextLine(textLine, textStyle, documentData, canvas, tracking);
|
||||
|
||||
// Reset canvas
|
||||
canvas.restore();
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> _getTextLines(String text) {
|
||||
// Split full text by carriage return character
|
||||
var formattedText = text.replaceAll('\r\n', '\r').replaceAll('\n', '\r');
|
||||
var textLinesArray = formattedText.split('\r');
|
||||
return textLinesArray;
|
||||
void _offsetCanvas(Canvas canvas, DocumentData documentData, int lineIndex,
|
||||
double lineWidth) {
|
||||
var position = documentData.boxPosition;
|
||||
var size = documentData.boxSize;
|
||||
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);
|
||||
case Justification.rightAlign:
|
||||
canvas.translate(lineStart + boxWidth - lineWidth, lineOffset);
|
||||
case Justification.center:
|
||||
canvas.translate(
|
||||
lineStart + boxWidth / 2.0 - lineWidth / 2.0, lineOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void _drawFontTextLine(String text, TextStyle textStyle,
|
||||
List<Characters> _getTextLines(String text) {
|
||||
// Split full text by carriage return character
|
||||
var formattedText = text
|
||||
.replaceAll('\r\n', '\r')
|
||||
.replaceAll('\u0003', '\r')
|
||||
.replaceAll('\n', '\r');
|
||||
var textLinesArray = formattedText.split('\r');
|
||||
return textLinesArray.map((l) => l.characters).toList();
|
||||
}
|
||||
|
||||
void _drawFontTextLine(Characters text, TextStyle textStyle,
|
||||
DocumentData documentData, Canvas canvas, double tracking) {
|
||||
for (var char in text.characters) {
|
||||
for (var char in text) {
|
||||
var charString = char;
|
||||
_drawCharacterFromFont(charString, textStyle, documentData, canvas);
|
||||
var textPainter = TextPainter(
|
||||
@ -305,43 +301,109 @@ class TextLayer extends BaseLayer {
|
||||
}
|
||||
}
|
||||
|
||||
double _getTextLineWidthForGlyphs(
|
||||
String textLine, Font font, double fontScale, double parentScale) {
|
||||
var textLineWidth = 0.0;
|
||||
for (var i = 0; i < textLine.length; i++) {
|
||||
var c = textLine[i];
|
||||
var characterHash = FontCharacter.hashFor(c, font.family, font.style);
|
||||
var character = _composition.characters[characterHash];
|
||||
if (character == null) {
|
||||
continue;
|
||||
List<_TextSubLine> _splitGlyphTextIntoLines(
|
||||
Characters textLine,
|
||||
double boxWidth,
|
||||
Font font,
|
||||
double fontScale,
|
||||
double tracking,
|
||||
TextStyle? textStyle) {
|
||||
var usingGlyphs = textStyle == null;
|
||||
var lineCount = 0;
|
||||
|
||||
var currentLineWidth = 0.0;
|
||||
var currentLineStartIndex = 0;
|
||||
|
||||
var currentWordStartIndex = 0;
|
||||
var currentWordWidth = 0.0;
|
||||
var nextCharacterStartsWord = false;
|
||||
|
||||
// The measured size of a space.
|
||||
var spaceWidth = 0.0;
|
||||
|
||||
var textPainter = TextPainter(
|
||||
text: TextSpan(text: '', style: textStyle),
|
||||
textDirection: _textDirection);
|
||||
var i = 0;
|
||||
for (var c in textLine) {
|
||||
double currentCharWidth;
|
||||
if (usingGlyphs) {
|
||||
var characterHash = FontCharacter.hashFor(c, font.family, font.style);
|
||||
var character = _composition.characters[characterHash];
|
||||
if (character == null) {
|
||||
continue;
|
||||
}
|
||||
currentCharWidth = character.width * fontScale + tracking;
|
||||
} else {
|
||||
textPainter.text = TextSpan(text: c, style: textStyle);
|
||||
textPainter.layout();
|
||||
currentCharWidth = textPainter.width + tracking;
|
||||
}
|
||||
textLineWidth += character.width * fontScale * parentScale;
|
||||
|
||||
if (c == ' ') {
|
||||
spaceWidth = currentCharWidth;
|
||||
nextCharacterStartsWord = true;
|
||||
} else if (nextCharacterStartsWord) {
|
||||
nextCharacterStartsWord = false;
|
||||
currentWordStartIndex = i;
|
||||
currentWordWidth = currentCharWidth;
|
||||
} else {
|
||||
currentWordWidth += currentCharWidth;
|
||||
}
|
||||
currentLineWidth += currentCharWidth;
|
||||
|
||||
if (boxWidth > 0 && currentLineWidth >= boxWidth) {
|
||||
if (c == ' ') {
|
||||
// Spaces at the end of a line don't do anything. Ignore it.
|
||||
// The next non-space character will hit the conditions below.
|
||||
continue;
|
||||
}
|
||||
var subLine = _ensureEnoughSubLines(++lineCount);
|
||||
if (currentWordStartIndex == currentLineStartIndex) {
|
||||
// Only word on line is wider than box, start wrapping mid-word.
|
||||
var substr = textLine.getRange(currentLineStartIndex, i);
|
||||
var trimmed = substr.trim(' '.characters);
|
||||
var trimmedSpace = (trimmed.length - substr.length) * spaceWidth;
|
||||
subLine.set(
|
||||
trimmed, currentLineWidth - currentCharWidth - trimmedSpace);
|
||||
currentLineStartIndex = i;
|
||||
currentLineWidth = currentCharWidth;
|
||||
currentWordStartIndex = currentLineStartIndex;
|
||||
currentWordWidth = currentCharWidth;
|
||||
} else {
|
||||
var substr = textLine.getRange(
|
||||
currentLineStartIndex, currentWordStartIndex - 1);
|
||||
var trimmed = substr.trim(' '.characters);
|
||||
var trimmedSpace = (substr.length - trimmed.length) * spaceWidth;
|
||||
subLine.set(trimmed,
|
||||
currentLineWidth - currentWordWidth - trimmedSpace - spaceWidth);
|
||||
currentLineStartIndex = currentWordStartIndex;
|
||||
currentLineWidth = currentWordWidth;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return textLineWidth;
|
||||
if (currentLineWidth > 0) {
|
||||
var line = _ensureEnoughSubLines(++lineCount);
|
||||
line.set(textLine.getRange(currentLineStartIndex), currentLineWidth);
|
||||
}
|
||||
return _textSubLines.sublist(0, lineCount);
|
||||
}
|
||||
|
||||
void _applyJustification(
|
||||
Justification justification, Canvas canvas, double textLineWidth) {
|
||||
switch (justification) {
|
||||
case Justification.leftAlign:
|
||||
// Do nothing. Default is left aligned.
|
||||
break;
|
||||
case Justification.rightAlign:
|
||||
canvas.translate(-textLineWidth, 0);
|
||||
break;
|
||||
case Justification.center:
|
||||
canvas.translate(-textLineWidth / 2, 0);
|
||||
break;
|
||||
/// Elements are reused and not deleted to save allocations.
|
||||
_TextSubLine _ensureEnoughSubLines(int numLines) {
|
||||
for (var i = _textSubLines.length; i < numLines; i++) {
|
||||
_textSubLines.add(_TextSubLine());
|
||||
}
|
||||
return _textSubLines[numLines - 1];
|
||||
}
|
||||
|
||||
void _drawCharacterAsGlyph(FontCharacter character, Matrix4 parentMatrix,
|
||||
double fontScale, DocumentData documentData, Canvas canvas) {
|
||||
void _drawCharacterAsGlyph(FontCharacter character, double fontScale,
|
||||
DocumentData documentData, Canvas canvas) {
|
||||
var contentGroups = _getContentsForCharacter(character);
|
||||
for (var j = 0; j < contentGroups.length; j++) {
|
||||
var path = contentGroups[j].getPath();
|
||||
path.getBounds();
|
||||
_matrix.set(parentMatrix);
|
||||
_matrix.reset();
|
||||
_matrix.translate(0.0, -documentData.baselineShift);
|
||||
_matrix.scale(fontScale, fontScale);
|
||||
path = path.transform(_matrix.storage);
|
||||
@ -385,11 +447,8 @@ class TextLayer extends BaseLayer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (paint.style == PaintingStyle.fill) {
|
||||
textStyle = textStyle.copyWith(foreground: paint);
|
||||
} else if (paint.style == PaintingStyle.stroke) {
|
||||
textStyle = textStyle.copyWith(background: paint);
|
||||
}
|
||||
textStyle = textStyle.copyWith(foreground: paint);
|
||||
|
||||
var painter = TextPainter(
|
||||
text: TextSpan(text: character, style: textStyle),
|
||||
textDirection: _textDirection,
|
||||
@ -489,3 +548,13 @@ class TextLayer extends BaseLayer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _TextSubLine {
|
||||
Characters text = Characters.empty;
|
||||
double width = 0.0;
|
||||
|
||||
void set(Characters text, double width) {
|
||||
this.text = text;
|
||||
this.width = width;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -73,9 +73,7 @@ class AnimatableValueParser {
|
||||
}
|
||||
|
||||
static List<Keyframe<T>> parse<T>(JsonReader reader,
|
||||
LottieComposition composition, ValueParser<T> valueParser,
|
||||
{double? scale}) {
|
||||
scale ??= 1.0;
|
||||
LottieComposition composition, ValueParser<T> valueParser) {
|
||||
return KeyframesParser.parse(reader, composition, valueParser);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ final JsonReaderOptions _names = JsonReaderOptions.of([
|
||||
'sc', // 8
|
||||
'sw', // 9
|
||||
'of', // 10
|
||||
'ps', // 11
|
||||
'sz', // 12
|
||||
]);
|
||||
|
||||
DocumentData documentDataParser(JsonReader reader) {
|
||||
@ -29,19 +31,18 @@ DocumentData documentDataParser(JsonReader reader) {
|
||||
var strokeColor = const Color(0x00000000);
|
||||
var strokeWidth = 0.0;
|
||||
var strokeOverFill = true;
|
||||
Offset? boxPosition;
|
||||
Offset? boxSize;
|
||||
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
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 ||
|
||||
@ -50,28 +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();
|
||||
case 12:
|
||||
reader.beginArray();
|
||||
boxSize = Offset(reader.nextDouble(), reader.nextDouble());
|
||||
reader.endArray();
|
||||
default:
|
||||
reader.skipName();
|
||||
reader.skipValue();
|
||||
@ -80,15 +81,18 @@ DocumentData documentDataParser(JsonReader reader) {
|
||||
reader.endObject();
|
||||
|
||||
return DocumentData(
|
||||
text: text ?? '',
|
||||
fontName: fontName,
|
||||
size: size,
|
||||
justification: justification,
|
||||
tracking: tracking,
|
||||
lineHeight: lineHeight,
|
||||
baselineShift: baselineShift,
|
||||
color: fillColor,
|
||||
strokeColor: strokeColor,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeOverFill: strokeOverFill);
|
||||
text: text ?? '',
|
||||
fontName: fontName,
|
||||
size: size,
|
||||
justification: justification,
|
||||
tracking: tracking,
|
||||
lineHeight: lineHeight,
|
||||
baselineShift: baselineShift,
|
||||
color: fillColor,
|
||||
strokeColor: strokeColor,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeOverFill: strokeOverFill,
|
||||
boxPosition: boxPosition,
|
||||
boxSize: boxSize,
|
||||
);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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()) {
|
||||
@ -44,18 +39,18 @@ 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();
|
||||
break;
|
||||
default:
|
||||
reader.skipName();
|
||||
reader.skipValue();
|
||||
}
|
||||
}
|
||||
reader.endObject();
|
||||
break;
|
||||
default:
|
||||
reader.skipName();
|
||||
reader.skipValue();
|
||||
|
@ -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();
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'dart:ui';
|
||||
import '../model/content/gradient_color.dart';
|
||||
import '../utils/collection.dart';
|
||||
import '../utils/gamma_evaluator.dart';
|
||||
import 'moshi/json_reader.dart';
|
||||
|
||||
class GradientColorParser {
|
||||
@ -67,22 +69,18 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
var gradientColor = GradientColor(positions, colors);
|
||||
_addOpacityStopsToGradientIfNeeded(gradientColor, array);
|
||||
gradientColor = _addOpacityStopsToGradientIfNeeded(gradientColor, array);
|
||||
return gradientColor;
|
||||
}
|
||||
|
||||
@ -93,50 +91,162 @@ class GradientColorParser {
|
||||
/// <p>
|
||||
/// This should be a good approximation is nearly all cases. However, if there are many more
|
||||
/// opacity stops than color stops, information will be lost.
|
||||
void _addOpacityStopsToGradientIfNeeded(
|
||||
GradientColor _addOpacityStopsToGradientIfNeeded(
|
||||
GradientColor gradientColor, List<double> array) {
|
||||
var startIndex = _colorPoints * 4;
|
||||
if (array.length <= startIndex) {
|
||||
return;
|
||||
return gradientColor;
|
||||
}
|
||||
|
||||
// When there are opacity stops, we create a merged list of color stops and opacity stops.
|
||||
// For a given color stop, we linearly interpolate the opacity for the two opacity stops around it.
|
||||
// For a given opacity stop, we linearly interpolate the color for the two color stops around it.
|
||||
var colorStopPositions = gradientColor.positions;
|
||||
var colorStopColors = gradientColor.colors;
|
||||
|
||||
var opacityStops = (array.length - startIndex) ~/ 2;
|
||||
var positions = List<double>.filled(opacityStops, 0.0);
|
||||
var opacities = List<double>.filled(opacityStops, 0.0);
|
||||
var opacityStopPositions = List<double>.filled(opacityStops, 0.0);
|
||||
var opacityStopOpacities = List<double>.filled(opacityStops, 0.0);
|
||||
|
||||
for (var i = startIndex, j = 0; i < array.length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
positions[j] = array[i];
|
||||
opacityStopPositions[j] = array[i];
|
||||
} else {
|
||||
opacities[j] = array[i];
|
||||
opacityStopOpacities[j] = array[i];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < gradientColor.size; i++) {
|
||||
var color = gradientColor.colors[i];
|
||||
color = color.withAlpha(_getOpacityAtPosition(
|
||||
gradientColor.positions[i], positions, opacities));
|
||||
gradientColor.colors[i] = color;
|
||||
}
|
||||
}
|
||||
// Pre-SKIA (Oreo) devices render artifacts when there is two stops in the same position.
|
||||
// As a result, we have to de-dupe the merge color and opacity stop positions.
|
||||
var newPositions =
|
||||
mergeUniqueElements(gradientColor.positions, opacityStopPositions);
|
||||
var newColorPoints = newPositions.length;
|
||||
var newColors = List<Color>.filled(newColorPoints, const Color(0xff000000));
|
||||
|
||||
int _getOpacityAtPosition(
|
||||
double position, List<double> positions, List<double> opacities) {
|
||||
for (var i = 1; i < positions.length; i++) {
|
||||
var lastPosition = positions[i - 1];
|
||||
var thisPosition = positions[i];
|
||||
if (positions[i] >= position) {
|
||||
var progress =
|
||||
(position - lastPosition) / (thisPosition - lastPosition);
|
||||
progress = progress.clamp(0, 1);
|
||||
if (progress.isNaN) {
|
||||
progress = 0.0;
|
||||
for (var i = 0; i < newColorPoints; i++) {
|
||||
var position = newPositions[i];
|
||||
var colorStopIndex = binarySearch(colorStopPositions, position);
|
||||
var opacityIndex = binarySearch(opacityStopPositions, position);
|
||||
if (colorStopIndex < 0 || opacityIndex > 0) {
|
||||
// This is a stop derived from an opacity stop.
|
||||
if (opacityIndex < 0) {
|
||||
// The formula here is derived from the return value for binarySearch. When an item isn't found, it returns -insertionPoint - 1.
|
||||
opacityIndex = -(opacityIndex + 1);
|
||||
}
|
||||
return (255 * lerpDouble(opacities[i - 1], opacities[i], progress)!)
|
||||
.round();
|
||||
newColors[i] = _getColorInBetweenColorStops(
|
||||
position,
|
||||
opacityStopOpacities[opacityIndex],
|
||||
colorStopPositions,
|
||||
colorStopColors);
|
||||
} else {
|
||||
// This os a step derived from a color stop.
|
||||
newColors[i] = _getColorInBetweenOpacityStops(
|
||||
position,
|
||||
colorStopColors[colorStopIndex],
|
||||
opacityStopPositions,
|
||||
opacityStopOpacities);
|
||||
}
|
||||
}
|
||||
return (255 * opacities[opacities.length - 1]).round();
|
||||
return GradientColor(newPositions, newColors);
|
||||
}
|
||||
|
||||
Color _getColorInBetweenColorStops(double position, double opacity,
|
||||
List<double> colorStopPositions, List<Color> colorStopColors) {
|
||||
if (colorStopColors.length < 2 || position == colorStopPositions[0]) {
|
||||
return colorStopColors[0];
|
||||
}
|
||||
for (var i = 1; i < colorStopPositions.length; i++) {
|
||||
var colorStopPosition = colorStopPositions[i];
|
||||
if (colorStopPosition < position && i != colorStopPositions.length - 1) {
|
||||
continue;
|
||||
}
|
||||
if (i == colorStopPositions.length - 1 && position >= colorStopPosition) {
|
||||
return colorStopColors[i].withOpacity(opacity);
|
||||
}
|
||||
// We found the position in which position is between i - 1 and i.
|
||||
var distanceBetweenColors =
|
||||
colorStopPositions[i] - colorStopPositions[i - 1];
|
||||
var distanceToLowerColor = position - colorStopPositions[i - 1];
|
||||
var percentage = distanceToLowerColor / distanceBetweenColors;
|
||||
var upperColor = colorStopColors[i];
|
||||
var lowerColor = colorStopColors[i - 1];
|
||||
return GammaEvaluator.evaluate(
|
||||
percentage, upperColor.withOpacity(1), lowerColor.withOpacity(1))
|
||||
.withOpacity(opacity);
|
||||
}
|
||||
throw Exception('Unreachable code.');
|
||||
}
|
||||
|
||||
Color _getColorInBetweenOpacityStops(double position, Color color,
|
||||
List<double> opacityStopPositions, List<double> opacityStopOpacities) {
|
||||
if (opacityStopOpacities.length < 2 ||
|
||||
position <= opacityStopPositions[0]) {
|
||||
return color.withOpacity(opacityStopOpacities[0]);
|
||||
}
|
||||
for (var i = 1; i < opacityStopPositions.length; i++) {
|
||||
var opacityStopPosition = opacityStopPositions[i];
|
||||
if (opacityStopPosition < position &&
|
||||
i != opacityStopPositions.length - 1) {
|
||||
continue;
|
||||
}
|
||||
final double opacity;
|
||||
if (opacityStopPosition <= position) {
|
||||
opacity = opacityStopOpacities[i];
|
||||
} else {
|
||||
// We found the position in which position in between i - 1 and i.
|
||||
var distanceBetweenOpacities =
|
||||
opacityStopPositions[i] - opacityStopPositions[i - 1];
|
||||
var distanceToLowerOpacity = position - opacityStopPositions[i - 1];
|
||||
var percentage = distanceToLowerOpacity / distanceBetweenOpacities;
|
||||
opacity = lerpDouble(
|
||||
opacityStopOpacities[i - 1], opacityStopOpacities[i], percentage)!;
|
||||
}
|
||||
return color.withOpacity(opacity);
|
||||
}
|
||||
throw Exception('Unreachable code.');
|
||||
}
|
||||
|
||||
/// Takes two sorted float arrays and merges their elements while removing duplicates.
|
||||
static List<double> mergeUniqueElements(
|
||||
List<double> arrayA, List<double> arrayB) {
|
||||
if (arrayA.isEmpty) {
|
||||
return arrayB;
|
||||
} else if (arrayB.isEmpty) {
|
||||
return arrayA;
|
||||
}
|
||||
|
||||
var aIndex = 0;
|
||||
var bIndex = 0;
|
||||
var numDuplicates = 0;
|
||||
// This will be the merged list but may be longer than what is needed if there are duplicates.
|
||||
// If there are, the 0 elements at the end need to be truncated.
|
||||
var mergedNotTruncated =
|
||||
List<double>.filled(arrayA.length + arrayB.length, 0);
|
||||
for (var i = 0; i < mergedNotTruncated.length; i++) {
|
||||
final a = aIndex < arrayA.length ? arrayA[aIndex] : double.nan;
|
||||
final b = bIndex < arrayB.length ? arrayB[bIndex] : double.nan;
|
||||
|
||||
if (b.isNaN || a < b) {
|
||||
mergedNotTruncated[i] = a;
|
||||
aIndex++;
|
||||
} else if (a.isNaN || b < a) {
|
||||
mergedNotTruncated[i] = b;
|
||||
bIndex++;
|
||||
} else {
|
||||
mergedNotTruncated[i] = a;
|
||||
aIndex++;
|
||||
bIndex++;
|
||||
numDuplicates++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numDuplicates == 0) {
|
||||
return mergedNotTruncated;
|
||||
}
|
||||
|
||||
return mergedNotTruncated
|
||||
.take(mergedNotTruncated.length - numDuplicates)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ class KeyframesParser {
|
||||
keyframes.add(KeyframeParser.parse(reader, composition, valueParser,
|
||||
animated: false, multiDimensional: multiDimensional));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
reader.skipValue();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -1,11 +1,10 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
class Buffer {
|
||||
Buffer(this.buffer);
|
||||
|
||||
final Uint8List buffer;
|
||||
final List<int> buffer;
|
||||
int _start = 0, _size = 0;
|
||||
int get size => _size;
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
import 'buffer.dart';
|
||||
import 'json_scope.dart';
|
||||
import 'json_utf8_reader.dart';
|
||||
@ -167,7 +166,7 @@ abstract class JsonReader {
|
||||
bool failOnUnknown = false;
|
||||
|
||||
/// Returns a new instance that reads UTF-8 encoded JSON from {@code source}.
|
||||
static JsonReader fromBytes(Uint8List source) {
|
||||
static JsonReader fromBytes(List<int> source) {
|
||||
return JsonUtf8Reader(Buffer(source));
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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 ':'");
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user