Commit fc978c1a authored by Adam Barth's avatar Adam Barth

Port examples to the new animation API

These now use Animation and AnimationController instead of PerformanceView and
Performance.
parent 477530f3
......@@ -12,21 +12,21 @@ final List<String> _iconNames = <String>["event", "home", "android", "alarm", "f
class TabViewDemo extends StatelessComponent {
Widget _buildTabIndicator(BuildContext context, String iconName) {
final Color color = Theme.of(context).primaryColor;
final AnimatedColorValue _selectedColor = new AnimatedColorValue(Colors.transparent, end: color, curve: Curves.ease);
final AnimatedColorValue _previousColor = new AnimatedColorValue(color, end: Colors.transparent, curve: Curves.ease);
final ColorTween _selectedColor = new ColorTween(begin: Colors.transparent, end: color);
final ColorTween _previousColor = new ColorTween(begin: color, end: Colors.transparent);
final TabBarSelectionState selection = TabBarSelection.of(context);
return new BuilderTransition(
performance: selection.performance,
variables: <AnimatedColorValue>[_selectedColor, _previousColor],
Animation animation = new CurvedAnimation(parent: selection.animation, curve: Curves.ease);
return new AnimationWatchingBuilder(
watchable: animation,
builder: (BuildContext context) {
Color background = selection.value == iconName ? _selectedColor.end : _selectedColor.begin;
if (selection.valueIsChanging) {
// Then the selection's performance is animating from previousValue to value.
if (selection.value == iconName)
background = _selectedColor.value;
background = _selectedColor.evaluate(animation);
else if (selection.previousValue == iconName)
background = _previousColor.value;
background = _previousColor.evaluate(animation);
}
return new Container(
width: 12.0,
......
......@@ -16,7 +16,7 @@ class _ProgressIndicatorAppState extends State<ProgressIndicatorApp> {
duration: const Duration(milliseconds: 1500)
)..play(AnimationDirection.forward);
animation = new ACurve(
animation = new CurvedAnimation(
parent: controller,
curve: new Interval(0.0, 0.9, curve: Curves.ease),
reverseCurve: Curves.ease
......
......@@ -26,29 +26,28 @@ class SmoothBlock extends StatefulComponent {
class CardTransition extends StatelessComponent {
CardTransition({
this.child,
this.performance,
this.animation,
this.x,
this.opacity,
this.scale
});
final Widget child;
final Performance performance;
final AnimatedValue<double> x;
final AnimatedValue<double> opacity;
final AnimatedValue<double> scale;
final Animation animation;
final Evaluatable<double> x;
final Evaluatable<double> opacity;
final Evaluatable<double> scale;
Widget build(BuildContext context) {
return new BuilderTransition(
performance: performance,
variables: <AnimatedValue<double>>[x, opacity, scale],
return new AnimationWatchingBuilder(
watchable: animation,
builder: (BuildContext context) {
double currentScale = scale.evaluate(animation);
Matrix4 transform = new Matrix4.identity()
..translate(x.value)
..scale(scale.value, scale.value);
..translate(x.evaluate(animation))
..scale(currentScale, currentScale);
return new Opacity(
opacity: opacity.value,
opacity: opacity.evaluate(animation),
child: new Transform(
transform: transform,
child: child
......@@ -63,22 +62,22 @@ class SmoothBlockState extends State<SmoothBlock> {
double _height = 100.0;
Widget _handleEnter(PerformanceView performance, Widget child) {
Widget _handleEnter(Animation animation, Widget child) {
return new CardTransition(
x: new AnimatedValue<double>(-200.0, end: 0.0, curve: Curves.ease),
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.ease),
scale: new AnimatedValue<double>(0.8, end: 1.0, curve: Curves.ease),
performance: performance,
x: new Tween<double>(begin: -200.0, end: 0.0),
opacity: new Tween<double>(begin: 0.0, end: 1.0),
scale: new Tween<double>(begin: 0.8, end: 1.0),
animation: new CurvedAnimation(parent: animation, curve: Curves.ease),
child: child
);
}
Widget _handleExit(PerformanceView performance, Widget child) {
Widget _handleExit(Animation animation, Widget child) {
return new CardTransition(
x: new AnimatedValue<double>(0.0, end: 200.0, curve: Curves.ease),
opacity: new AnimatedValue<double>(1.0, end: 0.0, curve: Curves.ease),
scale: new AnimatedValue<double>(1.0, end: 0.8, curve: Curves.ease),
performance: performance,
x: new Tween<double>(begin: 0.0, end: 200.0),
opacity: new Tween<double>(begin: 1.0, end: 0.0),
scale: new Tween<double>(begin: 1.0, end: 0.8),
animation: new CurvedAnimation(parent: animation, curve: Curves.ease),
child: child
);
}
......
......@@ -92,7 +92,7 @@ abstract class ProxyWatchableMixin implements Watchable {
abstract class Evaluatable<T> {
const Evaluatable();
T evaluate(double t);
T evaluate(Animation animation);
WatchableValue<T> watch(Animation parent) {
return new WatchableValue<T>(parent: parent, evaluatable: this);
......@@ -105,7 +105,7 @@ class WatchableValue<T> extends Watchable with ProxyWatchableMixin {
final Animation parent;
final Evaluatable<T> evaluatable;
T get value => evaluatable.evaluate(parent.progress);
T get value => evaluatable.evaluate(parent);
}
abstract class Animation extends Watchable {
......@@ -261,9 +261,8 @@ class _RepeatingSimulation extends Simulation {
bool isDone(double timeInSeconds) => false;
}
// TODO(abarth): Rename Curve to UnitTransform and ACurve to Curve.
class ACurve extends Animation with ProxyWatchableMixin {
ACurve({ this.parent, this.curve, this.reverseCurve }) {
class CurvedAnimation extends Animation with ProxyWatchableMixin {
CurvedAnimation({ this.parent, this.curve, this.reverseCurve }) {
assert(parent != null);
assert(curve != null);
parent.addStatusListener(_handleStatusChanged);
......@@ -317,9 +316,7 @@ class ACurve extends Animation with ProxyWatchableMixin {
}
class Tween<T extends dynamic> extends Evaluatable<T> {
Tween({ this.begin, this.end }) {
assert(begin != null);
}
Tween({ this.begin, this.end });
/// The value this variable has at the beginning of the animation.
T begin;
......@@ -330,9 +327,10 @@ class Tween<T extends dynamic> extends Evaluatable<T> {
/// Returns the value this variable has at the given animation clock value.
T lerp(double t) => begin + (end - begin) * t;
T evaluate(double t) {
T evaluate(Animation animation) {
if (end == null)
return begin;
double t = animation.progress;
if (t == 0.0)
return begin;
if (t == 1.0)
......
......@@ -415,10 +415,10 @@ class TabBarSelection<T> extends StatefulComponent {
class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
PerformanceView get performance => _performance.view;
Animation get animation => _controller.view;
// Both the TabBar and TabBarView classes access _performance because they
// alternately drive selection progress between tabs.
final _performance = new Performance(duration: _kTabBarScroll, progress: 1.0);
final AnimationController _controller = new AnimationController(duration: _kTabBarScroll, progress: 1.0);
final Map<T, int> _valueToIndex = new Map<T, int>();
void _initValueToIndex() {
......@@ -442,7 +442,7 @@ class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
}
void dispose() {
_performance.stop();
_controller.stop();
PageStorage.of(context)?.writeState(context, _value);
super.dispose();
}
......@@ -481,21 +481,21 @@ class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
// the previous and current selection index.
double progress;
if (_performance.status == PerformanceStatus.completed)
if (_controller.status == PerformanceStatus.completed)
progress = 0.0;
else if (_previousValue == values.first)
progress = _performance.progress;
progress = _controller.progress;
else if (_previousValue == values.last)
progress = 1.0 - _performance.progress;
progress = 1.0 - _controller.progress;
else if (previousIndex < index)
progress = (_performance.progress - 0.5) * 2.0;
progress = (_controller.progress - 0.5) * 2.0;
else
progress = 1.0 - _performance.progress * 2.0;
progress = 1.0 - _controller.progress * 2.0;
_performance
_controller
..progress = progress
..forward().then((_) {
if (_performance.progress == 1.0) {
if (_controller.progress == 1.0) {
if (config.onChanged != null)
config.onChanged(_value);
_valueIsChanging = false;
......@@ -507,14 +507,14 @@ class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
void registerPerformanceListener(TabBarSelectionPerformanceListener listener) {
_performanceListeners.add(listener);
_performance
_controller
..addStatusListener(listener.handleStatusChange)
..addListener(listener.handleProgressChange);
}
void unregisterPerformanceListener(TabBarSelectionPerformanceListener listener) {
_performanceListeners.remove(listener);
_performance
_controller
..removeStatusListener(listener.handleStatusChange)
..removeListener(listener.handleProgressChange);
}
......@@ -590,17 +590,11 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
if (_valueIsChanging && status == PerformanceStatus.completed) {
_valueIsChanging = false;
double progress = 0.5;
if (_selection.index == 0)
progress = 0.0;
else if (_selection.index == config.labels.length - 1)
progress = 1.0;
_indicatorTween
..begin = _tabIndicatorRect(math.max(0, _selection.index - 1))
..end = _tabIndicatorRect(math.min(config.labels.length - 1, _selection.index + 1));
setState(() {
_indicatorRect
..begin = _tabIndicatorRect(math.max(0, _selection.index - 1))
..end = _tabIndicatorRect(math.min(config.labels.length - 1, _selection.index + 1))
..curve = null
..setProgress(progress, AnimationDirection.forward);
_indicatorRect = _tabIndicatorRect(_selection.index);
});
}
}
......@@ -612,23 +606,32 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
if (!_valueIsChanging && _selection.valueIsChanging) {
if (config.isScrollable)
scrollTo(_centeredTabScrollOffset(_selection.index), duration: _kTabBarScroll);
_indicatorRect
..begin = _indicatorRect.value ?? _tabIndicatorRect(_selection.previousIndex)
..end = _tabIndicatorRect(_selection.index)
..curve = Curves.ease;
_indicatorTween
..begin = _indicatorRect ?? _tabIndicatorRect(_selection.previousIndex)
..end = _tabIndicatorRect(_selection.index);
_valueIsChanging = true;
}
Rect oldRect = _indicatorRect.value;
_indicatorRect.setProgress(_selection.performance.progress, AnimationDirection.forward);
Rect newRect = _indicatorRect.value;
if (oldRect != newRect)
Rect oldRect = _indicatorRect;
double t = _selection.animation.progress;
if (_valueIsChanging) {
// When _valueIsChanging is true, we're animating based on a ticker and
// want to curve the animation. When _valueIsChanging is false, we're
// animating based on a pointer event and want linear feedback. It's
// possible we should move this curve into the selection animation.
t = Curves.ease.transform(t);
}
// TODO(abarth): If we've never gone through handleStatusChange before, we
// might not have set up our _indicatorTween yet.
_indicatorRect = _indicatorTween.lerp(t);
if (oldRect != _indicatorRect)
setState(() { });
}
Size _viewportSize = Size.zero;
Size _tabBarSize;
List<double> _tabWidths;
AnimatedRectValue _indicatorRect = new AnimatedRectValue(null);
Rect _indicatorRect;
RectTween _indicatorTween = new RectTween();
Rect _tabRect(int tabIndex) {
assert(_tabBarSize != null);
......@@ -673,9 +676,9 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
labelColor = isSelectedTab ? selectedColor : color;
if (_selection.valueIsChanging) {
if (isSelectedTab)
labelColor = Color.lerp(color, selectedColor, _selection.performance.progress);
labelColor = Color.lerp(color, selectedColor, _selection.animation.progress);
else if (isPreviouslySelectedTab)
labelColor = Color.lerp(selectedColor, color, _selection.performance.progress);
labelColor = Color.lerp(selectedColor, color, _selection.animation.progress);
}
}
return new _Tab(
......@@ -749,7 +752,7 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
children: tabs,
selectedIndex: _selection?.index,
indicatorColor: indicatorColor,
indicatorRect: _indicatorRect.value,
indicatorRect: _indicatorRect,
textAndIcons: textAndIcons,
isScrollable: config.isScrollable,
onLayoutChanged: _layoutChanged
......@@ -873,14 +876,14 @@ class _TabBarViewState extends PageableListState<TabBarView> implements TabBarSe
return;
// The TabBar is driving the TabBarSelection performance.
final Performance performance = _selection.performance;
final Animation animation = _selection.animation;
if (performance.status == PerformanceStatus.completed) {
if (animation.status == PerformanceStatus.completed) {
_updateItemsAndScrollBehavior();
return;
}
if (performance.status != PerformanceStatus.forward)
if (animation.status != PerformanceStatus.forward)
return;
final int selectedIndex = _selection.index;
......@@ -895,9 +898,9 @@ class _TabBarViewState extends PageableListState<TabBarView> implements TabBarSe
}
if (_scrollDirection == AnimationDirection.forward)
scrollTo(performance.progress);
scrollTo(animation.progress);
else
scrollTo(1.0 - performance.progress);
scrollTo(1.0 - animation.progress);
}
void dispatchOnScroll() {
......@@ -905,12 +908,12 @@ class _TabBarViewState extends PageableListState<TabBarView> implements TabBarSe
return;
// This class is driving the TabBarSelection's performance.
final Performance performance = _selection._performance;
final AnimationController controller = _selection._controller;
if (_selection.index == 0 || _selection.index == _tabCount - 1)
performance.progress = scrollOffset;
controller.progress = scrollOffset;
else
performance.progress = scrollOffset / 2.0;
controller.progress = scrollOffset / 2.0;
}
Future fling(Offset scrollVelocity) {
......
......@@ -70,30 +70,30 @@ class _SmoothlyResizingOverflowBoxState extends State<SmoothlyResizingOverflowBo
class _Entry {
_Entry({
this.child,
this.enterPerformance,
this.enterController,
this.enterTransition
});
final Widget child;
final Performance enterPerformance;
final AnimationController enterController;
final Widget enterTransition;
Size childSize = Size.zero;
Performance exitPerformance;
AnimationController exitController;
Widget exitTransition;
Widget get currentTransition => exitTransition ?? enterTransition;
void dispose() {
enterPerformance?.stop();
exitPerformance?.stop();
enterController?.stop();
exitController?.stop();
}
}
typedef Widget TransitionBuilderCallback(PerformanceView performance, Widget child);
typedef Widget TransitionBuilderCallback(Animation animation, Widget child);
Widget _identityTransition(PerformanceView performance, Widget child) => child;
Widget _identityTransition(Animation animation, Widget child) => child;
class EnterExitTransition extends StatefulComponent {
EnterExitTransition({
......@@ -129,11 +129,11 @@ class _EnterExitTransitionState extends State<EnterExitTransition> {
}
_Entry _createEnterTransition() {
Performance enterPerformance = new Performance(duration: config.duration)..play();
AnimationController enterController = new AnimationController(duration: config.duration)..forward();
return new _Entry(
child: config.child,
enterPerformance: enterPerformance,
enterTransition: config.onEnter(enterPerformance, new KeyedSubtree(
enterController: enterController,
enterTransition: config.onEnter(enterController, new KeyedSubtree(
key: new GlobalKey(),
child: config.child
))
......@@ -141,11 +141,11 @@ class _EnterExitTransitionState extends State<EnterExitTransition> {
}
Future _createExitTransition(_Entry entry) async {
Performance exitPerformance = new Performance(duration: config.duration);
AnimationController exitController = new AnimationController(duration: config.duration);
entry
..exitPerformance = exitPerformance
..exitTransition = config.onExit(exitPerformance, entry.enterTransition);
await exitPerformance.play();
..exitController = exitController
..exitTransition = config.onExit(exitController, entry.enterTransition);
await exitController.forward();
if (!mounted)
return;
setState(() {
......
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