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

Unified Diff: sky/sdk/lib/framework/widgets/checkbox.dart

Issue 1182743002: Animate checkboxes (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: rebase Created 5 years, 6 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 | « no previous file | sky/sdk/lib/framework/widgets/wrappers.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/lib/framework/widgets/checkbox.dart
diff --git a/sky/sdk/lib/framework/widgets/checkbox.dart b/sky/sdk/lib/framework/widgets/checkbox.dart
index 1d2630c48487e9f77f3d34126202361c8a9c698e..a6b341844895a0e35081f2d48a5b260386fcbab4 100644
--- a/sky/sdk/lib/framework/widgets/checkbox.dart
+++ b/sky/sdk/lib/framework/widgets/checkbox.dart
@@ -6,22 +6,54 @@ import 'dart:sky' as sky;
import 'package:sky/framework/theme2/colors.dart' as colors;
+import '../animation/animated_value.dart';
+import '../animation/curves.dart';
import '../rendering/box.dart';
-import 'button_base.dart';
+import 'animated_component.dart';
import 'wrappers.dart';
typedef void ValueChanged(value);
-class Checkbox extends ButtonBase {
+const double _kMidpoint = 0.5;
+const double _kCheckDuration = 200.0;
+const sky.Color _kUncheckedColor = const sky.Color(0x8A000000);
+// TODO(jackson): This should change colors with the theme
+sky.Color _kCheckedColor = colors.Purple[500];
+const double _kEdgeSize = 20.0;
+const double _kEdgeRadius = 1.0;
- Checkbox({ Object key, this.onChanged, this.checked }) : super(key: key);
+class Checkbox extends AnimatedComponent {
+
+ Checkbox({
+ Object key,
+ this.checked,
+ this.onChanged
+ }) : super(key: key) {
+ _checkedAnimation = new AnimatedValue(checked ? 1.0 : 0.0);
+ }
bool checked;
+ AnimatedValue _checkedAnimation;
ValueChanged onChanged;
void syncFields(Checkbox source) {
- checked = source.checked;
onChanged = source.onChanged;
+ if (checked != source.checked) {
+ checked = source.checked;
+ double targetValue = checked ? 1.0 : 0.0;
+ double difference = (_checkedAnimation.value - targetValue).abs();
+ if (difference > 0) {
+ double duration = difference * _kCheckDuration;
+ _checkedAnimation.stop();
+ Curve curve;
+ if (targetValue > _checkedAnimation.value) {
+ curve = easeIn;
+ } else {
+ curve = easeOut;
+ }
+ _checkedAnimation.animateTo(targetValue, duration, curve: curve);
+ }
+ }
super.syncFields(source);
}
@@ -29,37 +61,68 @@ class Checkbox extends ButtonBase {
onChanged(!checked);
}
- UINode buildContent() {
- // TODO(jackson): This should change colors with the theme
- sky.Color color = highlight ? colors.Purple[500] : const sky.Color(0x8A000000);
- const double kEdgeSize = 20.0;
- const double kEdgeRadius = 1.0;
+ UINode build() {
return new EventListenerNode(
new Container(
margin: const EdgeDims.symmetric(horizontal: 5.0),
- width: kEdgeSize + 2.0,
- height: kEdgeSize + 2.0,
+ width: _kEdgeSize + 2.0,
+ height: _kEdgeSize + 2.0,
child: new CustomPaint(
+ token: _checkedAnimation.value,
callback: (sky.Canvas canvas, Size size) {
+ // Choose a color between grey and the theme color
+ sky.Paint paint = new sky.Paint()..strokeWidth = 2.0
+ ..color = _kUncheckedColor;
- sky.Paint paint = new sky.Paint()..color = color
- ..strokeWidth = 2.0;
+ // The rrect contracts slightly during the animation
+ double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
+ sky.Rect rect = new sky.Rect.fromLTRB(inset, inset, _kEdgeSize - inset, _kEdgeSize - inset);
+ sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kEdgeRadius, _kEdgeRadius);
- // Draw the outer rrect
- paint.setStyle(checked ? sky.PaintingStyle.strokeAndFill : sky.PaintingStyle.stroke);
- sky.Rect rect = new sky.Rect.fromLTRB(0.0, 0.0, kEdgeSize, kEdgeSize);
- sky.RRect rrect = new sky.RRect()..setRectXY(rect, kEdgeRadius, kEdgeRadius);
+
+ // Outline of the empty rrect
+ paint.setStyle(sky.PaintingStyle.stroke);
canvas.drawRRect(rrect, paint);
- // Draw the inner check
- if (checked) {
- // TODO(jackson): Use the theme color
+ // Radial gradient that changes size
+ if (_checkedAnimation.value > 0) {
+ paint.setStyle(sky.PaintingStyle.fill);
+ paint.setShader(
+ new sky.Gradient.radial(
+ new Point(_kEdgeSize / 2.0, _kEdgeSize / 2.0),
+ _kEdgeSize * (_kMidpoint - _checkedAnimation.value) * 8.0,
+ [const sky.Color(0x00000000), _kUncheckedColor],
+ [0.0, 1.0]
+ )
+ );
+ canvas.drawRRect(rrect, paint);
+ }
+
+ if (_checkedAnimation.value > _kMidpoint) {
+ double t = (_checkedAnimation.value - _kMidpoint) / (1.0 - _kMidpoint);
+
+ // Solid filled rrect
+ paint.setStyle(sky.PaintingStyle.strokeAndFill);
+ paint.color = new Color.fromARGB((t * 255).floor(),
+ _kCheckedColor.red,
+ _kCheckedColor.green,
+ _kCheckedColor.blue);
+ canvas.drawRRect(rrect, paint);
+
+ // White inner check
paint.color = const sky.Color(0xFFFFFFFF);
paint.setStyle(sky.PaintingStyle.stroke);
sky.Path path = new sky.Path();
- path.moveTo(kEdgeSize * 0.2, kEdgeSize * 0.5);
- path.lineTo(kEdgeSize * 0.4, kEdgeSize * 0.7);
- path.lineTo(kEdgeSize * 0.8, kEdgeSize * 0.3);
+ sky.Point start = new sky.Point(_kEdgeSize * 0.2, _kEdgeSize * 0.5);
+ sky.Point mid = new sky.Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
+ sky.Point end = new sky.Point(_kEdgeSize * 0.8, _kEdgeSize * 0.3);
+ Point lerp(Point p1, Point p2, double t)
+ => new Point(p1.x * (1.0 - t) + p2.x * t, p1.y * (1.0 - t) + p2.y * t);
+ sky.Point drawStart = lerp(start, mid, 1.0 - t);
+ sky.Point drawEnd = lerp(mid, end, t);
+ path.moveTo(drawStart.x, drawStart.y);
+ path.lineTo(mid.x, mid.y);
+ path.lineTo(drawEnd.x, drawEnd.y);
canvas.drawPath(path, paint);
}
}
« no previous file with comments | « no previous file | sky/sdk/lib/framework/widgets/wrappers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698