Created
April 6, 2021 08:17
-
-
Save oianmol/963a4540ffd4f3fbaf22f6dc88c61047 to your computer and use it in GitHub Desktop.
My Experiments with quadraticBezier and CustomPainter in Flutter.
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'; | |
const HAIR_COLOR = Color.fromRGBO(22, 31, 56, 1); | |
const BG_COLOR = Color.fromRGBO(204, 217, 205, 1); | |
const LEAVES_COLOR = Color.fromRGBO(64, 144, 130, 1); | |
const HEART_COLOR = Color.fromRGBO(255, 102, 83, 1); | |
const GIRL_LIGHT_COLOR = Color.fromRGBO(255, 178, 149, 1); | |
const GIRL_DARK_COLOR = Color.fromRGBO(253, 157, 121, 1); | |
const GIRL_CHEEKS_COLOR = Color.fromRGBO(251, 127, 106, 1); | |
const GIRL_TSHIRT_COLOR = Color.fromRGBO(255, 236, 227, 1); | |
class GirlWithHairPainted extends CustomPainter { | |
@override | |
void paint(Canvas canvas, Size size) { | |
paintHair(size, canvas); | |
paintLeaves(size, canvas); | |
paintFace(size, canvas); | |
paintNeck(size,canvas); | |
} | |
paintFace(Size size, Canvas canvas) { | |
faceShape(size, canvas); | |
faceTeeth(size, canvas); | |
faceEyes(size, canvas); | |
faceNose(size, canvas); | |
leftEar(size, canvas); | |
} | |
faceNose(Size size, Canvas canvas) { | |
final paint = getPainter(GIRL_DARK_COLOR); | |
Path path = Path() | |
..moveTo(width(size) * 0.58, height(size) * 0.60) | |
..quadraticBezierTo(width(size) * 0.54, height(size) * 0.61, | |
width(size) * 0.65, height(size) * 0.59) | |
..quadraticBezierTo(width(size) * 0.66, height(size) * 0.61, | |
width(size) * 0.64, height(size) * 0.61) | |
..quadraticBezierTo(width(size) * 0.60, height(size) * 0.64, | |
width(size) * 0.59, height(size) * 0.60) | |
..close(); | |
canvas.drawPath(path, paint); | |
} | |
faceEyes(Size size, Canvas canvas) { | |
final cheekLW = 0.49; | |
final cheekLH = 0.60; | |
final cheekRW = 0.70; | |
final cheekRH = 0.54; | |
final paint = getPainter(Colors.black); | |
Path path = Path() | |
..moveTo(width(size) * cheekRW, height(size) * cheekRH) | |
..addOval(Rect.fromCircle( | |
center: Offset(width(size) * cheekRW, height(size) * cheekRH), | |
radius: 14)) | |
..close(); | |
canvas.drawPath(path, paint); | |
path = Path() | |
..moveTo(width(size) * cheekLW, height(size) * cheekLH) | |
..addOval(Rect.fromCircle( | |
center: Offset(width(size) * cheekLW, height(size) * cheekLH), | |
radius: 14)) | |
..close(); | |
canvas.drawPath(path, paint); | |
} | |
faceTeeth(Size size, Canvas canvas) { | |
final paint = getPainter(Colors.white); | |
Path path = Path() | |
..moveTo(width(size) * 0.52, height(size) * 0.658) | |
..quadraticBezierTo(width(size) * 0.58, height(size) * 0.658, | |
width(size) * 0.68, height(size) * 0.628) | |
..quadraticBezierTo(width(size) * 0.7, height(size) * 0.628, | |
width(size) * 0.65, height(size) * 0.658) | |
..quadraticBezierTo(width(size) * 0.60, height(size) * 0.678, | |
width(size) * 0.52, height(size) * 0.658) | |
..close(); | |
canvas.drawPath(path, paint); | |
} | |
leftEar(Size size, Canvas canvas) { | |
final paint = getPainter(GIRL_LIGHT_COLOR); | |
Path path = Path() | |
..moveTo(width(size) * 0.35, height(size) * 0.55) | |
..lineTo(width(size) * 0.29, height(size) * 0.552) | |
..quadraticBezierTo(width(size) * 0.30, height(size) * 0.62, | |
width(size) * 0.37, height(size) * 0.59) | |
..close(); | |
canvas.drawPath(path, paint); | |
} | |
faceShape(Size size, Canvas canvas) { | |
final paint = getPainter(GIRL_LIGHT_COLOR); | |
Path path = Path() | |
..moveTo(width(size) * 0.35, height(size) * 0.55) | |
..quadraticBezierTo(width(size) * 0.65, height(size) * 0.53, | |
width(size) * 0.70, height(size) * 0.40) | |
..quadraticBezierTo(width(size) * 0.93, height(size) * 0.65, | |
width(size) * 0.65, height(size) * 0.7) | |
..quadraticBezierTo(width(size) * 0.35, height(size) * 0.68, | |
width(size) * 0.35, height(size) * 0.55) | |
..close(); | |
canvas.drawPath(path, paint); | |
} | |
paintNeck(Size size, Canvas canvas) { | |
final paint = getPainter(GIRL_DARK_COLOR); | |
Path path = Path() | |
..moveTo(width(size) * 0.65, height(size) * 0.7) | |
..close(); | |
canvas.drawPath(path, paint); | |
} | |
double height(Size size) => size.height; | |
double width(Size size) => size.width; | |
paintHair(Size size, Canvas canvas) { | |
final hairPainter = getHairPainter(); | |
final point1 = Offset(0, 0); | |
final point2 = Offset(0, height(size) * 0.40); | |
final quadPoint1 = Offset(width(size) * 0.15, height(size) * 0.45); | |
final quadPoint2 = Offset(width(size) * 0.20, height(size) * 0.55); | |
final quadPoint3 = Offset(width(size) * 0.25, height(size) * 0.65); | |
final quadPoint4 = Offset(width(size) * 0.50, height(size) * 0.65); | |
final quadPoint5 = Offset(width(size) * 0.85, height(size) * 0.65); | |
final quadPoint6 = Offset(width(size) * 0.85, height(size) * 0.45); | |
final quadPoint7 = Offset(width(size) * 0.90, height(size) * 0.30); | |
final hairRightBottom = Offset(width(size), height(size) * 0.3); | |
Path path = Path() | |
..moveTo(point1.dx, point1.dy) | |
..lineTo(point2.dx, point2.dy) | |
..quadraticBezierTo( | |
quadPoint1.dx, quadPoint1.dy, quadPoint2.dx, quadPoint2.dy) | |
..quadraticBezierTo( | |
quadPoint3.dx, quadPoint3.dy, quadPoint4.dx, quadPoint4.dy) | |
..quadraticBezierTo( | |
quadPoint5.dx, quadPoint5.dy, quadPoint6.dx, quadPoint6.dy) | |
..quadraticBezierTo( | |
quadPoint7.dx, quadPoint7.dy, hairRightBottom.dx, hairRightBottom.dy) | |
..lineTo(width(size), 0) | |
..close(); | |
canvas.drawPath(path, hairPainter); | |
} | |
paintLeaves( | |
Size size, | |
Canvas canvas, | |
) { | |
final leavesPaint = getPainter(LEAVES_COLOR); | |
final startingPoint = Offset(width(size) * 0.7, height(size) * 0.20); | |
final startingPoint1 = Offset(width(size) * 0.6, height(size) * 0.3); | |
final startingPoint2 = Offset(width(size) * 0.3, height(size) * 0.3); | |
drawLeavesPath(startingPoint, canvas, leavesPaint); | |
drawLeavesPath(startingPoint1, canvas, leavesPaint); | |
drawLeavesPath(startingPoint2, canvas, leavesPaint); | |
} | |
drawLeavesPath(Offset startingPoint, Canvas canvas, leavesPaint) { | |
Path path = Path() | |
..moveTo(startingPoint.dx, startingPoint.dy) | |
..quadraticBezierTo( | |
startingPoint.dx + (startingPoint.dx * 0.10), | |
startingPoint.dy - (startingPoint.dy * 0.15), | |
startingPoint.dx + (startingPoint.dx * 0.25), | |
startingPoint.dy - (startingPoint.dy * 0.10)) | |
..quadraticBezierTo( | |
startingPoint.dx + (startingPoint.dx * 0.15), | |
startingPoint.dy + (startingPoint.dy * 0.10), | |
startingPoint.dx, | |
startingPoint.dy) | |
..close(); | |
canvas.drawPath(path, leavesPaint); | |
} | |
@override | |
bool shouldRepaint(covariant CustomPainter oldDelegate) { | |
return true; | |
} | |
getHairPainter() { | |
return getPainter(HAIR_COLOR); | |
} | |
getPainter(color) { | |
Paint paint = new Paint() | |
..style = PaintingStyle.fill | |
..isAntiAlias = true | |
..color = color; | |
return paint; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment