mirror of
https://github.com/xvrh/lottie-flutter.git
synced 2025-08-06 16:39:36 +08:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
0715f6a402 |
@ -1,3 +1,6 @@
|
|||||||
|
## [0.3.6]
|
||||||
|
- Export the `Marker` class
|
||||||
|
|
||||||
## [0.3.5]
|
## [0.3.5]
|
||||||
- Fix a bug with a wrongly clipped rectangle.
|
- Fix a bug with a wrongly clipped rectangle.
|
||||||
|
|
||||||
|
1
example/assets/TwitterHeartButton.json
Normal file
1
example/assets/TwitterHeartButton.json
Normal file
File diff suppressed because one or more lines are too long
@ -5,23 +5,15 @@ void main() async {
|
|||||||
runApp(App());
|
runApp(App());
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends StatefulWidget {
|
class App extends StatelessWidget {
|
||||||
const App({Key key}) : super(key: key);
|
const App({Key key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
|
||||||
_AppState createState() => _AppState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AppState extends State<App> with TickerProviderStateMixin {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
color: Colors.lightBlue,
|
color: Colors.lightBlue,
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
backgroundColor: Colors.lightBlue,
|
backgroundColor: Colors.lightBlue,
|
||||||
appBar: AppBar(
|
|
||||||
title: Text(''),
|
|
||||||
),
|
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 300,
|
width: 300,
|
||||||
|
122
example/lib/examples/markers.dart
Normal file
122
example/lib/examples/markers.dart
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lottie/lottie.dart';
|
||||||
|
|
||||||
|
/// This example shows how to play the animation between two markers.
|
||||||
|
/// It is based on this article for lottie-ios:
|
||||||
|
/// https://medium.com/swlh/controlling-lottie-animation-with-markers-5e9035d94623
|
||||||
|
void main() async {
|
||||||
|
runApp(App());
|
||||||
|
}
|
||||||
|
|
||||||
|
class App extends StatefulWidget {
|
||||||
|
const App({Key key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_AppState createState() => _AppState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppState extends State<App> with TickerProviderStateMixin {
|
||||||
|
Future<LottieComposition> _composition;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_composition = AssetLottie('assets/TwitterHeartButton.json').load();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData.dark(),
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Markers'),
|
||||||
|
),
|
||||||
|
body: FutureBuilder<LottieComposition>(
|
||||||
|
future: _composition,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasError) return ErrorWidget(snapshot.error);
|
||||||
|
if (!snapshot.hasData) return CircularProgressIndicator();
|
||||||
|
return _LottieDetails(snapshot.data);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LottieDetails extends StatefulWidget {
|
||||||
|
final LottieComposition composition;
|
||||||
|
|
||||||
|
const _LottieDetails(this.composition, {Key key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_LottieDetailsState createState() => _LottieDetailsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LottieDetailsState extends State<_LottieDetails>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
AnimationController _controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = AnimationController(vsync: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListView(
|
||||||
|
children: [
|
||||||
|
Lottie(
|
||||||
|
composition: widget.composition,
|
||||||
|
controller: _controller,
|
||||||
|
height: 150,
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text('Composition start frame'),
|
||||||
|
trailing: Text(widget.composition.startFrame.toStringAsFixed(1)),
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text('Composition duration'),
|
||||||
|
trailing: Text(widget.composition.durationFrames.toStringAsFixed(1)),
|
||||||
|
),
|
||||||
|
RaisedButton(
|
||||||
|
child: Text('touchDownEnd - touchUpCancel'),
|
||||||
|
onPressed: () => _playBetween('touchDownEnd', 'touchUpCancel'),
|
||||||
|
),
|
||||||
|
RaisedButton(
|
||||||
|
child: Text('touchDownStart - touchDownEnd'),
|
||||||
|
onPressed: () => _playBetween('touchDownStart', 'touchDownEnd'),
|
||||||
|
),
|
||||||
|
RaisedButton(
|
||||||
|
child: Text('touchDownEnd - touchUpEnd'),
|
||||||
|
onPressed: () => _playBetween('touchDownEnd', 'touchUpEnd'),
|
||||||
|
),
|
||||||
|
for (var marker in widget.composition.markers)
|
||||||
|
ListTile(
|
||||||
|
title: Text(marker.name),
|
||||||
|
subtitle: Text(
|
||||||
|
'${marker.startFrame.toStringAsFixed(1)} ${marker.durationFrames.toStringAsFixed(1)}'),
|
||||||
|
trailing: Text(
|
||||||
|
'[${marker.start.toStringAsFixed(2)}-${marker.end.toStringAsFixed(2)}]'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _playBetween(String marker1, String marker2) {
|
||||||
|
var start = widget.composition.getMarker(marker1).start;
|
||||||
|
var end = widget.composition.getMarker(marker2).start;
|
||||||
|
|
||||||
|
_controller.value = start;
|
||||||
|
_controller.animateTo(end,
|
||||||
|
duration: widget.composition.duration * (end - start).abs());
|
||||||
|
}
|
||||||
|
}
|
@ -129,7 +129,7 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.3.4"
|
version: "0.3.6"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
BIN
example/test/goldens/all/twitterheartbutton.png
Normal file
BIN
example/test/goldens/all/twitterheartbutton.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -4,6 +4,7 @@ export 'src/lottie_builder.dart' show LottieBuilder;
|
|||||||
export 'src/lottie_delegates.dart' show LottieDelegates;
|
export 'src/lottie_delegates.dart' show LottieDelegates;
|
||||||
export 'src/lottie_drawable.dart' show LottieDrawable, LottieFontStyle;
|
export 'src/lottie_drawable.dart' show LottieDrawable, LottieFontStyle;
|
||||||
export 'src/lottie_image_asset.dart' show LottieImageAsset;
|
export 'src/lottie_image_asset.dart' show LottieImageAsset;
|
||||||
|
export 'src/model/marker.dart' show Marker;
|
||||||
export 'src/providers/asset_provider.dart' show AssetLottie;
|
export 'src/providers/asset_provider.dart' show AssetLottie;
|
||||||
export 'src/providers/file_provider.dart' show FileLottie;
|
export 'src/providers/file_provider.dart' show FileLottie;
|
||||||
export 'src/providers/lottie_provider.dart' show LottieProvider;
|
export 'src/providers/lottie_provider.dart' show LottieProvider;
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
import '../../lottie.dart';
|
||||||
|
|
||||||
class Marker {
|
class Marker {
|
||||||
static const String _carriageReturn = '\r';
|
final LottieComposition _composition;
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
final double startFrame;
|
final double startFrame;
|
||||||
final double durationFrames;
|
final double durationFrames;
|
||||||
|
|
||||||
Marker(this.name, {@required this.startFrame, @required this.durationFrames});
|
Marker(this._composition, this.name,
|
||||||
|
{@required this.startFrame, @required this.durationFrames});
|
||||||
|
|
||||||
bool matchesName(String name) {
|
bool matchesName(String name) {
|
||||||
if (this.name.toLowerCase() == name.toLowerCase()) {
|
return this.name.trim().toLowerCase() == name.toLowerCase();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is easy for a designer to accidentally include an extra newline which will cause the name to not match what they would
|
|
||||||
// expect. This is a convenience to precent unneccesary confusion.
|
|
||||||
if (this.name.endsWith(_carriageReturn) &&
|
|
||||||
this.name.substring(0, this.name.length - 1).toLowerCase() ==
|
|
||||||
name.toLowerCase()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double get start =>
|
||||||
|
(startFrame - _composition.startFrame) / _composition.durationFrames;
|
||||||
|
|
||||||
|
double get end =>
|
||||||
|
(startFrame + durationFrames - _composition.startFrame) /
|
||||||
|
_composition.durationFrames;
|
||||||
}
|
}
|
||||||
|
@ -254,8 +254,8 @@ class LottieCompositionParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.endObject();
|
reader.endObject();
|
||||||
markers.add(
|
markers.add(Marker(composition, comment,
|
||||||
Marker(comment, startFrame: frame, durationFrames: durationFrames));
|
startFrame: frame, durationFrames: durationFrames));
|
||||||
}
|
}
|
||||||
reader.endArray();
|
reader.endArray();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: lottie
|
name: lottie
|
||||||
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
|
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
|
||||||
version: 0.3.5
|
version: 0.3.6
|
||||||
homepage: https://github.com/xvrh/lottie-flutter
|
homepage: https://github.com/xvrh/lottie-flutter
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
Reference in New Issue
Block a user