您好,登錄后才能下訂單哦!
這篇文章主要介紹了基于Flutter如何實現(xiàn)多邊形和多角星組件的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇基于Flutter如何實現(xiàn)多邊形和多角星組件文章都會有所收獲,下面我們一起來看看吧。
正多邊形
正多角星
支持同時繪制多邊形和多角星
角的飽滿度調(diào)整
五角星為例:
可以看到,在一個五角星中,一共有10
個點,有5
個點平均分布在大圓上面,有5
個點平均分布在小圓上面,相當(dāng)于對360度進(jìn)行了10
等分,那么我們只需要將這10
個點找到,用線連起來即可。
既然知道了點的分布規(guī)律,我們只需要拿到圓的半徑通過三角函數(shù)就能得到每個點的坐標(biāo),通過path路徑進(jìn)行連接即可。
// 大圓半徑 double r = bigR ?? size.width / 2 / 2; // 小圓半徑 double r2 = smallR ?? size.width / 2 / 2 - 12; Path path = Path(); // 設(shè)置起點 path.moveTo(r * cos(pi / count), r * sin(pi / count)); // 將圓等分 count = 角的個數(shù) /// 繪制角 for (int i = 2; i <= count * 2; i++) { if (i.isEven) { path.lineTo(r2 * cos(pi / count * i), r2 * sin(pi / count * i)); } else { path.lineTo(r * cos(pi / count * i), r * sin(pi / count * i)); } } // 閉合 path.close(); canvas.drawPath(path, paint2); // 繪制輔助線 path.reset(); for (int i = 1; i <= count * 2; i++) { if (i.isEven) { path.reset(); path.lineTo(r2 * cos(pi / count * i), r2 * sin(pi / count * i)); canvas.drawPath(path, paint2..color = Colors.redAccent); } else { path.reset(); path.lineTo(r * cos(pi / count * i), r * sin(pi / count * i)); canvas.drawPath(path, paint2..color = Colors.blue); } }
默認(rèn)效果是這樣的,
畫布默認(rèn)0度是X軸右移方向,如果需要將一個角朝著正上,這里需要將畫布進(jìn)行旋轉(zhuǎn)一定角度,將0度改為Y軸向上方面,然后再偏移一定角度即可。
//旋轉(zhuǎn)角度讓尖角朝上 canvas.rotate(pi / 2 * 3 + pi / count);
角的點找到了,那么多邊形就直接連接大圓上的角就行了,就很簡單。
角的飽滿度通過修改小圓半徑即可。
最終效果圖:
源碼:
enum Type { angle, // 角 side, // 邊 all, // 都有 } /// 角 邊 型 class Polygonal extends StatelessWidget { final double size; // 組件大小 final double? bigR; // 大圓半徑 final double? smallR; // 小圓半徑 final int count; // 幾邊形 final Type type; // 五角星or五邊形 final bool isFill; // 是否填充 final Color color; // 顏色 const Polygonal( {Key? key, this.size = 80, this.bigR, this.smallR, this.count = 3, this.type = Type.angle, this.isFill = false, this.color = Colors.black87}) : super(key: key); @override Widget build(BuildContext context) { return CustomPaint( size: Size(size, size), painter: _PolygonalPainter(bigR, smallR, color: color, count: count, type: type, isFill: isFill), ); } } class _PolygonalPainter extends CustomPainter { final double? bigR; final double? smallR; final int count; // 幾邊形 final Type type; // 五角星or五邊形 final bool isFill; // 是否填充 final Color color; // 顏色 _PolygonalPainter(this.bigR, this.smallR, {required this.count, required this.type, required this.isFill, required this.color}); @override void paint(Canvas canvas, Size size) { canvas.clipRect(Offset.zero & size); canvas.translate(size.width / 2, size.height / 2); Paint paint2 = Paint() ..color = color ..strokeJoin = StrokeJoin.round ..style = isFill ? PaintingStyle.fill : PaintingStyle.stroke ..strokeWidth = 2; double r = bigR ?? size.width / 2 / 2; double r2 = smallR ?? size.width / 2 / 2 - 12; // 將圓等分 Path path = Path(); canvas.rotate(pi / count + pi / 2 * 3); path.moveTo(r * cos(pi / count), r * sin(pi / count)); /// 繪制角 if (type == Type.angle || type == Type.all) { for (int i = 2; i <= count * 2; i++) { if (i.isEven) { path.lineTo(r2 * cos(pi / count * i), r2 * sin(pi / count * i)); } else { path.lineTo(r * cos(pi / count * i), r * sin(pi / count * i)); } } path.close(); canvas.drawPath(path, paint2); } /// 繪制邊 if (type == Type.side || type == Type.all) { path.reset(); path.moveTo(r * cos(pi / count), r * sin(pi / count)); for (int i = 2; i <= count * 2; i++) { if (i.isOdd) { path.lineTo(r * cos(pi / count * i), r * sin(pi / count * i)); } } path.close(); canvas.drawPath(path, paint2); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return false; } }
關(guān)于“基于Flutter如何實現(xiàn)多邊形和多角星組件”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“基于Flutter如何實現(xiàn)多邊形和多角星組件”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。