diff --git a/example/.gitignore b/example/.gitignore index 07488ba..4bf79c9 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -8,6 +8,7 @@ .buildlog/ .history .svn/ +go/ # IntelliJ related *.iml diff --git a/example/assets/fonts/museo-sans.ttf b/example/assets/fonts/museo-sans.ttf new file mode 100644 index 0000000..67c604d Binary files /dev/null and b/example/assets/fonts/museo-sans.ttf differ diff --git a/example/lib/main.dart b/example/lib/main.dart index 920c47d..dc79f7a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,64 +1,93 @@ import 'package:flutter/material.dart'; +import 'package:ripple_effect/ripple_effect.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { - @override Widget build(BuildContext context) { return MaterialApp( title: 'Ripple Effect Demo', - theme: ThemeData( - primarySwatch: Colors.blue, + theme: new ThemeData( + primarySwatch: Colors.purple, + primaryColor: Colors.blue, + fontFamily: 'Museo Sans', ), - home: MyHomePage(title: 'Ripple Effect Demo Home Page'), + debugShowCheckedModeBanner: false, + home: HomePage(), ); } } -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - final String title; - +class HomePage extends StatefulWidget { @override - _MyHomePageState createState() => _MyHomePageState(); + _HomePageState createState() => _HomePageState(); } -class _MyHomePageState extends State { - int _counter = 0; +class _HomePageState extends State { + final pageKey = RipplePage.createGlobalKey(); + final effectKey = RippleEffect.createGlobalKey(); - void _incrementCounter() { - setState(() { - _counter++; - }); + @override + Widget build(BuildContext context) { + return RipplePage( + pageKey: pageKey, + child: Scaffold( + appBar: AppBar( + title: Center(child: Text('Home')), + ), + body: Center(), + floatingActionButton: RippleEffect( + pageKey: pageKey, + effectKey: effectKey, + color: Colors.purple, + child: FloatingActionButton( + onPressed: () => RippleEffect.start(effectKey, toNextPage), + child: Icon(Icons.cake), + ), + ), + ), + ); } + Future toNextPage() => Navigator.of(context).push( + FadeRouteBuilder( + page: SecondPage(), + ), + ); +} + +class SecondPage extends StatelessWidget { + final pageKey = RipplePage.createGlobalKey(); + final effectKey = RippleEffect.createGlobalKey(); + @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.display1, + return RipplePage( + pageKey: pageKey, + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.purple, + title: Center(child: Text('Second Page')), + ), + body: Center(), + floatingActionButton: RippleEffect( + pageKey: pageKey, + effectKey: effectKey, + color: Colors.blue, + child: FloatingActionButton( + backgroundColor: Colors.blue, + onPressed: () => + RippleEffect.start(effectKey, () => toNextPage(context)), + child: Icon(Icons.arrow_back), ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), + )), ); } + + Future toNextPage(BuildContext context) => Navigator.of(context).push( + FadeRouteBuilder( + page: HomePage(), + ), + ); } diff --git a/example/lib/main_desktop.dart b/example/lib/main_desktop.dart new file mode 100644 index 0000000..9c730a7 --- /dev/null +++ b/example/lib/main_desktop.dart @@ -0,0 +1,10 @@ +import 'package:flutter/foundation.dart' + show debugDefaultTargetPlatformOverride; +import 'package:flutter/material.dart'; + +import 'main.dart' as original_main; + +void main() { + debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; + original_main.main(); +} diff --git a/example/pubspec.lock b/example/pubspec.lock index fcf6763..9db2e66 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -57,13 +57,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" flutter: dependency: "direct main" description: flutter @@ -123,6 +116,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.5" + rect_getter: + dependency: transitive + description: + name: rect_getter + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + ripple_effect: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.1.0" sky_engine: dependency: transitive description: flutter @@ -193,3 +200,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.4.0 <3.0.0" + flutter: ">=0.1.4 <2.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 60fe6c6..953a73e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -21,3 +21,7 @@ dependency_overrides: flutter: uses-material-design: true + fonts: + - family: "Museo Sans" + fonts: + - asset: assets/fonts/museo-sans.ttf diff --git a/lib/ripple_effect.dart b/lib/ripple_effect.dart index c0ee0fd..cfce67f 100644 --- a/lib/ripple_effect.dart +++ b/lib/ripple_effect.dart @@ -1,4 +1,4 @@ library ripple_effect; -export 'src/ripple_effect.dart' show Ripple, RippleEffect; +export 'src/ripple_effect.dart' show RipplePage, RippleEffect; export 'src/transition.dart'; diff --git a/lib/src/ripple_data.dart b/lib/src/ripple_data.dart index 98e0ca5..cfceced 100644 --- a/lib/src/ripple_data.dart +++ b/lib/src/ripple_data.dart @@ -1,13 +1,23 @@ import 'package:flutter/material.dart'; -import 'ripple_effect.dart'; - class RippleData { - RippleData(this.rippleState, this.rect, this.color); + RippleData({ + @required this.context, + @required this.color, + @required this.animationDuration, + @required this.delay, + @required this.shape, + @required this.inflateMultiplier, + }); + + final BuildContext context; + final Color color; + final Duration animationDuration; + final Duration delay; + final BoxShape shape; + final double inflateMultiplier; - RippleState rippleState; Rect rect; - Color color; Widget toWidget() { if (rect == null) { @@ -17,15 +27,15 @@ class RippleData { return AnimatedPositioned( left: rect.left, top: rect.top, - right: MediaQuery.of(rippleState.context).size.width - rect.right, - bottom: MediaQuery.of(rippleState.context).size.height - rect.bottom, + right: MediaQuery.of(context).size.width - rect.right, + bottom: MediaQuery.of(context).size.height - rect.bottom, child: Container( decoration: BoxDecoration( - shape: rippleState.widget.shape, + shape: shape, color: color, ), ), - duration: rippleState.widget.animationDuration, + duration: animationDuration, ); } } diff --git a/lib/src/ripple_effect.dart b/lib/src/ripple_effect.dart index 84ab186..9f606fd 100644 --- a/lib/src/ripple_effect.dart +++ b/lib/src/ripple_effect.dart @@ -3,31 +3,22 @@ import 'package:rect_getter/rect_getter.dart'; import 'ripple_data.dart'; -class Ripple extends StatefulWidget { - Ripple({ - @required GlobalKey key, +class RipplePage extends StatefulWidget { + RipplePage({ + @required GlobalKey<_RipplePageState> pageKey, @required this.child, - this.animationDuration = const Duration(milliseconds: 300), - this.delay = const Duration(milliseconds: 300), - this.shape = BoxShape.circle, - this.inflateMultiplier = 1.3, - }) : super(key: key); + }) : super(key: pageKey); final Widget child; - final Duration animationDuration; - final Duration delay; - final BoxShape shape; - final double inflateMultiplier; @override - RippleState createState() => RippleState(); + _RipplePageState createState() => _RipplePageState(); - static GlobalKey createGlobalKey() { - return new GlobalKey(); - } + static GlobalKey<_RipplePageState> createGlobalKey() => + new GlobalKey<_RipplePageState>(); } -class RippleState extends State { +class _RipplePageState extends State { final Map ripples = {}; @override @@ -38,51 +29,61 @@ class RippleState extends State { ripples.entries.map((entry) => entry.value.toWidget()).toList(), ); - Future addRipple(GlobalKey key, Color color) async => - this.ripples[key] = RippleData(this, null, color); + Future addRipple(GlobalKey key, RippleData data) async => + this.ripples[key] = data; Future startAnimation(GlobalKey key, VoidCallback callback) async { + final data = ripples[key]; + setState(() { - ripples[key].rect = RectGetter.getRectFromKey(key); + data.rect = RectGetter.getRectFromKey(key); }); WidgetsBinding.instance.addPostFrameCallback((_) { + final inflateSize = + data.inflateMultiplier * MediaQuery.of(context).size.longestSide; setState(() { - ripples[key].rect = ripples[key].rect?.inflate( - widget.inflateMultiplier * MediaQuery.of(context).size.longestSide); + data.rect = data.rect?.inflate(inflateSize); }); - Future.delayed(widget.animationDuration + widget.delay, callback) - .then((_) => setState(() => ripples[key]?.rect = null)); + Future.delayed(data.animationDuration + data.delay, callback) + .then((_) => setState(() => data.rect = null)); }); } } class RippleEffect extends StatefulWidget { RippleEffect({ - @required this.key, - @required this.rippleKey, - @required this.child, + @required this.pageKey, + @required this.effectKey, @required this.color, - }) : super(key: key); + @required this.child, + this.animationDuration = const Duration(milliseconds: 300), + this.delay = const Duration(milliseconds: 300), + this.shape = BoxShape.circle, + this.inflateMultiplier = 1.3, + }) : super(key: effectKey); - final GlobalKey<_RippleEffectState> key; - final GlobalKey rippleKey; - final Widget child; + final GlobalKey<_RipplePageState> pageKey; + final GlobalKey<_RippleEffectState> effectKey; final Color color; + final Widget child; + final Duration animationDuration; + final Duration delay; + final BoxShape shape; + final double inflateMultiplier; @override _RippleEffectState createState() => _RippleEffectState(); - static GlobalKey<_RippleEffectState> createGlobalKey() { - return new GlobalKey<_RippleEffectState>(); - } + static GlobalKey<_RippleEffectState> createGlobalKey() => + new GlobalKey<_RippleEffectState>(); - static Future wrap( + static Future start( GlobalKey<_RippleEffectState> rippleEffectKey, VoidCallback callback, ) { final rippleEffectState = rippleEffectKey?.currentState; - final rippleState = rippleEffectState.widget?.rippleKey?.currentState; + final rippleState = rippleEffectState.widget?.pageKey?.currentState; return rippleState?.startAnimation( rippleEffectState?.rectGetterKey, callback); @@ -94,8 +95,16 @@ class _RippleEffectState extends State { @override void initState() { - widget.rippleKey.currentState.addRipple(rectGetterKey, widget.color); super.initState(); + final data = RippleData( + context: context, + color: widget.color, + animationDuration: widget.animationDuration, + delay: widget.delay, + shape: widget.shape, + inflateMultiplier: widget.inflateMultiplier, + ); + widget.pageKey.currentState.addRipple(rectGetterKey, data); } @override