使用路径在 Flutter 中绘制复杂元素,然后以不同角度重新绘制同一元素
Draw complex element in Flutter with path, then redraw this same element in different angles
我需要在 Flutter 中绘制以下小部件:
我已经有了绘制井字棋的方法:
var path = Path();
path.lineTo(size.width * 2, size.height * 0.05);
path.cubicTo(size.width * 2, size.height * 0.05, size.width,
size.height * 0.05, size.width, size.height * 0.05);
path.cubicTo(size.width, size.height * 0.05, size.width, size.height * 1.05,
size.width, size.height * 1.05);
path.cubicTo(size.width, size.height * 1.05, size.width * 2,
size.height * 1.05, size.width * 2, size.height * 1.05);
path.cubicTo(size.width * 2, size.height * 1.05, size.width * 2,
size.height * 0.05, size.width * 2, size.height * 0.05);
但是,这个井字棋是水平井字棋。我需要用不同的角度绘制多个。将每个放置在何处的数学是简单的三角函数(具有长度的正弦和余弦)。每一个应该形成的角度就是sine/cosine的角度。然而,用Flutter的裁剪工具绘制其中很多是很难的。
有没有办法在flutter中使用path绘制一个复杂的元素,然后在不同的地方稍微旋转一下重绘?
如果不是,我还应该采用哪种其他技术?
形状是带有圆角边框的矩形。您可以使用自定义画图。请看下面的代码或直接在DartPad here >> https://dartpad.dev/e0792a6ab7c9ff3aa1516bfeb77c3886
上运行
import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(MaterialApp(
home: MyApp(),
debugShowCheckedModeBanner: false,
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
body: Center(
child: CustomPaint(
painter: PillPainter(
circleSize: 100,
pillWidth: 11,
pillHeight: 20,
distanceBetweenPills: 10,
),
),
),
);
}
}
class PillPainter extends CustomPainter {
PillPainter({
this.circleSize,
this.pillWidth,
this.pillHeight,
this.distanceBetweenPills,
});
double circleSize;
double pillWidth;
double pillHeight;
int distanceBetweenPills;
@override
void paint(Canvas canvas, Size size) {
final double rotationFactor = 1.75;
final double numOfPills = 360 / distanceBetweenPills;
final Paint innerPaint = Paint()
..color = Colors.orange
..style = PaintingStyle.fill;
final Path path = Path();
final double rotationAngle = rotationFactor * pi;
final double initialDisplacement = 0.75 * pi;
for (int i = 0; i < numOfPills; i++) {
path.addRRect(
RRect.fromRectXY(
Rect.fromCenter(
center: Offset(
size.width / 2 +
circleSize * cos(initialDisplacement + rotationAngle),
size.height / 2 +
circleSize * sin(initialDisplacement + rotationAngle)),
width: pillWidth,
height: pillHeight),
20,
20),
);
canvas.rotate((distanceBetweenPills * pi) / 180);
innerPaint.color = i % 2 == 0 ? Colors.green : Colors.red;
canvas.drawPath(path, innerPaint);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
我需要在 Flutter 中绘制以下小部件:
我已经有了绘制井字棋的方法:
var path = Path();
path.lineTo(size.width * 2, size.height * 0.05);
path.cubicTo(size.width * 2, size.height * 0.05, size.width,
size.height * 0.05, size.width, size.height * 0.05);
path.cubicTo(size.width, size.height * 0.05, size.width, size.height * 1.05,
size.width, size.height * 1.05);
path.cubicTo(size.width, size.height * 1.05, size.width * 2,
size.height * 1.05, size.width * 2, size.height * 1.05);
path.cubicTo(size.width * 2, size.height * 1.05, size.width * 2,
size.height * 0.05, size.width * 2, size.height * 0.05);
但是,这个井字棋是水平井字棋。我需要用不同的角度绘制多个。将每个放置在何处的数学是简单的三角函数(具有长度的正弦和余弦)。每一个应该形成的角度就是sine/cosine的角度。然而,用Flutter的裁剪工具绘制其中很多是很难的。
有没有办法在flutter中使用path绘制一个复杂的元素,然后在不同的地方稍微旋转一下重绘?
如果不是,我还应该采用哪种其他技术?
形状是带有圆角边框的矩形。您可以使用自定义画图。请看下面的代码或直接在DartPad here >> https://dartpad.dev/e0792a6ab7c9ff3aa1516bfeb77c3886
上运行import 'package:flutter/material.dart';
import 'dart:math';
void main() {
runApp(MaterialApp(
home: MyApp(),
debugShowCheckedModeBanner: false,
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
body: Center(
child: CustomPaint(
painter: PillPainter(
circleSize: 100,
pillWidth: 11,
pillHeight: 20,
distanceBetweenPills: 10,
),
),
),
);
}
}
class PillPainter extends CustomPainter {
PillPainter({
this.circleSize,
this.pillWidth,
this.pillHeight,
this.distanceBetweenPills,
});
double circleSize;
double pillWidth;
double pillHeight;
int distanceBetweenPills;
@override
void paint(Canvas canvas, Size size) {
final double rotationFactor = 1.75;
final double numOfPills = 360 / distanceBetweenPills;
final Paint innerPaint = Paint()
..color = Colors.orange
..style = PaintingStyle.fill;
final Path path = Path();
final double rotationAngle = rotationFactor * pi;
final double initialDisplacement = 0.75 * pi;
for (int i = 0; i < numOfPills; i++) {
path.addRRect(
RRect.fromRectXY(
Rect.fromCenter(
center: Offset(
size.width / 2 +
circleSize * cos(initialDisplacement + rotationAngle),
size.height / 2 +
circleSize * sin(initialDisplacement + rotationAngle)),
width: pillWidth,
height: pillHeight),
20,
20),
);
canvas.rotate((distanceBetweenPills * pi) / 180);
innerPaint.color = i % 2 == 0 ? Colors.green : Colors.red;
canvas.drawPath(path, innerPaint);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}