| Index: sky/sdk/lib/animation/animation_performance.dart
|
| diff --git a/sky/sdk/lib/animation/animation_performance.dart b/sky/sdk/lib/animation/animation_performance.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c730d8011cb5128856d95f2f743b9829c5d70a45
|
| --- /dev/null
|
| +++ b/sky/sdk/lib/animation/animation_performance.dart
|
| @@ -0,0 +1,89 @@
|
| +// 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 'animated_value.dart';
|
| +import 'curves.dart';
|
| +
|
| +// TODO(mpcomplete): merge this stuff with AnimatedValue somehow. We shouldn't
|
| +// have 2 different ways to animate values.
|
| +abstract class AnimatedVariable {
|
| + void setFraction(double t);
|
| +}
|
| +
|
| +class AnimatedType<T> extends AnimatedVariable {
|
| + T value;
|
| + final T begin, end;
|
| + final Curve curve;
|
| +
|
| + AnimatedType(this.begin, this.end, {this.curve: linear}) {
|
| + value = begin;
|
| + }
|
| +
|
| + void setFraction(double t) {
|
| + // TODO(mpcomplete): Reverse the timeline and curve.
|
| + value = begin + (end - begin) * curve.transform(t);
|
| + }
|
| +}
|
| +
|
| +// This class manages a "performance" - a collection of values that change
|
| +// based on a timeline. For example, a performance may handle an animation
|
| +// of a menu opening by sliding and fading in (changing Y value and opacity)
|
| +// over .5 seconds. The performance can move forwards (present) or backwards
|
| +// (dismiss). A consumer may also take direct control of the timeline by
|
| +// manipulating |progress|, or |fling| the timeline causing a physics-based
|
| +// simulation to take over the progression.
|
| +class AnimationPerformance {
|
| + // TODO(mpcomplete): make this a list, or composable somehow.
|
| + AnimatedVariable variable;
|
| + // Advances from 0 to 1. On each tick, we'll update our variable's values.
|
| + AnimatedValue timeline = new AnimatedValue(0.0);
|
| + // TODO(mpcomplete): duration should be on a director.
|
| + Duration duration;
|
| +
|
| + AnimationPerformance() {
|
| + timeline.onValueChanged.listen((double t) {
|
| + variable.setFraction(t);
|
| + });
|
| + }
|
| +
|
| + double get progress => timeline.value;
|
| + void set progress(double t) {
|
| + stop();
|
| + timeline.value = t.clamp(0.0, 1.0);
|
| + }
|
| +
|
| + bool get isDismissed => progress == 0.0;
|
| + bool get isCompleted => progress == 1.0;
|
| + bool get isAnimating => timeline.isAnimating;
|
| +
|
| + void play() {
|
| + _animateTo(1.0);
|
| + }
|
| + void reverse() {
|
| + _animateTo(0.0);
|
| + }
|
| +
|
| + void _animateTo(double target) {
|
| + double remainingDistance = (target - timeline.value).abs();
|
| + timeline.stop();
|
| + if (remainingDistance != 0.0)
|
| + timeline.animateTo(target, remainingDistance * duration.inMilliseconds);
|
| + }
|
| +
|
| + void stop() {
|
| + timeline.stop();
|
| + }
|
| +
|
| + // Resume animating in a direction, with the given velocity.
|
| + // TODO(mpcomplete): this should be a force with friction so it slows over
|
| + // time.
|
| + void fling({double velocity: 1.0}) {
|
| + double target = velocity.sign < 0.0 ? 0.0 : 1.0;
|
| + double distance = (target - timeline.value).abs();
|
| + double duration = distance / velocity.abs();
|
| +
|
| + if (distance > 0.0)
|
| + timeline.animateTo(target, duration, curve: linear);
|
| + }
|
| +}
|
|
|