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]
|
||||
- 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());
|
||||
}
|
||||
|
||||
class App extends StatefulWidget {
|
||||
class App extends StatelessWidget {
|
||||
const App({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_AppState createState() => _AppState();
|
||||
}
|
||||
|
||||
class _AppState extends State<App> with TickerProviderStateMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
color: Colors.lightBlue,
|
||||
home: Scaffold(
|
||||
backgroundColor: Colors.lightBlue,
|
||||
appBar: AppBar(
|
||||
title: Text(''),
|
||||
),
|
||||
body: Center(
|
||||
child: SizedBox(
|
||||
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: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "0.3.4"
|
||||
version: "0.3.6"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
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_drawable.dart' show LottieDrawable, LottieFontStyle;
|
||||
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/file_provider.dart' show FileLottie;
|
||||
export 'src/providers/lottie_provider.dart' show LottieProvider;
|
||||
|
@ -1,26 +1,23 @@
|
||||
import 'package:meta/meta.dart';
|
||||
import '../../lottie.dart';
|
||||
|
||||
class Marker {
|
||||
static const String _carriageReturn = '\r';
|
||||
|
||||
final LottieComposition _composition;
|
||||
final String name;
|
||||
final double startFrame;
|
||||
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) {
|
||||
if (this.name.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;
|
||||
return this.name.trim().toLowerCase() == name.toLowerCase();
|
||||
}
|
||||
|
||||
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();
|
||||
markers.add(
|
||||
Marker(comment, startFrame: frame, durationFrames: durationFrames));
|
||||
markers.add(Marker(composition, comment,
|
||||
startFrame: frame, durationFrames: durationFrames));
|
||||
}
|
||||
reader.endArray();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: lottie
|
||||
description: Render After Effects animations natively on Flutter. This package is a pure Dart implementation of a Lottie player.
|
||||
version: 0.3.5
|
||||
version: 0.3.6
|
||||
homepage: https://github.com/xvrh/lottie-flutter
|
||||
|
||||
environment:
|
||||
|
Reference in New Issue
Block a user