From 90d47520fd91ab3af362c090a5dd4ec1499be60c Mon Sep 17 00:00:00 2001 From: Mehmet Akin Date: Wed, 7 Oct 2015 01:01:54 +0200 Subject: [PATCH] Make checkbox widget to fit more closely to material design standard. Make changes to remove animation artefacts. --- .../flutter/lib/src/widgets/checkbox.dart | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/flutter/lib/src/widgets/checkbox.dart b/packages/flutter/lib/src/widgets/checkbox.dart index 89cdaee293..2ae53375be 100644 --- a/packages/flutter/lib/src/widgets/checkbox.dart +++ b/packages/flutter/lib/src/widgets/checkbox.dart @@ -15,8 +15,9 @@ export 'package:sky/src/rendering/toggleable.dart' show ValueChanged; const double _kMidpoint = 0.5; const sky.Color _kLightUncheckedColor = const sky.Color(0x8A000000); const sky.Color _kDarkUncheckedColor = const sky.Color(0xB2FFFFFF); -const double _kEdgeSize = 20.0; +const double _kEdgeSize = 18.0; const double _kEdgeRadius = 1.0; +const double _kStrokeWidth = 2.0; /// A material design checkbox /// @@ -127,13 +128,18 @@ class _RenderCheckbox extends RenderToggleable { final PaintingCanvas canvas = context.canvas; // Choose a color between grey and the theme color sky.Paint paint = new sky.Paint() - ..strokeWidth = 2.0 + ..strokeWidth = _kStrokeWidth ..color = uncheckedColor; - // The rrect contracts slightly during the animation + // The rrect contracts slightly during the transition animation from checked states. + // Because we have a stroke size of 2, we should have a minimum 1.0 inset. double inset = 2.0 - (position - _kMidpoint).abs() * 2.0; - sky.Rect rect = new sky.Rect.fromLTWH(offset.dx + inset, offset.dy + inset, - _kEdgeSize - inset, _kEdgeSize - inset); + double rectSize = _kEdgeSize - inset * _kStrokeWidth; + sky.Rect rect = + new sky.Rect.fromLTWH(offset.dx + inset, offset.dy + inset, rectSize, rectSize); + // Create an inner rectangle to cover inside of rectangle. This is needed to avoid + // painting artefacts caused by overlayed paintings. + sky.Rect innerRect = rect.deflate(1.0); sky.RRect rrect = new sky.RRect() ..setRectXY(rect, _kEdgeRadius, _kEdgeRadius); @@ -150,25 +156,27 @@ class _RenderCheckbox extends RenderToggleable { const sky.Color(0x00000000), uncheckedColor ])); - canvas.drawRRect(rrect, paint); + canvas.drawRect(innerRect, paint); } if (position > _kMidpoint) { double t = (position - _kMidpoint) / (1.0 - _kMidpoint); - // Solid filled rrect - paint.setStyle(sky.PaintingStyle.strokeAndFill); + // First draw a rounded rect outline then fill inner rectangle with accent color. paint.color = new Color.fromARGB((t * 255).floor(), _accentColor.red, _accentColor.green, _accentColor.blue); + paint.setStyle(sky.PaintingStyle.stroke); canvas.drawRRect(rrect, paint); + paint.setStyle(sky.PaintingStyle.fill); + canvas.drawRect(innerRect, paint); // White inner check paint.color = const sky.Color(0xFFFFFFFF); paint.setStyle(sky.PaintingStyle.stroke); sky.Path path = new sky.Path(); - sky.Point start = new sky.Point(_kEdgeSize * 0.2, _kEdgeSize * 0.5); + sky.Point start = new sky.Point(_kEdgeSize * 0.15, _kEdgeSize * 0.45); sky.Point mid = new sky.Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7); - sky.Point end = new sky.Point(_kEdgeSize * 0.8, _kEdgeSize * 0.3); + sky.Point end = new sky.Point(_kEdgeSize * 0.85, _kEdgeSize * 0.25); 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);