Chromium Code Reviews| 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 '../animation/animated_value.dart'; | |
| 5 import '../painting/box_painter.dart'; | 6 import '../painting/box_painter.dart'; |
| 6 import '../theme/colors.dart' as colors; | 7 import '../theme/colors.dart' as colors; |
| 7 import '../theme/edges.dart'; | 8 import '../theme/edges.dart'; |
| 8 import '../theme/shadows.dart'; | 9 import '../theme/shadows.dart'; |
| 10 import 'animated_component.dart'; | |
| 9 import 'basic.dart'; | 11 import 'basic.dart'; |
| 10 import 'default_text_style.dart'; | 12 import 'default_text_style.dart'; |
| 11 import 'theme.dart'; | 13 import 'theme.dart'; |
| 12 | 14 |
| 13 class Material extends Component { | 15 const double _kAnimateShadowDurationMS = 100.0; |
| 16 | |
| 17 // Ugly code to linearly interpolate 2 BoxShadows. | |
| 18 double lerpDouble(double p1, double p2, double t) => p1 * (1.0 - t) + p2 * t; | |
| 19 | |
| 20 Color lerpColor(Color p1, Color p2, double t) => | |
| 21 new Color.fromARGB((p1.alpha * (1.0 - t) + p2.alpha * t).toInt(), | |
| 22 (p1.red * (1.0 - t) + p2.red * t).toInt(), | |
| 23 (p1.green * (1.0 - t) + p2.green * t).toInt(), | |
| 24 (p1.blue * (1.0 - t) + p2.blue * t).toInt()); | |
| 25 | |
| 26 Size lerpSize(Size p1, Size p2, double t) => | |
| 27 new Size(p1.width * (1.0 - t) + p2.width * t, | |
| 28 p1.height * (1.0 - t) + p2.height * t); | |
| 29 | |
| 30 BoxShadow lerpShadow(BoxShadow p1, BoxShadow p2, double t) { | |
| 31 return new BoxShadow( | |
| 32 color: lerpColor(p1.color, p2.color, t), | |
| 33 offset: lerpSize(p1.offset, p2.offset, t), | |
| 34 blur: lerpDouble(p1.blur, p2.blur, t)); | |
| 35 } | |
| 36 | |
| 37 List<BoxShadow> computeShadow(double level) { | |
| 38 if (level < 1.0) // shadows[1] is the first shadow | |
|
Hixie
2015/06/25 22:42:19
Can't we animate from no shadow to a shadow?
Matt Perry
2015/06/30 22:09:11
We could, but that's extra code and we don't need
| |
| 39 return null; | |
| 40 | |
| 41 int level1 = level.floor(); | |
| 42 int level2 = level.ceil(); | |
| 43 double t = level - level1.toDouble(); | |
| 44 | |
| 45 List<BoxShadow> shadow = new List<BoxShadow>(); | |
| 46 for (int i = 0; i < shadows[level1].length; ++i) | |
| 47 shadow.add(lerpShadow(shadows[level1][i], shadows[level2][i], t)); | |
| 48 return shadow; | |
| 49 } | |
| 50 | |
| 51 class Material extends AnimatedComponent { | |
| 14 | 52 |
| 15 Material({ | 53 Material({ |
| 16 String key, | 54 String key, |
| 17 this.child, | 55 this.child, |
| 18 this.edge: MaterialEdge.card, | 56 this.edge: MaterialEdge.card, |
| 19 this.level: 0, | 57 int level: 0, |
| 20 this.color | 58 this.color |
| 21 }) : super(key: key); | 59 }) : super(key: key) { |
| 60 this.level = new AnimatedValue(level.toDouble()); | |
| 61 animate(this.level, (_) {}); | |
| 62 } | |
| 22 | 63 |
| 23 final Widget child; | 64 Widget child; |
| 24 final int level; | 65 MaterialEdge edge; |
| 25 final MaterialEdge edge; | 66 AnimatedValue level; |
| 26 final Color color; | 67 Color color; |
| 27 | 68 |
| 28 Color get backgroundColor { | 69 Color get backgroundColor { |
| 29 if (color != null) | 70 if (color != null) |
| 30 return color; | 71 return color; |
| 31 switch (Theme.of(this).brightness) { | 72 switch (Theme.of(this).brightness) { |
| 32 case ThemeBrightness.light: | 73 case ThemeBrightness.light: |
| 33 return colors.Grey[50]; | 74 return colors.Grey[50]; |
| 34 case ThemeBrightness.dark: | 75 case ThemeBrightness.dark: |
| 35 return colors.Grey[850]; | 76 return colors.Grey[850]; |
| 36 } | 77 } |
| 37 } | 78 } |
| 38 | 79 |
| 39 // TODO(ianh): we should make this animate level changes and color changes | 80 void syncFields(Material source) { |
| 81 child = source.child; | |
| 82 edge = source.edge; | |
| 83 if (level.value != source.level.value) | |
| 84 level.animateTo(source.level.value.toDouble(), _kAnimateShadowDurationMS); | |
| 85 color = source.color; | |
| 86 super.syncFields(source); | |
| 87 } | |
| 88 | |
| 89 // TODO(mpcomplete): make this animate color changes. | |
| 40 | 90 |
| 41 Widget build() { | 91 Widget build() { |
| 42 return new Container( | 92 return new Container( |
| 43 decoration: new BoxDecoration( | 93 decoration: new BoxDecoration( |
| 44 boxShadow: shadows[level], | 94 boxShadow: computeShadow(level.value), |
| 45 borderRadius: edges[edge], | 95 borderRadius: edges[edge], |
| 46 backgroundColor: backgroundColor, | 96 backgroundColor: backgroundColor, |
| 47 shape: edge == MaterialEdge.circle ? Shape.circle : Shape.rectangle | 97 shape: edge == MaterialEdge.circle ? Shape.circle : Shape.rectangle |
| 48 ), | 98 ), |
| 49 child: new DefaultTextStyle(style: Theme.of(this).text.body1, child: child ) | 99 child: new DefaultTextStyle(style: Theme.of(this).text.body1, child: child ) |
| 50 ); | 100 ); |
| 51 } | 101 } |
| 52 | 102 |
| 53 } | 103 } |
| OLD | NEW |