场景
随着人们生活质量的提高以及可选择的变多以后,很多人发现我们不会做决定了,比如:今天吃什么、看那部电影、今天谁买单…… 等等。
为了解决大家这一选择难题,我决定制作一个转盘选择器,让他替我们来选择。
设计稿
可以看到,我们设计稿还是很给力的.
最终实现的效果:
接下来就开始想如何实现:
大致思路: 1、准备矩形; 2、将矩形剪切成扇形; 3、将扇形旋转到指定位置; 核心:如何剪切成扇形? 我们用的矩形都是有宽和高,我们默认 高度为圆的半径 r 然后 用 ClipPath.shape 自定义shape. 我们先创建一个 SectorShape 继承 SectorShape
大致如下:
class SectorShape extends ShapeBorder {
@override
EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
@override
Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
}
@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
// TODO: implement paint
}
@override
ShapeBorder scale(double t) {
}
}
我们看到有下面这个方法 返回的是一个剪切路径
Path getOuterPath(Rect rect, {TextDirection? textDirection})
接下来我们就返回一个扇形路径 我们需要知道三个点:
- a 圆心,我们取 宽度的一半
- b 左侧交点
- c 右侧交点
大致意思如图所示:
代码实现如下:
@override
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
var r = rect.size.height; // 半径
var w = rect.size.width/2.0;
// 找到相交点 a 和对称点 b 的坐标点
var sinQ = w/r;
/***
* 弧度数 为 Q
* .
* .\
* h .Q\
* . \
* . \
* -----\ a点
*
* 根据 sinQ^2 + cosQ^2 = 1
* ______________
* 得出 h = r * \| 1 - sinQ^2
*
* */
var h = r * Math.sqrt((1-Math.pow(sinQ, 2))); // 通过三角函数关系计算位置
var a = Offset(0, r-h);
var b = Offset(w*2.0, r-h);
return Path()
..moveTo(a.dx, a.dy)
..arcToPoint(b,radius: Radius.circular(r))
..lineTo(w, r)
..close();
}