Created
January 30, 2020 14:59
-
-
Save savioserra/b8d8a8f7c6646bb10ede2b868d304979 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'dart:math' as Math; | |
enum MarkerType { cross, circle, none } | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Center( | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [MyWidget(MarkerType.cross), MyWidget(MarkerType.circle)], | |
), | |
), | |
), | |
); | |
} | |
} | |
class MyWidget extends StatefulWidget { | |
final MarkerType type; | |
MyWidget(this.type); | |
@override | |
MyWidgetState createState() => MyWidgetState(); | |
} | |
class MyWidgetState extends State<MyWidget> { | |
bool checked = false; | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
height: 60, | |
width: 60, | |
decoration: BoxDecoration( | |
border: Border.all(color: Colors.black12, width: 1), | |
shape: BoxShape.circle, | |
), | |
child: GestureDetector( | |
onTap: () => setState(() => checked = !checked), | |
child: TicTacToeMarker(type: widget.type, checked: checked)), | |
); | |
} | |
} | |
class TicTacToeMarker extends StatelessWidget { | |
final bool checked; | |
final MarkerType type; | |
final Gradient gradient; | |
final double strokeWidth; | |
const TicTacToeMarker({ | |
Key key, | |
@required this.type, | |
this.checked = false, | |
this.strokeWidth = 6.0, | |
this.gradient = const LinearGradient( | |
colors: [Colors.orangeAccent, Colors.red], | |
begin: Alignment.topLeft, | |
), | |
}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return Padding( | |
padding: EdgeInsets.all(strokeWidth / 2), | |
child: RepaintBoundary( | |
child: TweenAnimationBuilder( | |
duration: const Duration(milliseconds: 140), | |
tween: Tween<double>(begin: 0, end: checked ? 1.0 : 0.0), | |
builder: (ctx, value, child) => CustomPaint( | |
painter: MarkerPainter( | |
type, | |
clip: value, | |
gradient: gradient, | |
strokeWidth: strokeWidth, | |
), | |
), | |
), | |
), | |
); | |
} | |
} | |
class MarkerPainter extends CustomPainter { | |
final double clip; | |
final MarkerType type; | |
final Gradient gradient; | |
final double strokeWidth; | |
const MarkerPainter( | |
this.type, { | |
@required this.clip, | |
@required this.gradient, | |
@required this.strokeWidth, | |
}); | |
@override | |
void paint(Canvas canvas, Size size) { | |
if (clip == 0 || type == MarkerType.none) return; | |
var gradientShader = gradient.createShader(Offset.zero & size); | |
var paint = Paint() | |
..strokeWidth = strokeWidth | |
..style = PaintingStyle.stroke | |
..strokeJoin = StrokeJoin.round | |
..strokeCap = StrokeCap.round | |
..shader = gradientShader; | |
if (type == MarkerType.cross) { | |
paintClippingCross(canvas, size, paint); | |
} else { | |
paintClippingCircle(canvas, size, paint); | |
} | |
} | |
void paintClippingCross(Canvas canvas, Size size, Paint paint) { | |
var path = Path(); | |
var currClip = clip * 2; | |
var firstLine = size.width * Math.min(1, currClip); | |
path.lineTo(firstLine, firstLine); | |
if (clip > 0.5) { | |
var secondLine = (currClip - 1) * size.width; | |
path | |
..moveTo(0, size.height) | |
..relativeLineTo(secondLine, -secondLine); | |
} | |
canvas.drawPath(path, paint); | |
} | |
void paintClippingCircle(Canvas canvas, Size size, Paint paint) { | |
var path = Path(); | |
path.addArc(Offset.zero & size, 0, 2 * Math.pi * clip); | |
canvas.drawPath(path, paint); | |
} | |
@override | |
bool shouldRepaint(MarkerPainter oldDelegate) => | |
oldDelegate.clip != clip || oldDelegate.type != type; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment