我正在尝试使用Flutter创建一个字母跟踪应用程序。以下是我打算实现和迄今为止已经实现的屏幕截图。
打算实现: https://imgur.com/3KfWFA7
使用以下提供的代码实现: https://imgur.com/6LTcITG
import 'package:flutter/material.dart';
List<Offset> _drawPoints = <Offset>[];
void main() => runApp(MyDrawApp());
class MyDrawApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: DrawCanvas(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.clear),
onPressed: () {
_drawPoints.clear();
},
),
),
);
}
}
class DrawCanvas extends StatefulWidget {
@override
_DrawCanvasState createState() => _DrawCanvasState();
}
class _DrawCanvasState extends State<DrawCanvas> {
@override
Widget build(BuildContext context) {
return Center(
child: ClipPath(
child: detectGestureForPainting(),
clipper: UpperCaseA(),
),
);
}
Widget detectGestureForPainting() {
return GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
setState(() {
RenderBox object = context.findRenderObject();
Offset _localPosition = object.globalToLocal(details.globalPosition);
_drawPoints = List.from(_drawPoints)..add(_localPosition);
});
},
onPanEnd: (DragEndDetails details) => _drawPoints.add(null),
child: CustomPaint(
painter: PaintBrush(points: _drawPoints),
child: Container(
width: 500,
height: 900,
),
// size: Size.fromHeight(375),
),
);
}
}
class UpperCaseA extends CustomClipper<Path> {
@override
Path getClip(Size size) {
double _width = size.width;
double _height = size.height;
Path mypath = Path();
print("Height = ${size.height}");
print("Width = ${size.width}");
mypath.moveTo(_width * 0.496, _height * 0.4373297);
mypath.lineTo(_width * 0.330666667, _height * 0.671662125);
mypath.lineTo(_width * 0.208, _height * 0.648501362);
mypath.lineTo(_width * 0.434666667, _height * 0.328337875);
mypath.lineTo(_width * 0.562666667, _height * 0.326975477);
mypath.lineTo(_width * 0.789333333, _height * 0.648501362);
mypath.lineTo(_width * 0.666666667, _height * 0.671662125);
mypath.lineTo(_width * 0.610666667, _height * 0.59400545);
mypath.lineTo(_width * 0.384, _height * 0.59400545);
mypath.lineTo(_width * 0.432, _height * 0.525885559);
mypath.lineTo(_width * 0.562666667, _height * 0.525885559);
mypath.close();
mypath.addArc(Rect.fromCircle(
center: Offset(_width * 0.27, _height * 0.66),
radius: _width * 0.0652), 0, 360);
mypath.addArc(
Rect.fromCircle(
center: Offset(_width * 0.496, _height * 0.34),
radius: _width * 0.0652), 0, 360);
mypath.addArc(
Rect.fromCircle(
center: Offset(_width * 0.501, _height * 0.34),
radius: _width * 0.0652),
0,
360);
mypath.addArc(
Rect.fromCircle(
center: Offset(_width * 0.728, _height * 0.66),
radius: _width * 0.0652),
0,
360);
return mypath;
// return Path.combine(PathOperation.reverseDifference, path, path1);
}
@override
bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}
class PaintBrush extends CustomPainter {
List<Offset> points;
PaintBrush({this.points});
@override
void paint(Canvas canvas, Size size) {
canvas.drawColor(Colors.grey[350], BlendMode.src);
Paint paint = new Paint()
..color = Colors.blueAccent.shade700
..strokeCap = StrokeCap.round
..strokeWidth = 100.0;
for (int i = 0; i < points.length - 1; i++) {
if (points[i] != null && points[i + 1] != null) {
print("points[$i] = ${points[i]}");
canvas.drawLine(points[i], points[i + 1], paint);
}
}
}
@override
bool shouldRepaint(PaintBrush oldDelegate) => oldDelegate.points != points;
}
任何人都可以建议:
由于所选的笔划宽度为100.0,因此涂料溢出到另一部分,如何将其限制为所需的描迹路径。
最具挑战性的是弯曲的边缘,例如:“ B”,我该如何实现?
可以使用纹理代替普通涂料。
我知道有太多问题要问,但是任何帮助/建议/文档/示例代码都会帮助很多。感谢您的辛勤工作。
提前谢谢!