Skip to content

Instantly share code, notes, and snippets.

@oianmol
Created April 6, 2021 08:17
Show Gist options
  • Save oianmol/963a4540ffd4f3fbaf22f6dc88c61047 to your computer and use it in GitHub Desktop.
Save oianmol/963a4540ffd4f3fbaf22f6dc88c61047 to your computer and use it in GitHub Desktop.
My Experiments with quadraticBezier and CustomPainter in Flutter.
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