flutter/packages/flutter/lib/src/animation/simulation_stepper.dart
Adam Barth 5cb0010085 Remove AnimatedSimulation
This patch folds the functionality from AnimatedSimulation into Timeline.
2015-10-05 10:13:11 -07:00

106 lines
3.2 KiB
Dart

// 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 'package:newton/newton.dart';
import 'package:sky/src/animation/animated_value.dart';
import 'package:sky/src/animation/curves.dart';
import 'package:sky/src/animation/ticker.dart';
/// 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 {
_TweenSimulation(double begin, double end, Duration duration, Curve curve)
: _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);
_tween.setProgress(t, Direction.forward);
return _tween.value;
}
double dx(double timeInSeconds) => 1.0;
bool isDone(double timeInSeconds) => timeInSeconds > _durationInSeconds;
}
typedef TimelineCallback(double value);
/// Steps a simulation one per frame
class SimulationStepper {
SimulationStepper(TimelineCallback onTick) : _onTick = onTick {
_ticker = new Ticker(_tick);
}
final TimelineCallback _onTick;
Ticker _ticker;
Simulation _simulation;
/// The current value of the timeline
double get value => _value;
double _value = 0.0;
void set value(double newValue) {
assert(newValue != null);
assert(!isAnimating);
_value = newValue;
_onTick(_value);
}
/// Whether the timeline is currently animating
bool get isAnimating => _ticker.isTicking;
/// Animate value of the timeline to the given target over the given duration
///
/// Returns a future that resolves when the timeline stops animating,
/// typically when the timeline arives at the target value.
Future animateTo(double target, { Duration duration, Curve curve: linear }) {
assert(duration > Duration.ZERO);
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() {
_simulation = null;
_ticker.stop();
}
void _tick(Duration elapsed) {
double elapsedInSeconds = elapsed.inMicroseconds.toDouble() / Duration.MICROSECONDS_PER_SECOND;
_value = _simulation.x(elapsedInSeconds);
if (_simulation.isDone(elapsedInSeconds))
stop();
_onTick(_value);
}
}