| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:async'; | 5 import 'dart:async'; |
| 6 | 6 |
| 7 import 'package:vector_math/vector_math.dart'; | 7 import 'package:vector_math/vector_math.dart'; |
| 8 | 8 |
| 9 import '../animation/animated_value.dart'; | 9 import '../animation/animated_value.dart'; |
| 10 import '../animation/animation_performance.dart'; | 10 import '../animation/animation_performance.dart'; |
| 11 import '../animation/curves.dart'; | 11 import '../animation/curves.dart'; |
| 12 import 'basic.dart'; | 12 import 'basic.dart'; |
| 13 | 13 |
| 14 class _AnimationEntry { | 14 class _AnimationEntry { |
| 15 _AnimationEntry(this.value); | 15 _AnimationEntry(this.value); |
| 16 final AnimatedValue value; | 16 final AnimatedValue value; |
| 17 StreamSubscription<double> subscription; | 17 StreamSubscription<double> subscription; |
| 18 } | 18 } |
| 19 | 19 |
| 20 abstract class AnimatedComponent extends StatefulComponent { | 20 abstract class AnimatedComponent extends StatefulComponent { |
| 21 | 21 |
| 22 AnimatedComponent({ String key }) : super(key: key); | 22 AnimatedComponent({ String key }) : super(key: key); |
| 23 | 23 |
| 24 void syncFields(AnimatedComponent source) { } | 24 void syncFields(AnimatedComponent source) { } |
| 25 | 25 |
| 26 List<_AnimationEntry> _animatedFields = new List<_AnimationEntry>(); | 26 final List<_AnimationEntry> _animatedFields = new List<_AnimationEntry>(); |
| 27 final List<AnimationPerformance> _watchedPerformances = new List<AnimationPerf
ormance>(); |
| 27 | 28 |
| 28 watch(AnimatedValue value) { | 29 void watch(AnimatedValue value) { |
| 29 assert(!mounted); | 30 assert(!mounted); |
| 30 // TODO(ianh): we really should assert that we're not doing this | 31 // TODO(ianh): we really should assert that we're not doing this |
| 31 // in the constructor since doing it there is pointless and | 32 // in the constructor since doing it there is pointless and |
| 32 // expensive, since we'll be doing it for every copy of the object | 33 // expensive, since we'll be doing it for every copy of the object |
| 33 // even though only the first one will use it (since we're | 34 // even though only the first one will use it (since we're |
| 34 // stateful, the others will all be discarded early). | 35 // stateful, the others will all be discarded early). |
| 35 _animatedFields.add(new _AnimationEntry(value)); | 36 _animatedFields.add(new _AnimationEntry(value)); |
| 36 } | 37 } |
| 37 | 38 |
| 39 void watchPerformance(AnimationPerformance performance) { |
| 40 assert(!mounted); |
| 41 assert(!_watchedPerformances.contains(performance)); |
| 42 _watchedPerformances.add(performance); |
| 43 } |
| 44 |
| 38 void didMount() { | 45 void didMount() { |
| 39 for (_AnimationEntry entry in _animatedFields) { | 46 for (_AnimationEntry entry in _animatedFields) { |
| 40 entry.subscription = entry.value.onValueChanged.listen((_) { | 47 entry.subscription = entry.value.onValueChanged.listen((_) { |
| 41 scheduleBuild(); | 48 scheduleBuild(); |
| 42 }); | 49 }); |
| 43 } | 50 } |
| 51 |
| 52 for (AnimationPerformance performance in _watchedPerformances) |
| 53 performance.addListener(scheduleBuild); |
| 54 |
| 44 super.didMount(); | 55 super.didMount(); |
| 45 } | 56 } |
| 46 | 57 |
| 47 void didUnmount() { | 58 void didUnmount() { |
| 48 for (_AnimationEntry entry in _animatedFields) { | 59 for (_AnimationEntry entry in _animatedFields) { |
| 49 assert(entry.subscription != null); | 60 assert(entry.subscription != null); |
| 50 entry.subscription.cancel(); | 61 entry.subscription.cancel(); |
| 51 entry.subscription = null; | 62 entry.subscription = null; |
| 52 } | 63 } |
| 64 |
| 65 for (AnimationPerformance performance in _watchedPerformances) |
| 66 performance.removeListener(scheduleBuild); |
| 67 |
| 53 super.didUnmount(); | 68 super.didUnmount(); |
| 54 } | 69 } |
| 55 | 70 |
| 56 } | 71 } |
| 57 | 72 |
| 58 // Types of things that can be animated in a component. Use build() to | 73 // Types of things that can be animated in a component. Use build() to |
| 59 // construct the final Widget based on the animation state. | 74 // construct the final Widget based on the animation state. |
| 60 // TODO(mpcomplete): the idea here is to eventually have an AnimatedCollection | 75 // TODO(mpcomplete): the idea here is to eventually have an AnimatedCollection |
| 61 // which assembles a container based on a list of animated things. e.g. if you | 76 // which assembles a container based on a list of animated things. e.g. if you |
| 62 // want to animate position, opacity, and shadow, you add those animators to an | 77 // want to animate position, opacity, and shadow, you add those animators to an |
| 63 // AnimatedCollection and just call collection.build() to construct your | 78 // AnimatedCollection and just call collection.build() to construct your |
| 64 // widget. | 79 // widget. |
| 65 | 80 |
| 66 class AnimatedPosition extends AnimatedType<Point> { | 81 class AnimatedPosition extends AnimatedType<Point> { |
| 67 AnimatedPosition(Point begin, Point end, {Curve curve: linear}) | 82 AnimatedPosition(Point begin, Point end, {Curve curve: linear}) |
| 68 : super(begin, end, curve: curve); | 83 : super(begin, end, curve: curve); |
| 69 | 84 |
| 70 Widget build(Widget child) { | 85 Widget build(Widget child) { |
| 71 Matrix4 transform = new Matrix4.identity(); | 86 Matrix4 transform = new Matrix4.identity(); |
| 72 transform.translate(value.x, value.y); | 87 transform.translate(value.x, value.y); |
| 73 return new Transform(transform: transform, child: child); | 88 return new Transform(transform: transform, child: child); |
| 74 } | 89 } |
| 75 } | 90 } |
| OLD | NEW |