Compare commits

...

5 Commits

Author SHA1 Message Date
e9e0e4f5d3 Add examples for a splash screen 2021-11-11 19:47:23 +01:00
2979b62dc0 fix: Revert Cubic to PathInterpolator.cubic (#173) 2021-09-24 23:42:56 +02:00
340f0d2f27 Format changelog 2021-09-19 20:51:42 +02:00
34fef26eb2 Fix changelog 2021-09-19 20:50:56 +02:00
89c62122bf Add support for Blur & DropShadow (#170) 2021-09-19 20:48:01 +02:00
391 changed files with 1009 additions and 196 deletions

View File

@ -1,3 +1,43 @@
## [1.2.1]
- Fix: Revert Cubic to `PathInterpolator.cubic`
## [1.2.0]
- Add support for gaussian blurs.
Example to blur some elements dynamically:
```dart
Lottie.asset(
'assets/AndroidWave.json',
delegates: LottieDelegates(values: [
ValueDelegate.blurRadius(
['**'], // The path to the element to blur
value: 20,
),
]),
)
```
- Add support for drop shadows.
Example to add a shadow dynamically:
```dart
Lottie.asset(
'assets/animation.json',
delegates: LottieDelegates(values: [
ValueDelegate.dropShadow(
['**'], // The path to the elements with shadow
value: const DropShadow(
color: Colors.blue,
direction: 140,
distance: 60,
radius: 10,
),
),
]),
)
```
## [1.1.0]
- Add `errorBuilder` callback to provide an alternative widget in case an error occurs during loading.
```dart

View File

@ -6,7 +6,6 @@ analyzer:
linter:
rules:
avoid_print: false
unnecessary_overrides: false # remove when mockito is fixed
always_declare_return_types: true
avoid_dynamic_calls: true

View File

@ -0,0 +1 @@
{"v":"5.7.7","fr":29.9700012207031,"ip":0,"op":181.000007372281,"w":375,"h":375,"nm":"Square","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":[187.5,187.5,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,"ef":[{"ty":25,"nm":"Drop Shadow2","np":8,"mn":"ADBE Drop Shadow","ix":1,"en":1,"ef":[{"ty":2,"nm":"Shadow Color","mn":"ADBE Drop Shadow-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0,0,0,1]},{"t":151.000006150356,"s":[0,0.371857702732,1,1]}],"ix":1}},{"ty":0,"nm":"Opacity","mn":"ADBE Drop Shadow-0002","ix":2,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":0,"s":[127.5]},{"t":151.000006150356,"s":[127.5]}],"ix":2}},{"ty":0,"nm":"Direction","mn":"ADBE Drop Shadow-0003","ix":3,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":151.000006150356,"s":[360]}],"ix":3}},{"ty":0,"nm":"Distance","mn":"ADBE Drop Shadow-0004","ix":4,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[10]},{"t":151.000006150356,"s":[15]}],"ix":4}},{"ty":0,"nm":"Softness","mn":"ADBE Drop Shadow-0005","ix":5,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[20]},{"t":151.000006150356,"s":[50]}],"ix":5}},{"ty":7,"nm":"Shadow Only","mn":"ADBE Drop Shadow-0006","ix":6,"v":{"a":0,"k":0,"ix":6}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[217.641,217.641],"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":[-4.68,-1.68],"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":184.000007494474,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1 @@
{"v":"5.7.7","fr":29.9700012207031,"ip":0,"op":121.000004928431,"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":{"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,"ef":[{"ty":29,"nm":"Gaussian Blur2","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Blurriness","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24.00000097754,"s":[120.7]}],"ix":1}},{"ty":7,"nm":"Blur Dimensions","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Repeat Edge Pixels","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]},{"ty":5,"nm":"Bulge","np":9,"mn":"ADBE Bulge","ix":2,"en":1,"ef":[{"ty":0,"nm":"Horizontal Radius","mn":"ADBE Bulge-0001","ix":1,"v":{"a":0,"k":50,"ix":1}},{"ty":0,"nm":"Vertical Radius","mn":"ADBE Bulge-0002","ix":2,"v":{"a":0,"k":50,"ix":2}},{"ty":3,"nm":"Bulge Center","mn":"ADBE Bulge-0003","ix":3,"v":{"a":0,"k":[200,200],"ix":3}},{"ty":0,"nm":"Bulge Height","mn":"ADBE Bulge-0004","ix":4,"v":{"a":0,"k":1,"ix":4}},{"ty":0,"nm":"Taper Radius","mn":"ADBE Bulge-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Antialiasing (Best Qual Only)","mn":"ADBE Bulge-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":7,"nm":"Pinning","mn":"ADBE Bulge-0007","ix":7,"v":{"a":0,"k":0,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[274.975,274.975],"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":"tr","p":{"a":0,"k":[-4.513,7.487],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector 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}],"ip":0,"op":121.000004928431,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1 @@
{"v":"5.7.7","fr":29.9700012207031,"ip":0,"op":121.000004928431,"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":{"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,"ef":[{"ty":29,"nm":"Gaussian Blur2","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Blurriness","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24.00000097754,"s":[120.7]}],"ix":1}},{"ty":7,"nm":"Blur Dimensions","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Repeat Edge Pixels","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]},{"ty":5,"nm":"Bulge","np":9,"mn":"ADBE Bulge","ix":2,"en":1,"ef":[{"ty":0,"nm":"Horizontal Radius","mn":"ADBE Bulge-0001","ix":1,"v":{"a":0,"k":50,"ix":1}},{"ty":0,"nm":"Vertical Radius","mn":"ADBE Bulge-0002","ix":2,"v":{"a":0,"k":50,"ix":2}},{"ty":3,"nm":"Bulge Center","mn":"ADBE Bulge-0003","ix":3,"v":{"a":0,"k":[200,200],"ix":3}},{"ty":0,"nm":"Bulge Height","mn":"ADBE Bulge-0004","ix":4,"v":{"a":0,"k":1,"ix":4}},{"ty":0,"nm":"Taper Radius","mn":"ADBE Bulge-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Antialiasing (Best Qual Only)","mn":"ADBE Bulge-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":7,"nm":"Pinning","mn":"ADBE Bulge-0007","ix":7,"v":{"a":0,"k":0,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[274.975,274.975],"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":"tr","p":{"a":0,"k":[-4.513,7.487],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,0,0,0.5,0.505,0,0.5,1,0.009,0,1],"ix":9}},"s":{"a":0,"k":[-125,0],"ix":5},"e":{"a":0,"k":[100,0],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false}],"ip":0,"op":121.000004928431,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1 @@
{"v":"5.7.7","fr":29.9700012207031,"ip":0,"op":121.000004928431,"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":{"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,"ef":[{"ty":29,"nm":"Gaussian Blur2","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Blurriness","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24.00000097754,"s":[120.7]}],"ix":1}},{"ty":7,"nm":"Blur Dimensions","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Repeat Edge Pixels","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]},{"ty":5,"nm":"Bulge","np":9,"mn":"ADBE Bulge","ix":2,"en":1,"ef":[{"ty":0,"nm":"Horizontal Radius","mn":"ADBE Bulge-0001","ix":1,"v":{"a":0,"k":50,"ix":1}},{"ty":0,"nm":"Vertical Radius","mn":"ADBE Bulge-0002","ix":2,"v":{"a":0,"k":50,"ix":2}},{"ty":3,"nm":"Bulge Center","mn":"ADBE Bulge-0003","ix":3,"v":{"a":0,"k":[200,200],"ix":3}},{"ty":0,"nm":"Bulge Height","mn":"ADBE Bulge-0004","ix":4,"v":{"a":0,"k":1,"ix":4}},{"ty":0,"nm":"Taper Radius","mn":"ADBE Bulge-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Antialiasing (Best Qual Only)","mn":"ADBE Bulge-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":7,"nm":"Pinning","mn":"ADBE Bulge-0007","ix":7,"v":{"a":0,"k":0,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[274.975,274.975],"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":"tr","p":{"a":0,"k":[-4.513,7.487],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":41,"ix":10},"g":{"p":3,"k":{"a":0,"k":[0,0.01,0,1,0.5,0.496,0,0.5,1,0.982,0,0],"ix":8}},"s":{"a":0,"k":[-45,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":13},"bm":0,"nm":"Gradient Stroke 1","mn":"ADBE Vector Graphic - G-Stroke","hd":false}],"ip":0,"op":121.000004928431,"st":0,"bm":0}],"markers":[]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"v":"5.7.7","fr":29.9700012207031,"ip":0,"op":181.000007372281,"w":375,"h":375,"nm":"Square","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":[187.5,187.5,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,"ef":[{"ty":25,"nm":"Drop Shadow2","np":8,"mn":"ADBE Drop Shadow","ix":1,"en":1,"ef":[{"ty":2,"nm":"Shadow Color","mn":"ADBE Drop Shadow-0001","ix":1,"v":{"a":0,"k":[0,1,0.609851837158,1],"ix":1}},{"ty":0,"nm":"Opacity","mn":"ADBE Drop Shadow-0002","ix":2,"v":{"a":0,"k":127.5,"ix":2}},{"ty":0,"nm":"Direction","mn":"ADBE Drop Shadow-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Distance","mn":"ADBE Drop Shadow-0004","ix":4,"v":{"a":0,"k":10,"ix":4}},{"ty":0,"nm":"Softness","mn":"ADBE Drop Shadow-0005","ix":5,"v":{"a":0,"k":20,"ix":5}},{"ty":7,"nm":"Shadow Only","mn":"ADBE Drop Shadow-0006","ix":6,"v":{"a":0,"k":0,"ix":6}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[217.641,217.641],"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":[-4.68,-1.68],"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":184.000007494474,"st":0,"bm":0}],"markers":[]}

View File

@ -0,0 +1 @@
{"v":"5.7.7","fr":29.9700012207031,"ip":0,"op":121.000004928431,"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":{"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,"ef":[{"ty":29,"nm":"Gaussian Blur2","np":5,"mn":"ADBE Gaussian Blur 2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Blurriness","mn":"ADBE Gaussian Blur 2-0001","ix":1,"v":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":24.00000097754,"s":[120.7]}],"ix":1}},{"ty":7,"nm":"Blur Dimensions","mn":"ADBE Gaussian Blur 2-0002","ix":2,"v":{"a":0,"k":1,"ix":2}},{"ty":7,"nm":"Repeat Edge Pixels","mn":"ADBE Gaussian Blur 2-0003","ix":3,"v":{"a":0,"k":0,"ix":3}}]},{"ty":5,"nm":"Bulge","np":9,"mn":"ADBE Bulge","ix":2,"en":1,"ef":[{"ty":0,"nm":"Horizontal Radius","mn":"ADBE Bulge-0001","ix":1,"v":{"a":0,"k":50,"ix":1}},{"ty":0,"nm":"Vertical Radius","mn":"ADBE Bulge-0002","ix":2,"v":{"a":0,"k":50,"ix":2}},{"ty":3,"nm":"Bulge Center","mn":"ADBE Bulge-0003","ix":3,"v":{"a":0,"k":[200,200],"ix":3}},{"ty":0,"nm":"Bulge Height","mn":"ADBE Bulge-0004","ix":4,"v":{"a":0,"k":1,"ix":4}},{"ty":0,"nm":"Taper Radius","mn":"ADBE Bulge-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":7,"nm":"Antialiasing (Best Qual Only)","mn":"ADBE Bulge-0006","ix":6,"v":{"a":0,"k":1,"ix":6}},{"ty":7,"nm":"Pinning","mn":"ADBE Bulge-0007","ix":7,"v":{"a":0,"k":0,"ix":7}}]}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[274.975,274.975],"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":"tr","p":{"a":0,"k":[-4.513,7.487],"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":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":46,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":121.000004928431,"st":0,"bm":0}],"markers":[]}

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
<string>9.0</string>
</dict>
</plist>

View File

@ -10,78 +10,32 @@ project 'Runner', {
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) do |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
end
generated_key_values
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
# Flutter Pod
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
# Plugin Pods
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
flutter_additional_ios_build_settings(target)
end
end

View File

@ -2,27 +2,21 @@ PODS:
- Flutter (1.0.0)
- path_provider (0.0.1):
- Flutter
- path_provider_macos (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
path_provider_macos:
:path: ".symlinks/plugins/path_provider_macos/ios"
SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
COCOAPODS: 1.9.1
COCOAPODS: 1.11.2

View File

@ -264,12 +264,10 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../Flutter/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
);
runOnlyForDeploymentPostprocessing = 0;
@ -313,7 +311,6 @@
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -353,7 +350,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -391,7 +388,6 @@
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -437,7 +433,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -447,7 +443,6 @@
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -487,7 +482,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;

View File

@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView(
children: [
Lottie.asset(
'assets/AndroidWave.json',
height: 300,
delegates: LottieDelegates(values: [
ValueDelegate.blurRadius(
['**'],
value: 20,
),
]),
),
],
),
),
);
}
}

View File

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView(
children: [
Lottie.asset(
'assets/Tests/Fill.json',
height: 300,
delegates: LottieDelegates(values: [
ValueDelegate.dropShadow(
['**'],
value: const DropShadow(
color: Colors.blue,
direction: 140,
distance: 60,
radius: 10,
),
),
]),
),
],
),
),
);
}
}

View File

@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart';
// This example show how to use a Lottie animation as a SplashScreen for your application
// Since animation are loaded from the assets and can take a few milliseconds to
// load, we instruct flutter to defer the first frame until when the animation
// is actually ready to be displayed.
void main() async {
Logger.root
..level = Level.ALL
..onRecord.listen(print);
runApp(const SplashScreen());
}
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
@override
void initState() {
super.initState();
WidgetsBinding.instance!.deferFirstFrame();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.lightBlue,
home: Scaffold(
backgroundColor: Colors.lightBlue,
appBar: AppBar(
title: const Text('Splash screen'),
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: [
Lottie.asset('assets/AndroidWave.json',
onLoaded: (composition) {
WidgetsBinding.instance!.allowFirstFrame();
}),
],
),
),
),
),
);
}
}

View File

@ -0,0 +1,86 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
import 'package:lottie/lottie.dart';
void main() async {
Logger.root
..level = Level.ALL
..onRecord.listen(print);
runApp(const MaterialApp(
color: Colors.lightBlue,
home: App(),
));
}
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> with TickerProviderStateMixin {
late Future<Uint8List> _lottieAnimation;
@override
void initState() {
super.initState();
// Start loading the animation in background here
_lottieAnimation = _loadAnimation();
}
Future<Uint8List> _loadAnimation() async {
var asset = await rootBundle.load('assets/AndroidWave.json');
return asset.buffer.asUint8List();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlue,
appBar: AppBar(
title: const Text('Splash screen'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
var bytes = await _lottieAnimation;
await Navigator.push<void>(
context,
MaterialPageRoute(
builder: (context) => AnimationScreen(
animationBytes: bytes,
),
),
);
},
child: const Text('Open splash'),
),
),
);
}
}
class AnimationScreen extends StatelessWidget {
final Uint8List animationBytes;
const AnimationScreen({Key? key, required this.animationBytes})
: super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Animation'),
),
body: Center(
child: Lottie.memory(animationBytes),
),
);
}
}

View File

@ -7,14 +7,14 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.2"
version: "3.1.6"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0"
version: "2.8.1"
boolean_selector:
dependency: transitive
description:
@ -35,7 +35,7 @@ packages:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.1"
clock:
dependency: transitive
description:
@ -89,14 +89,14 @@ packages:
name: flutter_colorpicker
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0"
version: "0.6.1"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "1.0.4"
flutter_test:
dependency: "direct dev"
description: flutter
@ -108,14 +108,14 @@ packages:
name: golden_toolkit
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0"
version: "0.11.0"
http:
dependency: "direct main"
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.3"
version: "0.13.4"
http_parser:
dependency: transitive
description:
@ -136,14 +136,14 @@ packages:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.0.2"
lottie:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "1.1.0"
version: "1.2.1"
matcher:
dependency: transitive
description:
@ -157,7 +157,7 @@ packages:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.7.0"
path:
dependency: transitive
description:
@ -171,21 +171,21 @@ packages:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.0.6"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.1"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
path_provider_platform_interface:
dependency: transitive
description:
@ -199,35 +199,28 @@ packages:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
version: "2.0.4"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
version: "3.0.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.1"
version: "4.2.4"
sky_engine:
dependency: transitive
description: flutter
@ -274,7 +267,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
version: "0.4.2"
typed_data:
dependency: transitive
description:
@ -295,7 +288,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.5"
version: "2.2.10"
xdg_directories:
dependency: transitive
description:
@ -304,5 +297,5 @@ packages:
source: hosted
version: "0.2.0"
sdks:
dart: ">=2.13.0 <3.0.0"
flutter: ">=1.20.0"
dart: ">=2.14.0 <3.0.0"
flutter: ">=2.5.0"

View File

@ -14,4 +14,5 @@ export 'src/providers/lottie_provider.dart' show LottieProvider;
export 'src/providers/memory_provider.dart' show MemoryLottie;
export 'src/providers/network_provider.dart' show NetworkLottie;
export 'src/raw_lottie.dart' show RawLottie;
export 'src/value/drop_shadow.dart' show DropShadow;
export 'src/value_delegate.dart' show ValueDelegate;

View File

@ -7,6 +7,7 @@ import '../../lottie_drawable.dart';
import '../../lottie_property.dart';
import '../../model/animatable/animatable_double_value.dart';
import '../../model/animatable/animatable_integer_value.dart';
import '../../model/content/drop_shadow_effect.dart';
import '../../model/content/shape_trim_path.dart';
import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
@ -15,8 +16,10 @@ import '../../utils/dash_path.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../utils/utils.dart';
import '../../value/drop_shadow.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import '../keyframe/drop_shadow_keyframe_animation.dart';
import '../keyframe/value_callback_keyframe_animation.dart';
import 'content.dart';
import 'drawing_content.dart';
@ -39,6 +42,9 @@ abstract class BaseStrokeContent
final List<BaseKeyframeAnimation<Object, double>> _dashPatternAnimations;
final BaseKeyframeAnimation<Object, double>? _dashPatternOffsetAnimation;
BaseKeyframeAnimation<ColorFilter, ColorFilter?>? _colorFilterAnimation;
BaseKeyframeAnimation<double, double>? _blurAnimation;
double _blurMaskFilterRadius = 0;
DropShadowKeyframeAnimation? dropShadowAnimation;
BaseStrokeContent(this.lottieDrawable, this.layer,
{required StrokeCap cap,
@ -77,6 +83,17 @@ abstract class BaseStrokeContent
if (_dashPatternOffsetAnimation != null) {
_dashPatternOffsetAnimation!.addUpdateListener(onUpdateListener);
}
var blurEffect = layer.blurEffect;
if (blurEffect != null) {
_blurAnimation = blurEffect.blurriness.createAnimation()
..addUpdateListener(onUpdateListener);
layer.addAnimation(_blurAnimation);
}
var dropShadowEffect = layer.dropShadowEffect;
if (dropShadowEffect != null) {
dropShadowAnimation = DropShadowKeyframeAnimation(
onUpdateListener, layer, dropShadowEffect);
}
}
void onUpdateListener() {
@ -139,6 +156,18 @@ abstract class BaseStrokeContent
paint.colorFilter = _colorFilterAnimation!.value;
}
var blurAnimation = _blurAnimation;
if (blurAnimation != null) {
var blurRadius = blurAnimation.value;
if (blurRadius == 0) {
paint.maskFilter = null;
} else if (blurRadius != _blurMaskFilterRadius) {
var blur = layer.getBlurMaskFilter(blurRadius);
paint.maskFilter = blur;
}
_blurMaskFilterRadius = blurRadius;
}
for (var i = 0; i < _pathGroups.length; i++) {
var pathGroup = _pathGroups[i];
@ -153,6 +182,10 @@ abstract class BaseStrokeContent
}
L.endSection('StrokeContent#buildPath');
L.beginSection('StrokeContent#drawPath');
var dropShadow = dropShadowAnimation;
if (dropShadow != null) {
dropShadow.draw(canvas, _path);
}
canvas.drawPath(_withDashPattern(_path, parentMatrix), paint);
L.endSection('StrokeContent#drawPath');
}
@ -308,10 +341,31 @@ abstract class BaseStrokeContent
} else {
_colorFilterAnimation =
ValueCallbackKeyframeAnimation<ColorFilter, ColorFilter?>(
callback as LottieValueCallback<ColorFilter>, null);
_colorFilterAnimation!.addUpdateListener(onUpdateListener);
callback as LottieValueCallback<ColorFilter>, null)
..addUpdateListener(onUpdateListener);
layer.addAnimation(_colorFilterAnimation);
}
} else if (property == LottieProperty.blurRadius) {
var blurAnimation = _blurAnimation;
if (blurAnimation != null) {
blurAnimation
.setValueCallback(callback as LottieValueCallback<double>?);
} else {
_blurAnimation = blurAnimation = ValueCallbackKeyframeAnimation(
callback as LottieValueCallback<double>?, 0)
..addUpdateListener(onUpdateListener);
layer.addAnimation(blurAnimation);
}
} else if (property == LottieProperty.dropShadow) {
var dropShadowAnimation = this.dropShadowAnimation;
if (dropShadowAnimation == null) {
var effect = DropShadowEffect.createEmpty();
this.dropShadowAnimation = dropShadowAnimation = dropShadowAnimation =
DropShadowKeyframeAnimation(onUpdateListener, layer, effect);
}
dropShadowAnimation
.setCallback(callback as LottieValueCallback<DropShadow>?);
}
}
}

View File

@ -3,14 +3,17 @@ import 'package:vector_math/vector_math_64.dart';
import '../../l.dart';
import '../../lottie_drawable.dart';
import '../../lottie_property.dart';
import '../../model/content/drop_shadow_effect.dart';
import '../../model/content/shape_fill.dart';
import '../../model/key_path.dart';
import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/drop_shadow.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import '../keyframe/drop_shadow_keyframe_animation.dart';
import '../keyframe/value_callback_keyframe_animation.dart';
import 'content.dart';
import 'drawing_content.dart';
@ -29,10 +32,25 @@ class FillContent implements DrawingContent, KeyPathElementContent {
late final BaseKeyframeAnimation<int, int> _opacityAnimation;
BaseKeyframeAnimation<ColorFilter, ColorFilter?>? _colorFilterAnimation;
final LottieDrawable lottieDrawable;
BaseKeyframeAnimation<double, double>? _blurAnimation;
double _blurMaskFilterRadius = 0;
DropShadowKeyframeAnimation? dropShadowAnimation;
FillContent(this.lottieDrawable, this.layer, ShapeFill fill)
: name = fill.name,
_hidden = fill.hidden {
var blurEffect = layer.blurEffect;
if (blurEffect != null) {
_blurAnimation = blurEffect.blurriness.createAnimation()
..addUpdateListener(onValueChanged);
layer.addAnimation(_blurAnimation);
}
var dropShadowEffect = layer.dropShadowEffect;
if (dropShadowEffect != null) {
dropShadowAnimation =
DropShadowKeyframeAnimation(onValueChanged, layer, dropShadowEffect);
}
if (fill.color == null || fill.opacity == null) {
return;
}
@ -80,6 +98,18 @@ class FillContent implements DrawingContent, KeyPathElementContent {
_paint.colorFilter = _colorFilterAnimation!.value;
}
var blurAnimation = _blurAnimation;
if (blurAnimation != null) {
var blurRadius = blurAnimation.value;
if (blurRadius == 0) {
_paint.maskFilter = null;
} else if (blurRadius != _blurMaskFilterRadius) {
var blur = layer.getBlurMaskFilter(blurRadius);
_paint.maskFilter = blur;
}
_blurMaskFilterRadius = blurRadius;
}
_path.reset();
for (var i = 0; i < _paths.length; i++) {
_path.addPath(_paths[i].getPath(), Offset.zero);
@ -87,6 +117,10 @@ class FillContent implements DrawingContent, KeyPathElementContent {
canvas.save();
canvas.transform(parentMatrix.storage);
var dropShadow = dropShadowAnimation;
if (dropShadow != null) {
dropShadow.draw(canvas, _path);
}
canvas.drawPath(_path, _paint);
canvas.restore();
@ -132,6 +166,28 @@ class FillContent implements DrawingContent, KeyPathElementContent {
..addUpdateListener(onValueChanged);
layer.addAnimation(_colorFilterAnimation);
}
} else if (property == LottieProperty.blurRadius) {
var blurAnimation = _blurAnimation;
if (blurAnimation != null) {
blurAnimation
.setValueCallback(callback as LottieValueCallback<double>?);
} else {
var callbackBlur = callback as LottieValueCallback<double>?;
_blurAnimation = blurAnimation = ValueCallbackKeyframeAnimation(
callbackBlur, callbackBlur?.value ?? 0)
..addUpdateListener(onValueChanged);
layer.addAnimation(blurAnimation);
}
} else if (property == LottieProperty.dropShadow) {
var dropShadowAnimation = this.dropShadowAnimation;
if (dropShadowAnimation == null) {
var effect = DropShadowEffect.createEmpty();
this.dropShadowAnimation = dropShadowAnimation = dropShadowAnimation =
DropShadowKeyframeAnimation(onValueChanged, layer, effect);
}
dropShadowAnimation
.setCallback(callback as LottieValueCallback<DropShadow>?);
}
}
}

View File

@ -3,6 +3,7 @@ import 'package:vector_math/vector_math_64.dart';
import '../../l.dart';
import '../../lottie_drawable.dart';
import '../../lottie_property.dart';
import '../../model/content/drop_shadow_effect.dart';
import '../../model/content/gradient_color.dart';
import '../../model/content/gradient_fill.dart';
import '../../model/content/gradient_type.dart';
@ -11,8 +12,10 @@ import '../../model/layer/base_layer.dart';
import '../../utils.dart';
import '../../utils/misc.dart';
import '../../utils/path_factory.dart';
import '../../value/drop_shadow.dart';
import '../../value/lottie_value_callback.dart';
import '../keyframe/base_keyframe_animation.dart';
import '../keyframe/drop_shadow_keyframe_animation.dart';
import '../keyframe/value_callback_keyframe_animation.dart';
import 'content.dart';
import 'drawing_content.dart';
@ -38,6 +41,9 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
_colorCallbackAnimation;
final LottieDrawable lottieDrawable;
final int _cacheSteps;
BaseKeyframeAnimation<double, double>? _blurAnimation;
double _blurMaskFilterRadius = 0;
DropShadowKeyframeAnimation? dropShadowAnimation;
GradientFillContent(this.lottieDrawable, this.layer, this._fill)
: _cacheSteps =
@ -59,6 +65,18 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
_endPointAnimation.addUpdateListener(invalidate);
layer.addAnimation(_endPointAnimation);
var blurEffect = layer.blurEffect;
if (blurEffect != null) {
_blurAnimation = blurEffect.blurriness.createAnimation()
..addUpdateListener(invalidate);
layer.addAnimation(_blurAnimation);
}
var dropShadowEffect = layer.dropShadowEffect;
if (dropShadowEffect != null) {
dropShadowAnimation =
DropShadowKeyframeAnimation(invalidate, layer, dropShadowEffect);
}
}
@override
@ -103,6 +121,18 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
_paint.colorFilter = _colorFilterAnimation!.value;
}
var blurAnimation = _blurAnimation;
if (blurAnimation != null) {
var blurRadius = blurAnimation.value;
if (blurRadius == 0) {
_paint.maskFilter = null;
} else if (blurRadius != _blurMaskFilterRadius) {
var blur = layer.getBlurMaskFilter(blurRadius);
_paint.maskFilter = blur;
}
_blurMaskFilterRadius = blurRadius;
}
var alpha =
((parentAlpha / 255.0 * _opacityAnimation.value / 100.0) * 255).round();
_paint.setAlpha(alpha.clamp(0, 255).toInt());
@ -112,6 +142,10 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
canvas.save();
canvas.transform(parentMatrix.storage);
var dropShadow = dropShadowAnimation;
if (dropShadow != null) {
dropShadow.draw(canvas, _path);
}
canvas.drawPath(_path, _paint);
canvas.restore();
L.endSection('GradientFillContent#draw');
@ -246,6 +280,27 @@ class GradientFillContent implements DrawingContent, KeyPathElementContent {
..addUpdateListener(invalidate);
layer.addAnimation(_colorCallbackAnimation);
}
} else if (property == LottieProperty.blurRadius) {
var blurAnimation = _blurAnimation;
if (blurAnimation != null) {
blurAnimation
.setValueCallback(callback as LottieValueCallback<double>?);
} else {
_blurAnimation = blurAnimation = ValueCallbackKeyframeAnimation(
callback as LottieValueCallback<double>?, 0)
..addUpdateListener(invalidate);
layer.addAnimation(blurAnimation);
}
} else if (property == LottieProperty.dropShadow) {
var dropShadowAnimation = this.dropShadowAnimation;
if (dropShadowAnimation == null) {
var effect = DropShadowEffect.createEmpty();
this.dropShadowAnimation = dropShadowAnimation = dropShadowAnimation =
DropShadowKeyframeAnimation(invalidate, layer, effect);
}
dropShadowAnimation
.setCallback(callback as LottieValueCallback<DropShadow>?);
}
}
}

View File

@ -0,0 +1,108 @@
import 'dart:math' as math;
import 'dart:ui';
import '../../lottie_property.dart';
import '../../model/content/drop_shadow_effect.dart';
import '../../model/layer/base_layer.dart';
import '../../value/drop_shadow.dart';
import '../../value/lottie_frame_info.dart';
import '../../value/lottie_value_callback.dart';
import 'base_keyframe_animation.dart';
import 'color_keyframe_animation.dart';
class DropShadowKeyframeAnimation {
static final double _degToRad = math.pi / 180.0;
final void Function() listener;
late final ColorKeyframeAnimation _color;
late final BaseKeyframeAnimation<double, double> _opacity;
late final BaseKeyframeAnimation<double, double> _direction;
late final BaseKeyframeAnimation<double, double> _distance;
late final BaseKeyframeAnimation<double, double> _radius;
Paint? _paint;
DropShadowKeyframeAnimation(
this.listener, BaseLayer layer, DropShadowEffect dropShadowEffect) {
_color = dropShadowEffect.color.createAnimation()
..addUpdateListener(onValueChanged);
layer.addAnimation(_color);
_opacity = dropShadowEffect.opacity.createAnimation()
..addUpdateListener(onValueChanged);
layer.addAnimation(_opacity);
_direction = dropShadowEffect.direction.createAnimation()
..addUpdateListener(onValueChanged);
layer.addAnimation(_direction);
_distance = dropShadowEffect.distance.createAnimation()
..addUpdateListener(onValueChanged);
layer.addAnimation(_distance);
_radius = dropShadowEffect.radius.createAnimation()
..addUpdateListener(onValueChanged);
layer.addAnimation(_radius);
}
void onValueChanged() {
_paint = null;
listener();
}
void draw(Canvas canvas, Path path) {
var directionRad = _direction.value * _degToRad;
var distance = _distance.value;
var x = math.sin(directionRad) * distance;
var y = math.cos(directionRad + math.pi) * distance;
var baseColor = _color.value;
var opacity = _opacity.value.round();
var color = baseColor.withAlpha(opacity);
var radius = _radius.value;
var sigma = radius * 0.57735 + 0.5;
var paint = _paint;
paint ??= _paint = Paint()
..color = color
..maskFilter = MaskFilter.blur(BlurStyle.normal, sigma);
canvas.drawPath(path.shift(Offset(x, y)), paint);
}
void setCallback(LottieValueCallback<DropShadow>? callback) {
if (callback != null) {
_color.setValueCallback(_createCallback(
callback, (c) => c?.color ?? const Color(0xff000000)));
_opacity.setValueCallback(
_createCallback(callback, (c) => c?.color.alpha.toDouble() ?? 255));
_direction.setValueCallback(
_createCallback(callback, (c) => c?.direction ?? 0));
_distance
.setValueCallback(_createCallback(callback, (c) => c?.distance ?? 0));
_radius
.setValueCallback(_createCallback(callback, (c) => c?.radius ?? 0));
} else {
_color.setValueCallback(null);
_opacity.setValueCallback(null);
_direction.setValueCallback(null);
_distance.setValueCallback(null);
_radius.setValueCallback(null);
}
}
LottieValueCallback<T> _createCallback<T>(
LottieValueCallback<DropShadow> callback,
T Function(DropShadow?) selector) {
return LottieValueCallback<T>(null)
..callback = (info) {
onValueChanged();
var frameInfo = LottieFrameInfo<DropShadow>(
info.startFrame,
info.endFrame,
LottieProperty.dropShadow,
LottieProperty.dropShadow,
info.linearKeyframeProgress,
info.interpolatedKeyframeProgress,
info.overallProgress,
);
var dropShadow = callback.getValue(frameInfo);
return selector(dropShadow);
};
}
}

View File

@ -1,4 +1,5 @@
import 'dart:ui';
import 'value/drop_shadow.dart';
/// Property values are the same type as the generic type of their corresponding
/// {@link LottieValueCallback}. With this, we can use generics to maintain type safety
@ -122,6 +123,12 @@ abstract class LottieProperty {
/// In Dp
static const double textSize = 28.0;
/// In Px
static const double blurRadius = 29.0;
static const dropShadow = DropShadow(
color: Color(0x00000000), direction: 0, distance: 0, radius: 0);
static const ColorFilter colorFilter =
ColorFilter.mode(Color(0xFF000000), BlendMode.dst);

View File

@ -22,7 +22,9 @@ abstract class BaseAnimatableValue<V extends Object, O extends Object>
String toString() {
final sb = StringBuffer();
if (keyframes.isNotEmpty) {
sb..write('values=')..write('$keyframes');
sb
..write('values=')
..write('$keyframes');
}
return sb.toString();
}

View File

@ -0,0 +1,7 @@
import '../animatable/animatable_double_value.dart';
class BlurEffect {
final AnimatableDoubleValue blurriness;
BlurEffect(this.blurriness);
}

View File

@ -0,0 +1,29 @@
import 'package:flutter/painting.dart';
import '../../value/keyframe.dart';
import '../animatable/animatable_color_value.dart';
import '../animatable/animatable_double_value.dart';
class DropShadowEffect {
final AnimatableColorValue color;
final AnimatableDoubleValue opacity;
final AnimatableDoubleValue direction;
final AnimatableDoubleValue distance;
final AnimatableDoubleValue radius;
DropShadowEffect({
required this.color,
required this.opacity,
required this.direction,
required this.distance,
required this.radius,
});
static DropShadowEffect createEmpty() => DropShadowEffect(
color: AnimatableColorValue.fromKeyframes(
[Keyframe.nonAnimated(const Color(0x00000000))]),
direction: AnimatableDoubleValue(),
radius: AnimatableDoubleValue(),
distance: AnimatableDoubleValue(),
opacity: AnimatableDoubleValue(),
);
}

View File

@ -14,6 +14,8 @@ import '../../l.dart';
import '../../lottie_drawable.dart';
import '../../utils.dart';
import '../../value/lottie_value_callback.dart';
import '../content/blur_effect.dart';
import '../content/drop_shadow_effect.dart';
import '../content/mask.dart';
import '../content/shape_data.dart';
import '../key_path.dart';
@ -27,11 +29,14 @@ import 'solid_layer.dart';
import 'text_layer.dart';
abstract class BaseLayer implements DrawingContent, KeyPathElement {
static BaseLayer? forModel(Layer layerModel, LottieDrawable drawable,
static BaseLayer? forModel(
CompositionLayer compositionLayer,
Layer layerModel,
LottieDrawable drawable,
LottieComposition composition) {
switch (layerModel.layerType) {
case LayerType.shape:
return ShapeLayer(drawable, layerModel);
return ShapeLayer(drawable, layerModel, compositionLayer);
case LayerType.preComp:
return CompositionLayer(drawable, layerModel,
composition.getPrecomps(layerModel.refId)!, composition);
@ -77,6 +82,9 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
final TransformKeyframeAnimation transform;
bool _visible = true;
double blurMaskFilterRadius = 0;
MaskFilter? blurMaskFilter;
BaseLayer(this.lottieDrawable, this.layerModel)
: _drawTraceName = '${layerModel.name}#draw',
transform = layerModel.transform.createAnimation() {
@ -547,6 +555,22 @@ abstract class BaseLayer implements DrawingContent, KeyPathElement {
return layerModel.name;
}
BlurEffect? get blurEffect {
return layerModel.blurEffect;
}
MaskFilter? getBlurMaskFilter(double radius) {
if (blurMaskFilterRadius == radius) {
return blurMaskFilter;
}
var sigma = radius * 0.57735 + 0.5;
blurMaskFilter = MaskFilter.blur(BlurStyle.normal, sigma);
blurMaskFilterRadius = radius;
return blurMaskFilter;
}
DropShadowEffect? get dropShadowEffect => layerModel.dropShadowEffect;
@override
void setContents(List<Content> contentsBefore, List<Content> contentsAfter) {
// Do nothing

View File

@ -36,7 +36,7 @@ class CompositionLayer extends BaseLayer {
BaseLayer? mattedLayer;
for (var i = layerModels.length - 1; i >= 0; i--) {
var lm = layerModels[i];
var layer = BaseLayer.forModel(lm, lottieDrawable, composition);
var layer = BaseLayer.forModel(this, lm, lottieDrawable, composition);
if (layer == null) {
continue;
}

View File

@ -5,7 +5,9 @@ import '../animatable/animatable_double_value.dart';
import '../animatable/animatable_text_frame.dart';
import '../animatable/animatable_text_properties.dart';
import '../animatable/animatable_transform.dart';
import '../content/blur_effect.dart';
import '../content/content_model.dart';
import '../content/drop_shadow_effect.dart';
import '../content/mask.dart';
enum LayerType { preComp, solid, image, nullLayer, shape, text, unknown }
@ -35,6 +37,8 @@ class Layer {
final MatteType matteType;
final AnimatableDoubleValue? timeRemapping;
final bool isHidden;
final BlurEffect? blurEffect;
final DropShadowEffect? dropShadowEffect;
double get startProgress {
return startFrame / composition.durationFrames;
@ -63,6 +67,8 @@ class Layer {
required this.matteType,
this.timeRemapping,
required this.isHidden,
this.blurEffect,
this.dropShadowEffect,
});
@override
@ -71,19 +77,32 @@ class Layer {
}
String toStringWithPrefix(String prefix) {
var sb = StringBuffer()..write(prefix)..write(name)..write('\n');
var sb = StringBuffer()
..write(prefix)
..write(name)
..write('\n');
var parent = composition.layerModelForId(parentId);
if (parent != null) {
sb..write('\t\tParents: ')..write(parent.name);
sb
..write('\t\tParents: ')
..write(parent.name);
parent = composition.layerModelForId(parent.parentId);
while (parent != null) {
sb..write('->')..write(parent.name);
sb
..write('->')
..write(parent.name);
parent = composition.layerModelForId(parent.parentId);
}
sb..write(prefix)..write('\n');
sb
..write(prefix)
..write('\n');
}
if (masks.isNotEmpty) {
sb..write(prefix)..write('\tMasks: ')..write(masks.length)..write('\n');
sb
..write(prefix)
..write('\tMasks: ')
..write(masks.length)
..write('\n');
}
if (solidWidth != 0 && solidHeight != 0) {
sb
@ -92,9 +111,15 @@ class Layer {
..write('${solidWidth}x$solidHeight $solidColor');
}
if (shapes.isNotEmpty) {
sb..write(prefix)..write('\tShapes:\n');
sb
..write(prefix)
..write('\tShapes:\n');
for (Object shape in shapes) {
sb..write(prefix)..write('\t\t')..write(shape)..write('\n');
sb
..write(prefix)
..write('\t\t')
..write(shape)
..write('\n');
}
}
return sb.toString();

View File

@ -3,15 +3,20 @@ import 'package:vector_math/vector_math_64.dart';
import '../../animation/content/content.dart';
import '../../animation/content/content_group.dart';
import '../../lottie_drawable.dart';
import '../content/blur_effect.dart';
import '../content/drop_shadow_effect.dart';
import '../content/shape_group.dart';
import '../key_path.dart';
import 'base_layer.dart';
import 'composition_layer.dart';
import 'layer.dart';
class ShapeLayer extends BaseLayer {
late ContentGroup _contentGroup;
final CompositionLayer _compositionLayer;
ShapeLayer(LottieDrawable lottieDrawable, Layer layerModel)
ShapeLayer(
LottieDrawable lottieDrawable, Layer layerModel, this._compositionLayer)
: super(lottieDrawable, layerModel) {
// Naming this __container allows it to be ignored in KeyPath matching.
var shapeGroup =
@ -34,6 +39,24 @@ class ShapeLayer extends BaseLayer {
return bounds;
}
@override
BlurEffect? get blurEffect {
var layerBlur = super.blurEffect;
if (layerBlur != null) {
return layerBlur;
}
return _compositionLayer.blurEffect;
}
@override
DropShadowEffect? get dropShadowEffect {
var layerDropShadow = super.dropShadowEffect;
if (layerDropShadow != null) {
return layerDropShadow;
}
return _compositionLayer.dropShadowEffect;
}
@override
void resolveChildKeyPath(KeyPath keyPath, int depth,
List<KeyPath> accumulator, KeyPath currentPartialKeyPath) {

View File

@ -0,0 +1,60 @@
import '../composition.dart';
import '../model/content/blur_effect.dart';
import 'animatable_value_parser.dart';
import 'moshi/json_reader.dart';
class BlurEffectParser {
static final JsonReaderOptions _blurEffectNames =
JsonReaderOptions.of(['ef']);
static final JsonReaderOptions _innerBlurEffectNames =
JsonReaderOptions.of(['ty', 'v']);
static BlurEffect? parse(JsonReader reader, LottieComposition composition) {
BlurEffect? blurEffect;
while (reader.hasNext()) {
switch (reader.selectName(_blurEffectNames)) {
case 0:
reader.beginArray();
while (reader.hasNext()) {
var be = _maybeParseInnerEffect(reader, composition);
if (be != null) {
blurEffect = be;
}
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
}
}
return blurEffect;
}
static BlurEffect? _maybeParseInnerEffect(
JsonReader reader, LottieComposition composition) {
BlurEffect? blurEffect;
var isCorrectType = false;
reader.beginObject();
while (reader.hasNext()) {
switch (reader.selectName(_innerBlurEffectNames)) {
case 0:
isCorrectType = reader.nextInt() == 0;
break;
case 1:
if (isCorrectType) {
blurEffect = BlurEffect(
AnimatableValueParser.parseFloat(reader, composition));
} else {
reader.skipValue();
}
break;
default:
reader.skipName();
reader.skipValue();
}
}
reader.endObject();
return blurEffect;
}
}

View File

@ -0,0 +1,97 @@
import '../composition.dart';
import '../model/animatable/animatable_color_value.dart';
import '../model/animatable/animatable_double_value.dart';
import '../model/content/drop_shadow_effect.dart';
import 'animatable_value_parser.dart';
import 'moshi/json_reader.dart';
class DropShadowEffectParser {
static final JsonReaderOptions _dropShadowEffectNames =
JsonReaderOptions.of(['ef']);
static final JsonReaderOptions _innerEffectNames =
JsonReaderOptions.of(['nm', 'v']);
AnimatableColorValue? _color;
AnimatableDoubleValue? _opacity;
AnimatableDoubleValue? _direction;
AnimatableDoubleValue? _distance;
AnimatableDoubleValue? _radius;
DropShadowEffect? parse(JsonReader reader, LottieComposition composition) {
while (reader.hasNext()) {
switch (reader.selectName(_dropShadowEffectNames)) {
case 0:
reader.beginArray();
while (reader.hasNext()) {
_maybeParseInnerEffect(reader, composition);
}
reader.endArray();
break;
default:
reader.skipName();
reader.skipValue();
}
}
var color = _color;
var opacity = _opacity;
var direction = _direction;
var distance = _distance;
var radius = _radius;
if (color != null &&
opacity != null &&
direction != null &&
distance != null &&
radius != null) {
return DropShadowEffect(
color: color,
opacity: opacity,
direction: direction,
distance: distance,
radius: radius);
}
return null;
}
void _maybeParseInnerEffect(
JsonReader reader, LottieComposition composition) {
var currentEffectName = '';
reader.beginObject();
while (reader.hasNext()) {
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,
isDp: false);
break;
case 'Direction':
_direction = AnimatableValueParser.parseFloat(reader, composition,
isDp: false);
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();
}
}
reader.endObject();
}
}

View File

@ -302,7 +302,7 @@ class KeyframeParser {
interpolator = _pathInterpolatorCache.putIfAbsent(hash, () {
try {
return Cubic(cp1.dx, cp1.dy, cp2.dx, cp2.dy);
return PathInterpolator.cubic(cp1.dx, cp1.dy, cp2.dx, cp2.dy);
} catch (e) {
debugPrint('DEBUG: Path interpolator error $e');
//TODO(xha): check the error message for Flutter

View File

@ -4,7 +4,9 @@ import '../model/animatable/animatable_double_value.dart';
import '../model/animatable/animatable_text_frame.dart';
import '../model/animatable/animatable_text_properties.dart';
import '../model/animatable/animatable_transform.dart';
import '../model/content/blur_effect.dart';
import '../model/content/content_model.dart';
import '../model/content/drop_shadow_effect.dart';
import '../model/content/mask.dart';
import '../model/layer/layer.dart';
import '../utils/misc.dart';
@ -12,7 +14,9 @@ import '../value/keyframe.dart';
import 'animatable_text_properties_parser.dart';
import 'animatable_transform_parser.dart';
import 'animatable_value_parser.dart';
import 'blur_effect_parser.dart';
import 'content_model_parser.dart';
import 'drop_shadow_effect_parser.dart';
import 'mask_parser.dart';
import 'moshi/json_reader.dart';
@ -74,7 +78,8 @@ class LayerParser {
static final JsonReaderOptions _textNames = JsonReaderOptions.of(['d', 'a']);
static final JsonReaderOptions _effectsNames = JsonReaderOptions.of(['nm']);
static final JsonReaderOptions _effectsNames =
JsonReaderOptions.of(['ty', 'nm']);
static Layer parseJson(JsonReader reader, LottieComposition composition) {
// This should always be set by After Effects. However, if somebody wants to minify
@ -95,6 +100,8 @@ class LayerParser {
var outFrame = 0.0;
String? cl;
var hidden = false;
BlurEffect? blurEffect;
DropShadowEffect? dropShadowEffect;
var matteType = MatteType.none;
AnimatableTransform? transform;
@ -207,7 +214,17 @@ class LayerParser {
while (reader.hasNext()) {
switch (reader.selectName(_effectsNames)) {
case 0:
effectNames.add(reader.nextString());
var type = reader.nextInt();
if (type == 29) {
blurEffect = BlurEffectParser.parse(reader, composition);
} else if (type == 25) {
dropShadowEffect =
DropShadowEffectParser().parse(reader, composition);
}
break;
case 1:
var effectName = reader.nextString();
effectNames.add(effectName);
break;
default:
reader.skipName();
@ -313,6 +330,9 @@ class LayerParser {
inOutKeyframes: inOutKeyframes,
matteType: matteType,
timeRemapping: timeRemapping,
isHidden: hidden);
isHidden: hidden,
blurEffect: blurEffect,
dropShadowEffect: dropShadowEffect,
);
}
}

View File

@ -39,7 +39,10 @@ class JsonScope {
switch (stack[i]) {
case emptyArray:
case nonEmptyArray:
result..write('[')..write(pathIndices[i])..write(']');
result
..write('[')
..write(pathIndices[i])
..write(']');
break;
case emptyObject:

View File

@ -88,8 +88,6 @@ extension IterableExtension<T> on Iterable<T> {
}
class ListEquality<E> {
static const int _hashMask = 0x7fffffff;
const ListEquality();
bool equals(List<E>? list1, List<E>? list2) {
@ -102,22 +100,4 @@ class ListEquality<E> {
}
return true;
}
int hash(List<E>? list) {
if (list == null) return null.hashCode;
// Jenkins's one-at-a-time hash function.
// This code is almost identical to the one in IterableEquality, except
// that it uses indexing instead of iterating to get the elements.
var hash = 0;
for (var i = 0; i < list.length; i++) {
var c = list[i].hashCode;
hash = (hash + c) & _hashMask;
hash = (hash + (hash << 10)) & _hashMask;
hash ^= hash >> 6;
}
hash = (hash + (hash << 3)) & _hashMask;
hash ^= hash >> 11;
hash = (hash + (hash << 15)) & _hashMask;
return hash;
}
}

View File

@ -0,0 +1,41 @@
import 'package:flutter/painting.dart';
class DropShadow {
final Color color;
final double direction;
final double distance;
final double radius;
const DropShadow({
required this.color,
required this.direction,
required this.distance,
required this.radius,
});
DropShadow copyWith(
{Color? color, double? direction, double? distance, double? radius}) {
return DropShadow(
color: color ?? this.color,
direction: direction ?? this.direction,
distance: distance ?? this.distance,
radius: radius ?? this.radius,
);
}
@override
bool operator ==(other) {
return other is DropShadow &&
other.color == color &&
other.direction == direction &&
other.distance == distance &&
other.radius == radius;
}
@override
int get hashCode => hashValues(color, direction, distance, radius);
@override
String toString() => 'DropShadow(color: $color, direction: $direction, '
'distance: $distance, radius: $radius)';
}

View File

@ -3,6 +3,7 @@ import 'lottie_drawable.dart';
import 'lottie_property.dart';
import 'model/key_path.dart';
import 'utils.dart';
import 'value/drop_shadow.dart';
import 'value/lottie_frame_info.dart';
import 'value/lottie_relative_double_value_callback.dart';
import 'value/lottie_relative_integer_value_callback.dart';
@ -263,6 +264,16 @@ class ValueDelegate<T> {
List<Color> Function(LottieFrameInfo<List<Color>>)? callback}) =>
ValueDelegate._(keyPath, LottieProperty.gradientColor, value, callback);
static ValueDelegate<double> blurRadius(List<String> keyPath,
{double? value,
double Function(LottieFrameInfo<double>)? callback}) =>
ValueDelegate._(keyPath, LottieProperty.blurRadius, value, callback);
static ValueDelegate<DropShadow> dropShadow(List<String> keyPath,
{DropShadow? value,
DropShadow Function(LottieFrameInfo<DropShadow>)? callback}) =>
ValueDelegate._(keyPath, LottieProperty.dropShadow, value, callback);
ResolvedValueDelegate<T>? _resolved;
ResolvedValueDelegate _resolve(List<KeyPath> resolvedPaths) {
_resolved = ResolvedValueDelegate<T>(this, resolvedPaths);

View File

@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "22.0.0"
version: "26.0.0"
analyzer:
dependency: "direct dev"
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.1"
version: "2.3.0"
archive:
dependency: "direct main"
description:
@ -28,14 +28,14 @@ packages:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.3.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.6.1"
version: "2.8.1"
boolean_selector:
dependency: transitive
description:
@ -49,7 +49,7 @@ packages:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.1.0"
build_config:
dependency: transitive
description:
@ -70,35 +70,35 @@ packages:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
version: "2.0.4"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.1.2"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "7.0.0"
version: "7.1.0"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.0"
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.1.0"
version: "8.1.2"
characters:
dependency: "direct main"
description:
@ -112,7 +112,7 @@ packages:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.1"
checked_yaml:
dependency: transitive
description:
@ -126,7 +126,7 @@ packages:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.2"
version: "0.3.3"
clock:
dependency: transitive
description:
@ -140,7 +140,7 @@ packages:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
version: "4.1.0"
collection:
dependency: transitive
description:
@ -168,7 +168,7 @@ packages:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
version: "2.1.0"
fake_async:
dependency: transitive
description:
@ -201,7 +201,7 @@ packages:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "1.0.4"
flutter_test:
dependency: "direct dev"
description: flutter
@ -213,7 +213,7 @@ packages:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.1.2"
glob:
dependency: transitive
description:
@ -227,7 +227,7 @@ packages:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0"
http_multi_server:
dependency: transitive
description:
@ -248,7 +248,7 @@ packages:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
version: "1.0.3"
js:
dependency: transitive
description:
@ -276,7 +276,7 @@ packages:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.0.2"
matcher:
dependency: transitive
description:
@ -290,7 +290,7 @@ packages:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.7.0"
mime:
dependency: transitive
description:
@ -304,7 +304,7 @@ packages:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
path:
dependency: "direct main"
description:
@ -332,7 +332,7 @@ packages:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0"
pubspec_parse:
dependency: transitive
description:
@ -346,7 +346,7 @@ packages:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.4"
version: "1.2.0"
shelf_web_socket:
dependency: transitive
description:
@ -407,7 +407,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
version: "0.4.2"
timing:
dependency: transitive
description:

View File

@ -1,10 +1,10 @@
name: lottie
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
version: 1.1.0
version: 1.2.1
homepage: https://github.com/xvrh/lottie-flutter
environment:
sdk: '>=2.12.0-0 <3.0.0'
sdk: '>=2.12.0 <3.0.0'
dependencies:
archive: ^3.0.0

View File

@ -288,6 +288,27 @@ void main() {
filePath: 'Tests/TrackMattes.json',
);
testGolden(
'Blur',
ValueDelegate.blurRadius(
['**'],
value: 22,
),
);
testGolden(
'Drop shadow',
ValueDelegate.dropShadow(
['Shape Layer 1', '**'],
value: const DropShadow(
color: Colors.green,
direction: 150,
distance: 20,
radius: 10,
),
),
);
for (var progress in [0.0, 0.5, 1.0]) {
testGolden(
'Opacity interpolation ($progress)',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

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