Merge pull request #1480 from abarth/rm_animated_simulation
Remove AnimatedSimulation
This commit is contained in:
commit
041cd88d14
@ -7,7 +7,6 @@
|
|||||||
/// This library depends only on core Dart libraries and the `newton` package.
|
/// This library depends only on core Dart libraries and the `newton` package.
|
||||||
library animation;
|
library animation;
|
||||||
|
|
||||||
export 'src/animation/animated_simulation.dart';
|
|
||||||
export 'src/animation/animated_value.dart';
|
export 'src/animation/animated_value.dart';
|
||||||
export 'src/animation/animation_performance.dart';
|
export 'src/animation/animation_performance.dart';
|
||||||
export 'src/animation/clamped_simulation.dart';
|
export 'src/animation/clamped_simulation.dart';
|
||||||
@ -15,4 +14,5 @@ export 'src/animation/curves.dart';
|
|||||||
export 'src/animation/forces.dart';
|
export 'src/animation/forces.dart';
|
||||||
export 'src/animation/scheduler.dart';
|
export 'src/animation/scheduler.dart';
|
||||||
export 'src/animation/scroll_behavior.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/animated_value.dart';
|
||||||
import 'package:sky/src/animation/forces.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
|
/// The status of an animation
|
||||||
enum AnimationStatus {
|
enum AnimationStatus {
|
||||||
@ -53,7 +53,7 @@ abstract class WatchableAnimationPerformance {
|
|||||||
/// progression.
|
/// progression.
|
||||||
class AnimationPerformance implements WatchableAnimationPerformance {
|
class AnimationPerformance implements WatchableAnimationPerformance {
|
||||||
AnimationPerformance({ this.duration, double progress }) {
|
AnimationPerformance({ this.duration, double progress }) {
|
||||||
_timeline = new Timeline(_tick);
|
_timeline = new SimulationStepper(_tick);
|
||||||
if (progress != null)
|
if (progress != null)
|
||||||
_timeline.value = progress.clamp(0.0, 1.0);
|
_timeline.value = progress.clamp(0.0, 1.0);
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ class AnimationPerformance implements WatchableAnimationPerformance {
|
|||||||
/// The length of time this performance should last
|
/// The length of time this performance should last
|
||||||
Duration duration;
|
Duration duration;
|
||||||
|
|
||||||
Timeline _timeline;
|
SimulationStepper _timeline;
|
||||||
Direction _direction;
|
Direction _direction;
|
||||||
|
|
||||||
/// The direction used to select the current curve
|
/// The direction used to select the current curve
|
||||||
@ -159,7 +159,7 @@ class AnimationPerformance implements WatchableAnimationPerformance {
|
|||||||
if (force == null)
|
if (force == null)
|
||||||
force = kDefaultSpringForce;
|
force = kDefaultSpringForce;
|
||||||
_direction = velocity < 0.0 ? Direction.reverse : Direction.forward;
|
_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>();
|
final List<AnimationPerformanceListener> _listeners = new List<AnimationPerformanceListener>();
|
||||||
|
@ -5,23 +5,26 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:newton/newton.dart';
|
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_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 {
|
class _TweenSimulation extends Simulation {
|
||||||
final double _durationInSeconds;
|
|
||||||
final AnimatedValue<double> _tween;
|
|
||||||
|
|
||||||
_TweenSimulation(double begin, double end, Duration duration, Curve curve)
|
_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) {
|
_tween = new AnimatedValue<double>(begin, end: end, curve: curve) {
|
||||||
assert(_durationInSeconds > 0.0);
|
assert(_durationInSeconds > 0.0);
|
||||||
assert(begin != null);
|
assert(begin != null);
|
||||||
assert(end != null);
|
assert(end != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final double _durationInSeconds;
|
||||||
|
final AnimatedValue<double> _tween;
|
||||||
|
|
||||||
double x(double timeInSeconds) {
|
double x(double timeInSeconds) {
|
||||||
assert(timeInSeconds >= 0.0);
|
assert(timeInSeconds >= 0.0);
|
||||||
final double t = (timeInSeconds / _durationInSeconds).clamp(0.0, 1.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;
|
bool isDone(double timeInSeconds) => timeInSeconds > _durationInSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A timeline for an animation
|
typedef TimelineCallback(double value);
|
||||||
class Timeline {
|
|
||||||
Timeline(Function onTick) {
|
/// Steps a simulation one per frame
|
||||||
_animation = new AnimatedSimulation(onTick);
|
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
|
/// The current value of the timeline
|
||||||
double get value => _animation.value;
|
double get value => _value;
|
||||||
|
double _value = 0.0;
|
||||||
void set value(double newValue) {
|
void set value(double newValue) {
|
||||||
assert(newValue != null);
|
assert(newValue != null);
|
||||||
assert(!isAnimating);
|
assert(!isAnimating);
|
||||||
_animation.value = newValue;
|
_value = newValue;
|
||||||
|
_onTick(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the timeline is currently animating
|
/// 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
|
/// 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.
|
/// typically when the timeline arives at the target value.
|
||||||
Future animateTo(double target, { Duration duration, Curve curve: linear }) {
|
Future animateTo(double target, { Duration duration, Curve curve: linear }) {
|
||||||
assert(duration > Duration.ZERO);
|
assert(duration > Duration.ZERO);
|
||||||
assert(!_animation.isAnimating);
|
assert(!isAnimating);
|
||||||
return _animation.start(new _TweenSimulation(value, target, duration, curve));
|
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
|
/// Stop animating the timeline
|
||||||
void stop() {
|
void stop() {
|
||||||
_animation.stop();
|
_simulation = null;
|
||||||
|
_ticker.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gives the given simulation control over the timeline
|
void _tick(Duration elapsed) {
|
||||||
Future fling(Simulation simulation) {
|
double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND;
|
||||||
stop();
|
_value = _simulation.x(elapsedInSeconds);
|
||||||
return _animation.start(simulation);
|
if (_simulation.isDone(elapsedInSeconds))
|
||||||
|
stop();
|
||||||
|
_onTick(_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,17 +4,16 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:newton/newton.dart';
|
|
||||||
import 'package:sky/src/animation/scheduler.dart';
|
import 'package:sky/src/animation/scheduler.dart';
|
||||||
|
|
||||||
typedef _TickerCallback(Duration elapsed);
|
typedef TickerCallback(Duration elapsed);
|
||||||
|
|
||||||
/// Calls its callback once per animation frame
|
/// Calls its callback once per animation frame
|
||||||
class Ticker {
|
class Ticker {
|
||||||
/// Constructs a ticker that will call onTick once per frame while running
|
/// 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;
|
Completer _completer;
|
||||||
int _animationId;
|
int _animationId;
|
||||||
@ -45,7 +44,7 @@ class Ticker {
|
|||||||
_animationId = null;
|
_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
|
// when we actually complete the future (isTicking uses _completer
|
||||||
// to determine its state).
|
// to determine its state).
|
||||||
Completer localCompleter = _completer;
|
Completer localCompleter = _completer;
|
||||||
@ -78,57 +77,3 @@ class Ticker {
|
|||||||
_animationId = scheduler.requestAnimationFrame(_tick);
|
_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();
|
super.initState();
|
||||||
if (config.initialScrollOffset is double)
|
if (config.initialScrollOffset is double)
|
||||||
_scrollOffset = config.initialScrollOffset;
|
_scrollOffset = config.initialScrollOffset;
|
||||||
_animation = new Timeline(_setScrollOffset);
|
_animation = new SimulationStepper(_setScrollOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline _animation;
|
SimulationStepper _animation;
|
||||||
|
|
||||||
double _scrollOffset = 0.0;
|
double _scrollOffset = 0.0;
|
||||||
double get scrollOffset => _scrollOffset;
|
double get scrollOffset => _scrollOffset;
|
||||||
@ -151,7 +151,7 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
|
|||||||
_createSnapSimulation(velocity) ?? _createFlingSimulation(velocity ?? 0.0);
|
_createSnapSimulation(velocity) ?? _createFlingSimulation(velocity ?? 0.0);
|
||||||
if (simulation == null)
|
if (simulation == null)
|
||||||
return new Future.value();
|
return new Future.value();
|
||||||
return _animation.fling(simulation);
|
return _animation.animateWith(simulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -13,7 +13,6 @@ import 'package:sky/painting.dart';
|
|||||||
import 'package:sky/rendering.dart';
|
import 'package:sky/rendering.dart';
|
||||||
import 'package:sky/src/widgets/basic.dart';
|
import 'package:sky/src/widgets/basic.dart';
|
||||||
import 'package:sky/src/widgets/framework.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/icon.dart';
|
||||||
import 'package:sky/src/widgets/ink_well.dart';
|
import 'package:sky/src/widgets/ink_well.dart';
|
||||||
import 'package:sky/src/widgets/scrollable.dart';
|
import 'package:sky/src/widgets/scrollable.dart';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user