Commit 5cb00100 authored by Adam Barth's avatar Adam Barth

Remove AnimatedSimulation

This patch folds the functionality from AnimatedSimulation into Timeline.
parent 49aba0cc
......@@ -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';
......@@ -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<AnimationPerformanceListener> _listeners = new List<AnimationPerformanceListener>();
......
......@@ -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<double> _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<double>(begin, end: end, curve: curve) {
assert(_durationInSeconds > 0.0);
assert(begin != null);
assert(end != null);
}
final double _durationInSeconds;
final AnimatedValue<double> _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);
}
}
......@@ -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);
}
}
......@@ -51,10 +51,10 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
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<T extends Scrollable> extends State<T> {
_createSnapSimulation(velocity) ?? _createFlingSimulation(velocity ?? 0.0);
if (simulation == null)
return new Future.value();
return _animation.fling(simulation);
return _animation.animateWith(simulation);
}
void dispose() {
......
......@@ -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';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment