Skip to content

Instantly share code, notes, and snippets.

@JohnKim
Created November 6, 2020 09:09
Show Gist options
  • Save JohnKim/a0fc1d41829226883c39c76995303f22 to your computer and use it in GitHub Desktop.
Save JohnKim/a0fc1d41829226883c39c76995303f22 to your computer and use it in GitHub Desktop.
Face Example (Flutter)
import 'package:flutter/material.dart';
import 'dart:math';
double degreesToRads(double deg) {
return (deg * pi) / 180.0;
}
void main() {
runApp(Face());
}
class Face extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: CustomPaint(
painter: _MyPainter(1.2, color: Colors.white),
),
);
}
}
class _MyPainter extends CustomPainter {
_MyPainter(
animationValue, {
this.color = const Color(0xFF615f56),
}) : activeIndex = animationValue.floor(),
unitAnimatingValue = (animationValue * 10 % 10 / 10);
final int activeIndex;
Color color;
final double unitAnimatingValue;
@override
void paint(Canvas canvas, Size size) {
_drawEye(canvas, size);
_drawMouth(canvas, size);
}
@override
bool shouldRepaint(_MyPainter oldDelegate) {
return unitAnimatingValue != oldDelegate.unitAnimatingValue ||
activeIndex != oldDelegate.activeIndex;
}
_drawEye(canvas, size) {
var angle = 0.0;
var wide = 0.0;
switch (activeIndex) {
case 0: // 0 -> 0.99 angle 조정
angle = 55 - unitAnimatingValue * 50;
wide = 80.0;
break;
case 1: // 1 -> 1.99 width 조정
wide = 80 - unitAnimatingValue * 80;
angle = 5;
break;
}
var degree1 = 90 * 3 + angle;
var degree2 = 90 * 3 - angle + wide;
var x1 = size.width / 2 * 0.65;
var x2 = size.width - x1;
var y = size.height * 0.41;
var eyeRadius = size.width * (5 / 60); // 60 diameter -> 5.0;
var paint = Paint()..color = color;
canvas.drawArc(
Rect.fromCircle(
center: Offset(x1, y),
radius: eyeRadius,
),
degreesToRads(degree1), // 270d + angle
degreesToRads(360 - wide),
false,
paint,
);
canvas.drawArc(
Rect.fromCircle(
center: Offset(x2, y),
radius: eyeRadius,
),
degreesToRads(degree2),
degreesToRads(360 - wide),
false,
paint,
);
}
_drawMouth(Canvas canvas, size) {
var upperY = size.height * 0.70;
var lowerY = size.height * 0.77;
var middleY = (lowerY - upperY) / 2 + upperY;
var leftX = size.width / 2 * 0.65;
var rightX = size.width - leftX;
var middleX = size.width / 2;
double y1, y3, x2, y2;
Path path2;
switch (activeIndex) {
case 0:
y1 = lowerY;
x2 = middleX;
y2 = upperY;
y3 = lowerY;
break;
case 1:
y1 = lowerY;
x2 = middleX;
y2 = unitAnimatingValue * (middleY - upperY) + upperY;
y3 = lowerY - unitAnimatingValue * (lowerY - upperY);
break;
case 2:
y1 = unitAnimatingValue * (upperY - lowerY) + lowerY;
x2 = middleX;
y2 = unitAnimatingValue * (lowerY + 3 - middleY) + middleY;
y3 = upperY;
break;
case 3:
y1 = upperY;
x2 = middleX;
y2 = lowerY + 3;
y3 = upperY;
path2 = Path()
..moveTo(leftX, y1)
..quadraticBezierTo(
x2,
y2,
upperY - 2.5,
y3 - 2.5,
)
..quadraticBezierTo(
x2,
y2 - unitAnimatingValue * (y2 - upperY + 2.5),
leftX,
upperY - 2.5,
)
..close();
break;
case 4:
y1 = upperY;
x2 = middleX;
y2 = lowerY + 3;
y3 = upperY;
path2 = Path()
..moveTo(leftX, y1)
..quadraticBezierTo(
x2,
y2,
upperY - 2.5,
y3 - 2.5,
)
..quadraticBezierTo(
x2,
upperY - 2.5,
leftX,
upperY - 2.5,
)
..close();
break;
}
var path = Path()
..moveTo(leftX, y1)
..quadraticBezierTo(
x2,
y2,
rightX,
y3,
);
canvas.drawPath(
path,
Paint()
..color = color
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round
..strokeWidth = size.width * (5 / 60));
if (path2 != null) {
canvas.drawPath(
path2,
Paint()
..color = color
..style = PaintingStyle.fill
..strokeCap = StrokeCap.round,
);
}
}
}
@JohnKim
Copy link
Author

JohnKim commented Nov 6, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment