饼状图,显示各元素的比例 各元素上有文字说明 圆盘可跟着手势转动 快速滑动抬起手后,可惯性滚动直至停止
新建类继承于CustomPainter实现paint()和shouldRepaint()方法 在paint方法中绘制你想要的内容 借助于CustomPaint Widget来构建自己的Widget
List angles;///文案集合
List contents;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
///颜色集合
List colors;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
..color = //颜色 红色
..strokeWidth = // 宽度
..isAntiAlias = true //是否抗锯齿 是
..style = // 模式 填充
Rect rect = (
center: Offset( / 2, / 2),
radius: / 2);
//画扇形
for (int i = 0; i < angles.length; i++) {
paint..color = colors[i];//取到颜色
(rect, 2 * pi * startAngles
2 * pi * angles[i], true, paint);
startAngles += angles[i];
}
ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle(
textAlign: ,
fontWeight: ,
fontStyle: ,
fontSize: ,
));
((color: ));
(text]);
// 设置文本的宽度约束
ParagraphConstraints pc = ParagraphConstraints(width: 400);
// 这里需要先layout,将宽度约束填入,否则无法绘制
Paragraph paragraph = ()..layout(pc);
();//这里先把canvas保存个副本,待会移动旋转完 好还原
// 新建一个段落建造器,然后将文字基本信息填入;
ParagraphBuilder pb = ParagraphBuilder...上面那一段,拿到paragraph.
// 文字左上角起始点
Offset offset = Offset(60, 0 - / 2);//由于没找到算文本宽度的方法,这里文本x轴的七点模拟写成 了60。
( / 2, / 2);//先把canvas移动到中心点
double roaAngle = 2 * pi * (startAngles + angles[i] / 2) ;
(roaAngle); //再将画布旋转一定角度,具体这个角度怎么来的, 稍微琢磨一下就明白了
(paragraph, offset);
();//画完后重置 画布
startAngles += angles[i]; //把当前元素角度累加
}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
3、onPanEnd (DragEndDetails details) --------- 手指抬起时触发文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
/// C点 (*radius,).
/// oc距离 radius
/// A点 (pAx,pAy),
/// B点 (pBx,pBy).文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
/// AC距离
double acDistance = (
+ 2 * , + , pAx, pAy);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
/// AO距离
double aoDistance = (
+ , + , pAx, pAy);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
double ocdistance = ;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
///根据手在上半圆还是下半圆, 决定角是正还是负
int c = 1;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
if (pAy < ( + )) {
c = -1;
}
///计算 cos aoc 的值 ,然后拿到 角 aoc
double cosAOC = (aoDistance * aoDistance + ocdistance * ocdistance - acDistance * acDistance) / (2 * aoDistance * ocdistance);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
double AOC = c * acos(cosAOC);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
/// BC距离
double bcDistance = (
+ 2 * , + , pBx, pBy);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
/// BO距离
double boDistance = (
+ , + , pBx, pBy);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
c = 1;
if (pBy < ( + )) {
c = -1;
}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
///计算 cos boc 的值,然后拿到角 boc;
double cosBOC = (boDistance * boDistance +ocdistance * ocdistance - bcDistance * bcDistance) / (2 * boDistance * ocdistance);
double BOC = c * acos(cosBOC);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
return BOC - AOC;
}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
绳子断了的时候,线速度v 摩擦力f 绳子系在磨上的点到磨中心点的距离r
我们假设从时间 tA到tB ,分别计算这两个时间点的角速度vA和vB,这样就拿到了 tA到tB 这个时间段转过的角度jAB,做累加,这是一种方法。 jiaoV除以角速度ja,得到一共惯性运动的时间t,这样我们就拿到了动画运行时间,同样假设时间点tC,可以计算0-tC之间滑动的过得角度jC,这样直接把这个角度在绘制的时候加上就可以了,主要涉及的就是路程、时间、加速度公式得到转过的角度。
double t = (inertiaInitAngle) , // vA;毫秒级
double animalValue = turns;//由于不是累加,定义一个变量作为当前旋转的角度
var time = new DateTime.now();//动画开启时 的 时间戳
int direction = 1; ///方向控制参数,用以最后的角度是加还是减
if (inertiaInitAngle < 0) {
direction = -1;
}//flutter中的动画,不熟悉的同学可以看下官网
autoAnimationController = AnimationController(
duration: Duration(milliseconds: (t * 1000).toInt()), vsync: this)
..addListener(() {
var animalTime = new DateTime.now();
double t1 = - time.millisecondsSinceEpoch;//动画执行中间的某个时间点
setState(() {
double s1 = (2 * inertiaInitAngle - direction * vA * (t1 / 1000)) *t1 / (2 * 1000);//路程、时间、加速度公式得到转过的角度。
turns = animalValue + s1;
});
});文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html
();文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16948.html