| Index: sky/examples/fn/widgets/inksplash.dart
|
| diff --git a/sky/examples/fn/widgets/inksplash.dart b/sky/examples/fn/widgets/inksplash.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c5abb270942f836d172e1ae8a42533b4f1c13ee1
|
| --- /dev/null
|
| +++ b/sky/examples/fn/widgets/inksplash.dart
|
| @@ -0,0 +1,96 @@
|
| +part of widgets;
|
| +
|
| +const double _kSplashSize = 400.0;
|
| +const double _kSplashDuration = 500.0;
|
| +
|
| +class SplashAnimation {
|
| + AnimationGenerator _animation;
|
| + double _offsetX;
|
| + double _offsetY;
|
| +
|
| + Stream<String> _styleChanged;
|
| +
|
| + Stream<String> get onStyleChanged => _styleChanged;
|
| +
|
| + void cancel() => _animation.cancel();
|
| +
|
| + SplashAnimation(sky.ClientRect rect, double x, double y,
|
| + { Function onDone })
|
| + : _offsetX = x - rect.left,
|
| + _offsetY = y - rect.top {
|
| +
|
| + _animation = new AnimationGenerator(_kSplashDuration,
|
| + end: _kSplashSize, curve: easeOut, onDone: onDone);
|
| +
|
| + _styleChanged = _animation.onTick.map((p) => '''
|
| + top: ${_offsetY - p/2}px;
|
| + left: ${_offsetX - p/2}px;
|
| + width: ${p}px;
|
| + height: ${p}px;
|
| + border-radius: ${p}px;
|
| + opacity: ${1.0 - (p / _kSplashSize)};
|
| + ''');
|
| + }
|
| +}
|
| +
|
| +class InkSplash extends Component {
|
| +
|
| + Stream<String> onStyleChanged;
|
| +
|
| + static Style _style = new Style('''
|
| + position: absolute;
|
| + pointer-events: none;
|
| + overflow: hidden;
|
| + top: 0;
|
| + left: 0;
|
| + bottom: 0;
|
| + right: 0;
|
| + ''');
|
| +
|
| + static Style _splashStyle = new Style('''
|
| + position: absolute;
|
| + background-color: rgba(0, 0, 0, 0.4);
|
| + border-radius: 0;
|
| + top: 0;
|
| + left: 0;
|
| + height: 0;
|
| + width: 0;
|
| + ''');
|
| +
|
| + double _offsetX;
|
| + double _offsetY;
|
| + String _inlineStyle;
|
| +
|
| + InkSplash(Stream<String> onStyleChanged)
|
| + : onStyleChanged = onStyleChanged,
|
| + super(stateful: true, key: onStyleChanged.hashCode);
|
| +
|
| + bool _listening = false;
|
| +
|
| + void _ensureListening() {
|
| + if (_listening)
|
| + return;
|
| +
|
| + _listening = true;
|
| +
|
| + onStyleChanged.listen((style) {
|
| + setState(() {
|
| + _inlineStyle = style;
|
| + });
|
| + });
|
| + }
|
| +
|
| + Node render() {
|
| + _ensureListening();
|
| +
|
| + return new Container(
|
| + style: _style,
|
| + children: [
|
| + new Container(
|
| + inlineStyle: _inlineStyle,
|
| + style: _splashStyle
|
| + )
|
| + ]
|
| + );
|
| + }
|
| +}
|
|
|