qq头像玩电脑的(高仿QQ讨论组头像)
qq头像玩电脑的(高仿QQ讨论组头像)以下是部分内容展示:
View宽D,蓝色小圆半径r,红色大圆半径R,Y轴上偏移量dy,头像数量n。
- 首先需要得到大圆中心坐标。这里头像数量n为3为例。
//中心坐标x。
double centerX = width / 2;
//中心坐标y 因为3和5在y轴上有偏移量,需要单独计算。
double centerY = width / 2;
//小圆半径。
double r;
//大圆中心到小圆中心的半径。
double r1;
switch (n) {
case 3:
r = width / (2 4 * math.sin(math.pi * (n - 2) / (2 * n)));
r1 = r / math.cos(math.pi * (n - 2) / (2 * n));
double R = r * (1 math.sin(math.pi / n)) / math.sin(math.pi / n);
double dy = 0.5 * (width - R - r * (1 1 / math.tan(math.pi / n)));
centerY = dy r r1;
break;
}
- 圆心坐标通用公式,当n为2和4的时候初始角度为-45度。
for (int i = 0; i < n; i ) {
double degree1 = (n == 2 || n == 4) ? (-math.pi / 4) : 0;
double x = centerX r1 * math.sin(degree1 i * 2 * math.pi / n);
double y = centerY - r1 * math.cos(degree1 i * 2 * math.pi / n);
}
二、如何实现圆弧缺口
使用ClipPath组件,自定义clipper。
class QQClipper extends CustomClipper<Path> {
QQClipper({
this.total
this.index
this.initIndex: 1
this.previousX
this.previousY
this.degree
this.arcAngle: 60
}) : assert(arcAngle != null && arcAngle >= 0 && arcAngle <= 180);
//头像数量。
final int total;
//头像index。
final int index;
//头像initIndex。
final int initIndex;
//上一个圆心坐标x。
final double previousX;
//上一个圆心坐标y。
final double previousY;
//圆弧中心角度。
final double degree;
//圆弧角度。
final double arcAngle;
@override
Path getClip(Size size) {
double r = size.width / 2;
Path path = Path();
List<Offset> points = List();
//头像数量为2,头像index为initIndex时,保持整圆。
if (total == 2 && index == initIndex) {
path.addOval(Rect.fromLTRB(0 0 size.width size.height));
} else {
//圆弧路径坐标。
double spaceA = arcAngle / 2;
double startA = degree spaceA;
double endA = degree - spaceA;
for (double i = startA; i <= 360 endA; i = i 1) {
double x1 = r r * math.sin(d2r(i));
double y1 = r - r * math.cos(d2r(i));
points.add(Offset(x1 y1));
}
//圆弧缺口路径坐标。
double spaceB = math.atan(
r * math.sin(d2r(spaceA)) / (2 * r - r * math.cos(d2r(spaceA)))) /
math.pi *
180;
double r1 = (2 * r - r * math.cos(d2r(spaceA))) / math.cos(d2r(spaceB));
double startB = degree - 180 - spaceB;
double endB = degree - 180 spaceB;
List<Offset> pointsB = List();
for (double i = startB; i < endB; i = i 1) {
double x1 = previousX r1 * math.sin(d2r(i));
double y1 = previousY - r1 * math.cos(d2r(i));
pointsB.add(Offset(x1 y1));
}
points.addAll(pointsB.reversed);
path.addPolygon(points true);
}
return path;
}
/// degree to radian.
double d2r(double degree) {
return degree / 180 * math.pi;
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return this != oldClipper;
}
}
Screenshots
nine_grid_view:https://github.com/flutterchina/nine_grid_view
若有需要Flutter资源,麻烦各位转发一下(可以帮助更多的人看到哦!),记得一定要关注 转发,然后私信@芜湖Android“Flutter”,即可回复免费下载的方式!!如果是需要Android开发进阶的资源,则可以私信“Android开发”领取。
以下是部分内容展示: