From 5cb0010085f8b59122b15df4243268b87e77b8e1 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Sat, 3 Oct 2015 14:59:48 -0700 Subject: [PATCH] Remove AnimatedSimulation This patch folds the functionality from AnimatedSimulation into Timeline. --- packages/flutter/lib/animation.dart | 4 +- .../src/animation/animation_performance.dart | 8 +- ...{timeline.dart => simulation_stepper.dart} | 73 +++++++++++++------ .../{animated_simulation.dart => ticker.dart} | 63 +--------------- .../flutter/lib/src/widgets/scrollable.dart | 6 +- packages/flutter/lib/src/widgets/tabs.dart | 1 - 6 files changed, 64 insertions(+), 91 deletions(-) rename packages/flutter/lib/src/animation/{timeline.dart => simulation_stepper.dart} (52%) rename packages/flutter/lib/src/animation/{animated_simulation.dart => ticker.dart} (55%) diff --git a/packages/flutter/lib/animation.dart b/packages/flutter/lib/animation.dart index f35b2538bb..564f8cdae4 100644 --- a/packages/flutter/lib/animation.dart +++ b/packages/flutter/lib/animation.dart @@ -7,7 +7,6 @@ /// This library depends only on core Dart libraries and the `newton` package. library animation; -export 'src/animation/animated_simulation.dart'; export 'src/animation/animated_value.dart'; export 'src/animation/animation_performance.dart'; export 'src/animation/clamped_simulation.dart'; @@ -15,4 +14,5 @@ export 'src/animation/curves.dart'; export 'src/animation/forces.dart'; export 'src/animation/scheduler.dart'; export 'src/animation/scroll_behavior.dart'; -export 'src/animation/timeline.dart'; +export 'src/animation/simulation_stepper.dart'; +export 'src/animation/ticker.dart'; diff --git a/packages/flutter/lib/src/animation/animation_performance.dart b/packages/flutter/lib/src/animation/animation_performance.dart index 8111754442..a3340d4cc9 100644 --- a/packages/flutter/lib/src/animation/animation_performance.dart +++ b/packages/flutter/lib/src/animation/animation_performance.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'package:sky/src/animation/animated_value.dart'; import 'package:sky/src/animation/forces.dart'; -import 'package:sky/src/animation/timeline.dart'; +import 'package:sky/src/animation/simulation_stepper.dart'; /// The status of an animation enum AnimationStatus { @@ -53,7 +53,7 @@ abstract class WatchableAnimationPerformance { /// progression. class AnimationPerformance implements WatchableAnimationPerformance { AnimationPerformance({ this.duration, double progress }) { - _timeline = new Timeline(_tick); + _timeline = new SimulationStepper(_tick); if (progress != null) _timeline.value = progress.clamp(0.0, 1.0); } @@ -66,7 +66,7 @@ class AnimationPerformance implements WatchableAnimationPerformance { /// The length of time this performance should last Duration duration; - Timeline _timeline; + SimulationStepper _timeline; Direction _direction; /// The direction used to select the current curve @@ -159,7 +159,7 @@ class AnimationPerformance implements WatchableAnimationPerformance { if (force == null) force = kDefaultSpringForce; _direction = velocity < 0.0 ? Direction.reverse : Direction.forward; - return _timeline.fling(force.release(progress, velocity)); + return _timeline.animateWith(force.release(progress, velocity)); } final List _listeners = new List(); diff --git a/packages/flutter/lib/src/animation/timeline.dart b/packages/flutter/lib/src/animation/simulation_stepper.dart similarity index 52% rename from packages/flutter/lib/src/animation/timeline.dart rename to packages/flutter/lib/src/animation/simulation_stepper.dart index 29005c75f5..39ff00c4e8 100644 --- a/packages/flutter/lib/src/animation/timeline.dart +++ b/packages/flutter/lib/src/animation/simulation_stepper.dart @@ -5,23 +5,26 @@ import 'dart:async'; import 'package:newton/newton.dart'; -import 'package:sky/src/animation/curves.dart'; import 'package:sky/src/animation/animated_value.dart'; -import 'package:sky/src/animation/animated_simulation.dart'; +import 'package:sky/src/animation/curves.dart'; +import 'package:sky/src/animation/ticker.dart'; -/// A simulation that linearly varies from [begin] to [end] over [duration] +/// A simulation that varies from [begin] to [end] over [duration] using [curve] +/// +/// This class is an adaptor between the Simulation interface and the +/// AnimatedValue interface. class _TweenSimulation extends Simulation { - final double _durationInSeconds; - final AnimatedValue _tween; - _TweenSimulation(double begin, double end, Duration duration, Curve curve) - : _durationInSeconds = duration.inMicroseconds / Duration.MICROSECONDS_PER_SECOND, + : _durationInSeconds = duration.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND, _tween = new AnimatedValue(begin, end: end, curve: curve) { assert(_durationInSeconds > 0.0); assert(begin != null); assert(end != null); } + final double _durationInSeconds; + final AnimatedValue _tween; + double x(double timeInSeconds) { assert(timeInSeconds >= 0.0); final double t = (timeInSeconds / _durationInSeconds).clamp(0.0, 1.0); @@ -34,24 +37,30 @@ class _TweenSimulation extends Simulation { bool isDone(double timeInSeconds) => timeInSeconds > _durationInSeconds; } -/// A timeline for an animation -class Timeline { - Timeline(Function onTick) { - _animation = new AnimatedSimulation(onTick); +typedef TimelineCallback(double value); + +/// Steps a simulation one per frame +class SimulationStepper { + SimulationStepper(TimelineCallback onTick) : _onTick = onTick { + _ticker = new Ticker(_tick); } - AnimatedSimulation _animation; + final TimelineCallback _onTick; + Ticker _ticker; + Simulation _simulation; /// The current value of the timeline - double get value => _animation.value; + double get value => _value; + double _value = 0.0; void set value(double newValue) { assert(newValue != null); assert(!isAnimating); - _animation.value = newValue; + _value = newValue; + _onTick(_value); } /// Whether the timeline is currently animating - bool get isAnimating => _animation.isAnimating; + bool get isAnimating => _ticker.isTicking; /// Animate value of the timeline to the given target over the given duration /// @@ -59,18 +68,38 @@ class Timeline { /// typically when the timeline arives at the target value. Future animateTo(double target, { Duration duration, Curve curve: linear }) { assert(duration > Duration.ZERO); - assert(!_animation.isAnimating); - return _animation.start(new _TweenSimulation(value, target, duration, curve)); + assert(!isAnimating); + return _start(new _TweenSimulation(value, target, duration, curve)); + } + + /// Gives the given simulation control over the timeline + Future animateWith(Simulation simulation) { + stop(); + return _start(simulation); + } + + /// Start ticking the given simulation once per frame + /// + /// Returns a future that resolves when the simulation stops ticking. + Future _start(Simulation simulation) { + assert(simulation != null); + assert(!isAnimating); + _simulation = simulation; + _value = simulation.x(0.0); + return _ticker.start(); } /// Stop animating the timeline void stop() { - _animation.stop(); + _simulation = null; + _ticker.stop(); } - /// Gives the given simulation control over the timeline - Future fling(Simulation simulation) { - stop(); - return _animation.start(simulation); + void _tick(Duration elapsed) { + double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND; + _value = _simulation.x(elapsedInSeconds); + if (_simulation.isDone(elapsedInSeconds)) + stop(); + _onTick(_value); } } diff --git a/packages/flutter/lib/src/animation/animated_simulation.dart b/packages/flutter/lib/src/animation/ticker.dart similarity index 55% rename from packages/flutter/lib/src/animation/animated_simulation.dart rename to packages/flutter/lib/src/animation/ticker.dart index 32f0a91aa7..6c0dd32eb0 100644 --- a/packages/flutter/lib/src/animation/animated_simulation.dart +++ b/packages/flutter/lib/src/animation/ticker.dart @@ -4,17 +4,16 @@ import 'dart:async'; -import 'package:newton/newton.dart'; import 'package:sky/src/animation/scheduler.dart'; -typedef _TickerCallback(Duration elapsed); +typedef TickerCallback(Duration elapsed); /// Calls its callback once per animation frame class Ticker { /// Constructs a ticker that will call onTick once per frame while running - Ticker(_TickerCallback onTick) : _onTick = onTick; + Ticker(TickerCallback onTick) : _onTick = onTick; - final _TickerCallback _onTick; + final TickerCallback _onTick; Completer _completer; int _animationId; @@ -45,7 +44,7 @@ class Ticker { _animationId = null; } - // We take the _completer into a local variable so that !isTicking + // We take the _completer into a local variable so that isTicking is false // when we actually complete the future (isTicking uses _completer // to determine its state). Completer localCompleter = _completer; @@ -78,57 +77,3 @@ class Ticker { _animationId = scheduler.requestAnimationFrame(_tick); } } - -/// Ticks a simulation once per frame -class AnimatedSimulation { - - AnimatedSimulation(Function onTick) : _onTick = onTick { - _ticker = new Ticker(_tick); - } - - final Function _onTick; - Ticker _ticker; - - Simulation _simulation; - - double _value = 0.0; - /// The current value of the simulation - double get value => _value; - void set value(double newValue) { - assert(!_ticker.isTicking); - _value = newValue; - _onTick(_value); - } - - /// Start ticking the given simulation once per frame - /// - /// Returns a future that resolves when the simulation stops ticking. - Future start(Simulation simulation) { - assert(simulation != null); - assert(!_ticker.isTicking); - _simulation = simulation; - _value = simulation.x(0.0); - return _ticker.start(); - } - - /// Stop ticking the current simulation - void stop() { - _simulation = null; - _ticker.stop(); - } - - /// Whether this object is currently ticking a simulation - bool get isAnimating => _ticker.isTicking; - - void _tick(Duration elapsed) { - - double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND; - _value = _simulation.x(elapsedInSeconds); - - if (_simulation.isDone(elapsedInSeconds)) - stop(); - - _onTick(_value); - } - -} diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index e09fe4f861..cf1693a4a1 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -51,10 +51,10 @@ abstract class ScrollableState extends State { super.initState(); if (config.initialScrollOffset is double) _scrollOffset = config.initialScrollOffset; - _animation = new Timeline(_setScrollOffset); + _animation = new SimulationStepper(_setScrollOffset); } - Timeline _animation; + SimulationStepper _animation; double _scrollOffset = 0.0; double get scrollOffset => _scrollOffset; @@ -151,7 +151,7 @@ abstract class ScrollableState extends State { _createSnapSimulation(velocity) ?? _createFlingSimulation(velocity ?? 0.0); if (simulation == null) return new Future.value(); - return _animation.fling(simulation); + return _animation.animateWith(simulation); } void dispose() { diff --git a/packages/flutter/lib/src/widgets/tabs.dart b/packages/flutter/lib/src/widgets/tabs.dart index c00bc8ba6f..19b9c6748b 100644 --- a/packages/flutter/lib/src/widgets/tabs.dart +++ b/packages/flutter/lib/src/widgets/tabs.dart @@ -13,7 +13,6 @@ import 'package:sky/painting.dart'; import 'package:sky/rendering.dart'; import 'package:sky/src/widgets/basic.dart'; import 'package:sky/src/widgets/framework.dart'; -import 'package:sky/src/widgets/gesture_detector.dart'; import 'package:sky/src/widgets/icon.dart'; import 'package:sky/src/widgets/ink_well.dart'; import 'package:sky/src/widgets/scrollable.dart';