Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1002)

Unified Diff: sky/sdk/lib/animation/timeline.dart

Issue 1233653003: Add support for "flinging" the animation timeline with a spring force. So far, (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: . Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/sdk/lib/animation/animation_performance.dart ('k') | sky/sdk/lib/widgets/dismissable.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/lib/animation/timeline.dart
diff --git a/sky/sdk/lib/animation/timeline.dart b/sky/sdk/lib/animation/timeline.dart
index a0be4537a1151585fdbf370b5be398c8de8801e8..607cb6d4ca9f35f8f1b973951a0219d663eb4cac 100644
--- a/sky/sdk/lib/animation/timeline.dart
+++ b/sky/sdk/lib/animation/timeline.dart
@@ -4,131 +4,88 @@
import 'dart:async';
-import 'package:sky/base/scheduler.dart' as scheduler;
+import 'package:newton/newton.dart';
+import 'package:sky/animation/animated_simulation.dart';
-class Ticker {
- Ticker(Function onTick) : _onTick = onTick;
+const double _kEpsilon = 0.001;
- final Function _onTick;
-
- Completer _completer;
- int _animationId;
+// Simple simulation that linearly varies from |begin| to |end| over |duration|.
+class TweenSimulation extends Simulation {
+ final double _durationInSeconds;
+ final double begin;
+ final double end;
- Future start() {
- assert(!isTicking);
- _completer = new Completer();
- _scheduleTick();
- return _completer.future;
+ TweenSimulation(Duration duration, this.begin, this.end) :
+ _durationInSeconds = duration.inMilliseconds / 1000.0 {
+ assert(_durationInSeconds > 0.0);
+ assert(begin != null && begin >= 0.0 && begin <= 1.0);
+ assert(end != null && end >= 0.0 && end <= 1.0);
}
- void stop() {
- if (!isTicking)
- return;
-
- if (_animationId != null) {
- scheduler.cancelAnimationFrame(_animationId);
- _animationId = null;
- }
-
- Completer localCompleter = _completer;
- _completer = null;
-
- // We take the _completer into a local variable so that !isTicking when we
- // actually complete the future.
- assert(!isTicking);
- localCompleter.complete();
+ double x(double timeInSeconds) {
+ assert(timeInSeconds >= 0.0);
+ final double t = timeInSeconds / _durationInSeconds;
+ return t >= 1.0 ? end : begin + (end - begin) * t;
}
- bool get isTicking => _completer != null;
-
- void _tick(double timeStamp) {
- assert(isTicking);
- assert(_animationId != null);
- _animationId = null;
-
- _onTick(timeStamp);
-
- if (isTicking)
- _scheduleTick();
- }
+ double dx(double timeInSeconds) => 1.0;
- void _scheduleTick() {
- assert(isTicking);
- assert(_animationId == null);
- _animationId = scheduler.requestAnimationFrame(_tick);
- }
+ bool isDone(double timeInSeconds) => timeInSeconds > _durationInSeconds;
}
class Timeline {
-
Timeline(Function onTick) : _onTick = onTick {
- _ticker = new Ticker(_tick);
+ _animation = new AnimatedSimulation(_tick);
}
final Function _onTick;
- Ticker _ticker;
+ AnimatedSimulation _animation;
- double _value = 0.0;
- double get value => _value;
+ double get value => _animation.value.clamp(0.0, 1.0);
void set value(double newValue) {
assert(newValue != null && newValue >= 0.0 && newValue <= 1.0);
- assert(!_ticker.isTicking);
- _value = newValue;
- _onTick(_value);
+ assert(!isAnimating);
+ _animation.value = newValue;
}
- double _duration;
- double _begin;
- double _end;
-
- double _startTime;
+ bool get isAnimating => _animation.isAnimating;
- Future start({
- double duration,
+ Future _start({
+ Duration duration,
double begin: 0.0,
double end: 1.0
}) {
- assert(duration != null && duration > 0.0);
- assert(begin != null && begin >= 0.0 && begin <= 1.0);
- assert(end != null && end >= 0.0 && end <= 1.0);
-
- assert(!_ticker.isTicking);
+ assert(!_animation.isAnimating);
- _duration = duration;
- _begin = begin;
- _end = end;
-
- _startTime = null;
- _value = begin;
-
- return _ticker.start();
+ return _animation.start(new TweenSimulation(duration, begin, end));
}
- Future animateTo(double target, { double duration }) {
- return start(duration: duration, begin: _value, end: target);
+ Future animateTo(double target, { Duration duration }) {
+ return _start(duration: duration, begin: value, end: target);
}
void stop() {
- _duration = null;
- _begin = null;
- _end = null;
- _startTime = null;
- _ticker.stop();
+ _animation.stop();
}
- bool get isAnimating => _ticker.isTicking;
-
- void _tick(double timeStamp) {
- if (_startTime == null)
- _startTime = timeStamp;
+ static final SpringDescription _kDefaultSpringDesc =
+ new SpringDescription.withDampingRatio(
+ mass: 1.0, springConstant: 500.0, ratio: 1.0);
- final double t = ((timeStamp - _startTime) / _duration).clamp(0.0, 1.0);
- final bool isLastTick = t >= 1.0;
+ Simulation defaultSpringSimulation({double velocity: 0.0}) {
+ // Target just past the 0 or 1 endpoint, because the animation will stop
+ // once the Spring gets within the epsilon, and we want to stop at 0 or 1.
+ double target = velocity < 0.0 ? -_kEpsilon : 1.0 + _kEpsilon;
+ return new SpringSimulation(_kDefaultSpringDesc, value, target, velocity);
+ }
- _value = isLastTick ? _end : _begin + (_end - _begin) * t;
- _onTick(_value);
+ // Give |simulation| control over the timeline.
+ Future fling(Simulation simulation) {
+ stop();
+ return _animation.start(simulation);
+ }
- if (isLastTick)
- stop();
+ void _tick(double newValue) {
+ _onTick(value);
}
}
« no previous file with comments | « sky/sdk/lib/animation/animation_performance.dart ('k') | sky/sdk/lib/widgets/dismissable.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698