Make checkbox widget to fit more closely to material design standard. Make changes to remove animation artefacts.

This commit is contained in:
Mehmet Akin 2015-10-07 01:01:54 +02:00
parent cf17dd9687
commit 90d47520fd

View File

@ -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);