Chromium Code Reviews| Index: sky/sdk/lib/animation/timeline.dart |
| diff --git a/sky/sdk/lib/animation/timeline.dart b/sky/sdk/lib/animation/timeline.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4ec1b060896c1a18eae397da2d741868efcf4296 |
| --- /dev/null |
| +++ b/sky/sdk/lib/animation/timeline.dart |
| @@ -0,0 +1,160 @@ |
| +// 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 '../base/scheduler.dart' as scheduler; |
| +import 'curves.dart'; |
| + |
| +class Ticker { |
| + Ticker(Function onTick) : _onTick = onTick; |
| + |
| + final Function _onTick; |
| + |
| + Completer _completer; |
| + int _animationId; |
| + |
| + Future start() { |
| + assert(!isTicking); |
| + _completer = new Completer(); |
| + _scheduleTick(); |
| + return _completer.future; |
| + } |
| + |
| + 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(); |
| + } |
| + |
| + bool get isTicking => _completer != null; |
| + |
| + void _tick(double timeStamp) { |
| + assert(isTicking); |
| + assert(_animationId != null); |
| + _animationId = null; |
| + |
| + _onTick(timeStamp); |
| + |
| + if (isTicking) |
| + _scheduleTick(); |
| + } |
| + |
| + void _scheduleTick() { |
| + assert(isTicking); |
| + assert(_animationId == null); |
| + _animationId = scheduler.requestAnimationFrame(_tick); |
| + } |
| +} |
| + |
| +class Timeline { |
| + |
| + Timeline(Function onTick, { double initialValue: 0.0 }) |
| + : _onTick = onTick, _value = initialValue { |
| + _ticker = new Ticker(_tick); |
| + } |
| + |
| + final Function _onTick; |
| + Ticker _ticker; |
| + |
| + double _value; |
| + double get value => _value; |
| + void set value(double newValue) { |
| + assert(newValue != null); |
| + assert(!_ticker.isTicking); |
| + _value = newValue; |
| + _onTick(_value); |
| + } |
| + |
| + double _initialDelay; |
| + double _duration; |
| + double _begin; |
| + double _end; |
| + Curve _curve; |
|
Matt Perry
2015/07/09 17:38:08
This class seems overly complicated to me. If it's
abarth-chromium
2015/07/09 17:48:30
Ok. I'll remove that functionality.
|
| + |
| + double _startTime; |
| + double _t; |
| + |
| + Future start({ |
| + double initialDelay: 0.0, |
| + double duration, |
| + double begin: 0.0, |
| + double end: 1.0, |
| + Curve curve: linear |
| + }) { |
| + assert(initialDelay != null); |
| + assert(duration != null && duration > 0.0); |
| + assert(begin != null); |
| + assert(end != null); |
| + assert(curve != null); |
| + |
| + assert(!_ticker.isTicking); |
| + |
| + _initialDelay = initialDelay; |
| + _duration = duration; |
| + _begin = begin; |
| + _end = end; |
| + _curve = curve; |
| + |
| + _startTime = null; |
| + _t = 0.0; |
| + _value = begin; |
| + |
| + return _ticker.start(); |
| + } |
| + |
| + Future animateTo(double target, { |
| + double initialDelay: 0.0, |
| + double duration, |
| + Curve curve: linear |
| + }) { |
| + return start(initialDelay: initialDelay, |
| + duration: duration, |
| + begin: _value, |
| + end: target, |
| + curve: curve); |
| + } |
| + |
| + void stop() { |
| + _initialDelay = null; |
| + _duration = null; |
| + _begin = null; |
| + _end = null; |
| + _curve = null; |
| + |
| + _startTime = null; |
| + _t = null; |
| + |
| + _ticker.stop(); |
| + } |
| + |
| + bool get isAnimating => _t != null; |
| + |
| + void _tick(double timeStamp) { |
| + if (_startTime == null) |
| + _startTime = timeStamp; |
| + |
| + _t = ((timeStamp - (_startTime + _initialDelay)) / _duration).clamp(0.0, 1.0); |
| + |
| + final bool isLastTick = _t >= 1.0; |
| + |
| + _value = isLastTick ? _end : _begin + (_end - _begin) * _curve.transform(_t); |
| + _onTick(_value); |
| + |
| + if (isLastTick) |
| + stop(); |
| + } |
| +} |