radial_reaction.dart 3.03 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:sky' as sky;
import 'dart:sky' show Point, Offset, Color, Paint;

9
import 'package:sky/animation.dart';
10 11 12 13 14 15 16 17 18 19 20

const Duration _kShowDuration = const Duration(milliseconds: 300);
const Duration _kHideDuration = const Duration(milliseconds: 200);
const Color _kOuterColor = const Color(0xFFFFFFFF);
const Color _kInnerColor = const Color(0xFFFFFFFF);
const double _kMaxOpacity = 0.2;

int _roundOpacity(double opacity) {
  return (255 * opacity).round();
}

21 22 23
/// A material design radial ink reaction
///
/// See [https://www.google.com/design/spec/animation/responsive-interaction.html#responsive-interaction-radial-action]
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
class RadialReaction {
  RadialReaction({
    this.center,
    this.radius,
    Point startPosition
  }) {
    _outerOpacity = new AnimatedValue<double>(0.0, end: _kMaxOpacity, curve: easeOut);
    _innerCenter = new AnimatedValue<Point>(startPosition, end: center, curve: easeOut);
    _innerRadius = new AnimatedValue<double>(0.0, end: radius, curve: easeOut);
    _showPerformance = new AnimationPerformance()
      ..addVariable(_outerOpacity)
      ..addVariable(_innerCenter)
      ..addVariable(_innerRadius)
      ..duration = _kShowDuration;

    _fade = new AnimatedValue(1.0, end: 0.0, curve: easeIn);
    _hidePerformance = new AnimationPerformance()
      ..addVariable(_fade)
      ..duration =_kHideDuration;
  }

45
  /// The center of the circle in which the reaction occurs
46
  final Point center;
47 48

  /// The radius of the circle in which the reaction occurs
49 50 51 52 53 54 55 56 57 58 59 60
  final double radius;

  AnimationPerformance _showPerformance;
  AnimatedValue<double> _outerOpacity;
  AnimatedValue<Point> _innerCenter;
  AnimatedValue<double> _innerRadius;

  Future _showComplete;

  AnimationPerformance _hidePerformance;
  AnimatedValue<double> _fade;

61 62 63 64 65
  /// Show the reaction
  ///
  /// Returns a future that resolves when the reaction is completely revealed.
  Future show() {
    return _showComplete = _showPerformance.forward();
66 67
  }

68 69 70
  /// Hide the reaction
  ///
  /// Returns a future that resolves when the reaction is completely hidden.
71 72 73 74 75
  Future hide() async {
    await _showComplete;
    await _hidePerformance.forward();
  }

76
  /// Call listener whenever the visual appearance of the reaction changes
77 78 79 80 81 82 83 84
  void addListener(Function listener) {
    _showPerformance.addListener(listener);
    _hidePerformance.addListener(listener);
  }

  final Paint _outerPaint = new Paint();
  final Paint _innerPaint = new Paint();

85
  /// Paint the reaction onto the given canvas at the given offset
86 87 88 89 90 91 92 93
  void paint(sky.Canvas canvas, Offset offset) {
    _outerPaint.color = _kOuterColor.withAlpha(_roundOpacity(_outerOpacity.value * _fade.value));
    canvas.drawCircle(center + offset, radius, _outerPaint);

    _innerPaint.color = _kInnerColor.withAlpha(_roundOpacity(_kMaxOpacity  * _fade.value));
    canvas.drawCircle(_innerCenter.value + offset, _innerRadius.value, _innerPaint);
  }
}