Flutter构建随机转盘(一)

665 阅读1分钟

场景

随着人们生活质量的提高以及可选择的变多以后,很多人发现我们不会做决定了,比如:今天吃什么、看那部电影、今天谁买单…… 等等。

为了解决大家这一选择难题,我决定制作一个转盘选择器,让他替我们来选择。

设计稿

image.png

可以看到,我们设计稿还是很给力的.

最终实现的效果:

heart.gif

接下来就开始想如何实现:

大致思路: 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}) 

接下来我们就返回一个扇形路径 我们需要知道三个点:

  1. a 圆心,我们取 宽度的一半
  2. b 左侧交点
  3. c 右侧交点

大致意思如图所示:

image.png

代码实现如下:

    @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();
  }